难!难!难!大虾请进!OLE保存的文件怎样才能去掉其中的附加信息?(100分)

  • 主题发起人 主题发起人 brokenbridge
  • 开始时间 开始时间
B

brokenbridge

Unregistered / Unconfirmed
GUEST, unregistred user!
我现在用ole连接的图片,存储到数据库中。
//l_FileName:bmp文件名
OleContainer1.CreateObjectFromFile(l_FileName, False);
OleContainer1.SaveToStream(tmp);
ADOTable1.Append;
tmp.Position := 0;
//写入库中
TBlobField(ADOTable1.FieldByName('BMP')).LoadFromStream(tmp);
ADOTable1.Post;
现在我又想把数据库中的这个字段保存成文件,恢复原来文件的模样。
TBlobField(ADOTable1.FieldByName('BMP')).SaveToFile(FileName);
可是这个文件由于添加了OLE的一些辅助信息不同于原来的文件。所以图片用Windows的画图
或者Photoshop打不开, 怎样才能恢复文件?
分数实在不足了,先给100,等赚了分数一定另外补上!
 
如果需要,可以给你例子!cwg_delphi@263.net
 
DFW的大虾,你们都到哪里去了?

这个问题有那么难吗?
 
TBlobField(ADOTable1.FieldByName('BMP')).SaveToFile(FileName);

把上面这句代码改一下,先把它读到TImage或TDBImage,再 SaveToFile
 
你一定要用ole吗?
 
把TBlobField换成 ADO的BlobField
 
你可不用ole来装入图形呀。
直接用TImage就可以了。
AFileStream :=TFileStream.Create(yourfilename,bmread);
AGraphic :=TBitMap.Create;//用于显示
AGraphic.loadfromstream(AFileStream);
IMage1.Picture.Graphic :=AGraphic;

TBlobField(ADOTable1.FieldByName('BMP')).LoadFromStream(AFileStream);
这样TBlobField(ADOTable1.FieldByName('BMP')).SaveToFile(FileName); 就应该可以了。




 
我想brokenbridge可能还要用OleContainer来完成比如word文档之类信息的的显示吧
 
To 小人物:
用Image和DBImage都不行,因为我保存之后的文件已经有了OLE的附加信息,其实数据库
中的那个字段也是这样的。
您的解决方式?期待!
To 北斗:
其实不只是BMP字段,我的数据库中还要存储CAD图形,这两者都需要调用OLE来进行编辑。
因为我要做报表,只有用OLE存储的东东,才能用FrReport的OLE打印,否则FrReport的OLE
控件显示不出来。
因为BMP和CAD,我还没有找到好的方式来实现链接和打印,所以只好这样。你有没有别的
方法?实现BMP和CAD的编辑修改和打印?

To Activer:
能否说的详细一点?
To wangxd:
是的。

感谢以上各位的关注,谢谢!

我非常着急,期待问题的解决!







 
关键是OLE的保存问题。把
OleContainer1.SaveToStream(tmp);
改成
OleContainer1.SaveAsDocument(filename)
就作为文档保存,去掉附加信息了
 
惭愧 惭愧,看到 过路者 的提示方让我回忆起以前学习OLE和COM的点滴

搞错了,TOleContainer是一个OLE的容器,调用它的SaveToStream和SaveToFile是存储
它自己的格式,可以用它的LoadFromStream和LoadFromFile来导入。
^^^^^^^^^^^^
在而SaveAsDocument是存储为原生的文件格式(看看Help),不过我试过还是和SaveToFile
差不多,不知道什么原因:(
 
To 过路者,Activer:
我试过的,SaveAsDocument对于Word的DOC是可以,对于别的好像不行。
谢谢!


 
你用COM试一试,不要用OLEContainer了。
 
To Activer:
COM能实现我的打印吗?能详细点吗?
 
COM是OLE的升级(不仅仅是升级)
其实你要用的也只是OLE的功能,只是不要用OLEContainter,自己直接调用COM服务器就好了。
如何操纵COM服务器,你可以看看Delphi自带的例子(Demo/ActiveX下面)
或者用yahoo或者google找找这方面的资料

//转载
...
AutoCAD R14.01版本提供了ActiveX Automation 技术,
ActiveX 是微软制定的一种实现程序间通讯、调用的软件复用规范,
它提供了一种控制AutoCAD的机制,即凡是AutoCAD中每一个裸露的对象,
如circle、line都可以用VB、Delphi等支持ActiveX的语言来控制。
每一个对象都有其相应的特性、方法,可以读取或改变其特性,
可以用方法来控制对象的动作。
...
Delphi用Olevariant类型的变量来引用OLE自动化对象,进而访问自动化对象的特性和方法。
首先创建AutoCAD自动化服务器,设AutoCAD对象的变量为ACAD,子对象之一document,
即文档(图形文件),变量为ACADDoc,其创建如下:
ACAD:=CreataOleObject('AutoCad.Application');
ACADDoc:=ACAD.ActiveDocument;
...
你可以看看这里:
http://www.powerba.com/develop/delphi/article/20001019002.htm

 
以前好像研究过,将数据流中的前几个数据截去好像就可以了。
可以这样验证,首先SaveToFile一片Word文档,然后使用utlaEdit打开,
将前面的多余的几个字节删除(和正常的相比)。
这样就应该能够行的通了。
*仅供参考*
 
抄来的 http://www.delphibbs.com/delphibbs/dispq.asp?lid=771258
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, OleCtnrs, ActiveX, ComObj, ComCtrls;

type
TForm1 = class(TForm)
OleContainer1: TOleContainer;
Button1: TButton;
DateTimePicker1: TDateTimePicker;
Button2: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
Data: IDataObject;
SM: TStgMedium;
FormatEtc: TFormatEtc;
Bmp: TBitmap;
begin
OleContainer1.DoVerb(ovShow);
Data := OleContainer1.OleObjectInterface as IDataObject;

FormatEtc.cfFormat := CF_BITMAP;
FormatEtc.tymed := TYMED_GDI;
FormatEtc.ptd := nil;
FormatEtc.dwAspect := DVASPECT_CONTENT;
FormatEtc.lindex := -1;

Bmp := TBitmap.Create;
try
OleCheck(Data.GetData(FormatEtc, SM));
try
Bmp.LoadFromClipboardFormat(CF_BITMAP, SM.hBitmap, 0);
Bmp.SaveToFile('e:/Test.bmp');
finally
ReleaseStgMedium(SM);
end;
finally
Bmp.Free;
end;
end;

end.
 
后退
顶部