I am trying to embed an instance of LibreOffice with Delphi in my Application. My main goal is it to achieve a result like in MS office when im embedding LibreOffice documents into it. If possible, i want to use TOLEConatiner to achieve this.
For testing i wrote a program with a TOleContainer Component:
procedure TForm1.btn1Click(Sender: TObject);
begin
if OpenDialog.Execute then
if FileExists(OpenDialog.FileName) then
OleContainer.CreateObjectFromFile(OpenDialog.FileName, false)
end;
For MS Office (opening a .docx-file), this already works without problems. Opening an .odt-file and then activating the OLEContainer results in an empty frame, showing more or less nothing, therefore not viewable or editable.
So i tried to find out more about LibreOffice, OLE and COM. I have found out that i can use OO API to access its functionality , I first need to create an OLEObject of the OO ServiceManager, then creating a desktop service to create a document, something like this:
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);
My problem is that i don't see how to combine this with OLEContainer to get my expected result. Examples I have found (for example this one) couldn't really help me either as they open a seperate instance of LibreOffice. I also informed myself about some services of LibreOffice to find any solution, but its quite hard for me to get through the documentation.
OLE, COM and LibreOffice API is a new topic for me and i feel quite lost there. So i come up with the following question:
Is it even possible to show and edit a document in a LibreOffice instance embedded in an OleContainer? If yes, how can i achieve that? If no, are there any alternatives to show a LibreOffice Instance in my application?
It is a while ago, but i have found the reason for the empty frame in the container:
While working with MSOffice, the method DoVerb
internally calls IOleDocumentSite.ActivateMe
of TOleContainer
which sets different attributes, including FDocObj
. For LibreOffice, the interface IOleDocumentSite
does not seem to be supported (QueryInterface
raises an error), therefore ActivateMe
is never called. This results in not setting FDocObj
, therefore receiving a wrong handle in TOleContainer.GetWindow
(instead of OleContainer's own handle its parent's handle is received), and the document is not shown in the Container.
To solve the problem, I have set FDocObj
to True before calling DoVerb
. This might not be the final solution as i still dont understand completely how TOleContainer exactly works but for the moment this solution works for me.