将LibreOffice实例嵌入到应用程序中(使用TOLEContainer)

时间:2016-11-24 16:42:47

标签: delphi com ole libreoffice delphi-xe4

我正在尝试在我的应用程序中使用Delphi嵌入LibreOffice的实例。我的主要目标是当我将LibreOffice文档嵌入其中时,在MS office中获得结果。如果可能的话,我想使用TOLEConatiner来实现这一目标。

为了测试,我用TOleContainer组件编写了一个程序:

procedure TForm1.btn1Click(Sender: TObject);
begin
  if OpenDialog.Execute then
  if FileExists(OpenDialog.FileName) then
    OleContainer.CreateObjectFromFile(OpenDialog.FileName, false)
end;

对于MS Office(打开.docx文件),这已经没有问题了。打开.odt文件然后激活OLEContainer会产生一个空框架,显示或多或少没有任何内容,因此无法查看或编辑。

所以我试图找到更多关于LibreOffice,OLE和COM的信息。我发现我可以使用OO API来访问它的功能,我首先需要创建一个OO ServiceManager的OLEObject,然后创建一个桌面服务来创建一个文档,如下所示:

Server := CreateOleObject('com.sun.star.ServiceManager');
Desktop := Server.CreateInstance('com.sun.star.frame.Desktop')
LoadParams := VarArrayCreate([0, 0], varVariant);
Param := Server.Bridge_GetStruct('com.sun.star.beans.PropertyValue');
Param.Name := 'Hidden';
Param.Value := True;
LoadParams[0] := Param;
Document := Desktop.LoadComponentFromURL('private:factory/swriter', '_default', 0, LoadParams);

我的问题是我不知道如何将它与OLEContainer结合起来以获得我的预期结果。我发现的示例(例如this one)在打开LibreOffice的单独实例时无法帮助我。我还告诉自己LibreOffice的一些服务,以找到任何解决方案,但我很难通过文档。

OLE,COM和LibreOffice API对我来说是一个新话题,我觉得很失落。所以我想出了以下问题:

甚至可以在OleContainer中嵌入的LibreOffice实例中显示和编辑文档吗? 如果是,我怎么能实现这一目标? 如果不是,是否有任何替代方案可以在我的应用程序中显示LibreOffice实例?

1 个答案:

答案 0 :(得分:0)

不久之前,我发现了容器中空框架的原因:

在使用MSOffice时,方法DoVerb在内部调用IOleDocumentSite.ActivateMe TOleContainerFDocObj设置不同的属性,包括IOleDocumentSite。对于LibreOffice,似乎不支持接口QueryInterfaceActivateMe引发错误),因此永远不会调用FDocObj。这导致未设置TOleContainer.GetWindow,因此在FDocObj中接收到错误的句柄(而不是OleContainer自己的句柄,而是收到其父句柄),并且文档未显示在容器中。

要解决此问题,我在调用DoVerb之前已将Object.prototype.getB = function() { // how to get the current value a return a.b; }; const a = {b: 'c'}; a.getB(); 设置为True。这可能不是最终解决方案,因为我仍然完全不了解TOleContainer如何正常工作,但目前这个解决方案对我有用。