将Blob内容显示到OleContainer Delphi中
使用XE8。 Devex TcxGrid,其中一列表示具有PopupEditProperties和PopupControl=TOleContainer控件的blob数据。 该列表示各种数据类型(图像、pdf、word、excel、mpg、avi、mp3、ppt等)的数据库字段(BlobType) 当PopupEditProperties中的OnInitPopup事件激发时,我希望执行以下操作:将Blob内容显示到OleContainer Delphi中,delphi,devexpress,media,ole,Delphi,Devexpress,Media,Ole,使用XE8。 Devex TcxGrid,其中一列表示具有PopupEditProperties和PopupControl=TOleContainer控件的blob数据。 该列表示各种数据类型(图像、pdf、word、excel、mpg、avi、mp3、ppt等)的数据库字段(BlobType) 当PopupEditProperties中的OnInitPopup事件激发时,我希望执行以下操作: var MS: TMemoryStream; OC: TOleContainer; begin
var
MS: TMemoryStream;
OC: TOleContainer;
begin
if not Query1.FieldByName('data').isNull then begin
OC := TcxPopupEditProperties(cxGrid1DBTableView1Data.Properties).PopupControl as TOleContainer;
//Size of Container
with OC do begin
Parent := TcxPopupEdit(Sender).PopupWindow;
Left := 5;
Top := 5;
Width := cxGrid1DBTableView1.Controller.FocusedColumn.Width;
Height := 300;
end;
MS := TMemoryStream.Create;
try
TBlobField(Query1.FieldByName('data')).SaveToStream(MS);
// I Want show the content with appropiate application
OC.LoadFromStream(MS); // here crashes
finally
MS.Free;
end;
end;
end;
引发了无效的流格式消息。
执行此操作的最佳问题是什么?
TOleContainer
使用自己的格式与LoadFromStream
/SaveToStream
。我假设您的DB blob保存原始文件数据。您需要将TMemoryStream
保存到临时文件,然后调用CreateObjectFromFile
另一种选择是使用这个解决方案:(我会亲自攻击所需的私有成员,并编写一个独立的过程,但这将取决于版本)
显然,我认为正确的上述“解决方案”不起作用,并且失败,因为“%1已经存在”
EOleSysError异常,正如您在评论中提到的那样
所以,唯一的方法是使用一个具有适当扩展名的临时文件。需要扩展名来确定哪个OLE服务器应用程序将处理该文件。每个扩展都在您的计算机上的
HKEY\U CLASSES\U ROOT
中注册。依我看,您必须将文件类型保存在数据库中。您的应用程序以后如何知道它是哪种类型?唯一的方法是检查流/blob签名(可能不是100%准确)。您不能直接将原始文件格式加载到TOleContainer中。此流必须采用特殊的OLE格式。这就是为什么出现错误“无效流格式”
作为解决方法,您可以将BLOB保存到具有适当文件扩展名的临时文件中。例如:c:\temp\image.gif
然后将其加载到TOleContainer中,如下所示:
OC.CreateObjectFromFile('c:\temp\image.gif', false);
编辑:如果你不知道实际的文件格式,你可以检测它!例如,您可以尝试Marco Pontello的TrID库。因此,首先检测文件格式并将其保存到临时文件夹,然后加载到OC。我不知道文件类型,必须添加任何内容:视频、文档、xls、PDF、从文件打开的图像或从剪贴板粘贴的图像。。。如示例所示,我测试了“LoadAsDocument”,但EOleSysError引发“%1”已存在(`OleCheck(StgOpenStorageOnILockBytes(FLockBytes,nil,STGM_READWRITE或STGM_SHARE_EXCLUSIVE,nil,0,FStorage));`这里说明您是正确的。我假设该解决方案是准确的,没有对其进行测试。