【问题标题】:Show Blob content into OleContainer Delphi在 OleContainer Delphi 中显示 Blob 内容
【发布时间】:2016-08-31 14:42:51
【问题描述】:

使用 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; 

引发了无效的流格式消息。 这样做的最佳问题是什么?

【问题讨论】:

    标签: delphi devexpress media ole


    【解决方案1】:

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

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

    显然,我假设正确的上述“解决方案”不起作用并且失败并出现"%1 already exists" EOleSysError 异常,正如您在 cmets 中提到的那样。

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

    【讨论】:

    • 我不知道文件类型,必须添加任何内容:视频、文档、xls、pdf、从文件打开的图像或从剪贴板粘贴...我测试了“LoadAsDocument”,如示例所述,但是EOleSysError 引发“%1 已存在”... :(
    • ` OleCheck(StgOpenStorageOnILockBytes(FLockBytes, nil, STGM_READWRITE or STGM_SHARE_EXCLUSIVE, nil, 0, FStorage));` 这里提出
    • 你是对的。我假设解决方案是准确的,无需测试。
    【解决方案2】:

    您不能将原始文件格式直接加载到 TOleContainer 中。此流必须采用特殊的 OLE 格式。这就是您收到“无效流格式”错误的原因。

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

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

    编辑:如果你不知道实际的文件格式,你可以检测出来!例如,您可以尝试 Marco Pontello 的 TrID 库。所以首先检测文件格式并将其保存到临时文件夹,然后加载到 OC。

    【讨论】:

      猜你喜欢
      • 2020-02-20
      • 2016-08-30
      • 1970-01-01
      • 1970-01-01
      • 2020-04-23
      • 1970-01-01
      • 2014-03-10
      • 1970-01-01
      • 2012-04-02
      相关资源
      最近更新 更多