将Blob内容显示在OleContainer Delphi中

时间:2016-08-31 14:42:52

标签: 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
  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; 

引发无效的流格式消息。 这是最好的问题吗?

2 个答案:

答案 0 :(得分:4)

TOleContainer使用自己的格式LoadFromStream / SaveToStream。我假设你的数据库blob保存原始文件数据。您需要将TMemoryStream保存到临时文件,然后调用CreateObjectFromFile

另一种选择是使用这个解决方案:Load a TOleContainer from a stream which contains a file image, without using CreateObjectFromFile(我个人会破解所需的私人成员并编写一个独立的程序,但它将是版本依赖的。)

显然上面的"解决方案"我假设正确无法正常工作,并且因您在评论中提到的"%1 already exists" EOleSysError异常而失败。

因此,AFAIK唯一的方法是使用具有适当扩展名的临时文件。需要扩展名来确定哪个OLE服务器应用程序将处理该文件。每个扩展程序都在HKEY_CLASSES_ROOT的您的计算机上注册。 IMO,您必须保存数据库中的文件类型。您的应用程序以后会如何知道它是哪种类型?唯一的方法是检查stream / blob 签名(可能不是100%准确)。

答案 1 :(得分:2)

您无法直接将原始文件格式加载到TOleContainer中。此流必须是特殊的OLE格式。这就是您收到错误"无效的流格式"。

的原因

作为解决方法,您可以将BLOB保存到具有适当文件扩展名的临时文件中。例如:c:\ temp \ image.gif 然后将其加载到TOleContainer中,如下所示:

OC.CreateObjectFromFile('c:\temp\image.gif', false);

编辑:如果您不了解实际的文件格式,则可以检测到它!例如,您可以尝试Marco Pontello的TrID库。因此,首先检测文件格式并将其保存到临时文件夹,然后加载到OC。