使用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;
引发无效的流格式消息。 这是最好的问题吗?
答案 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。