将Blob内容显示到OleContainer Delphi中

将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

使用XE8。 Devex TcxGrid,其中一列表示具有PopupEditProperties和PopupControl=TOleContainer控件的blob数据。 该列表示各种数据类型(图像、pdf、word、excel、mpg、avi、mp3、ppt等)的数据库字段(BlobType)

当PopupEditProperties中的OnInitPopup事件激发时,我希望执行以下操作:

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));`这里说明您是正确的。我假设该解决方案是准确的,没有对其进行测试。