2016-11-24 2 views
0

Ich versuche, eine Instanz von LibreOffice mit Delphi in meiner Anwendung einzubetten. Mein Hauptziel ist es, ein Ergebnis wie in MS Office zu erreichen, wenn LibreOffice Dokumente darin eingebettet werden. Wenn möglich, möchte ich mit TOLEConatiner dies erreichen.Embedding Instanz von LibreOffice in Anwendung (mit TOLEContainer)

Für den Test habe ich ein Programm mit einer TOleContainer Komponente:

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

Für MS Office (eine DOCX-Datei zu öffnen), das bereits ohne Probleme funktioniert. Das Öffnen einer .odt-Datei und das anschließende Aktivieren des OLEContainer führt zu einem leeren Frame, der mehr oder weniger nichts anzeigt, also nicht sichtbar oder editierbar ist.

Also habe ich versucht, mehr über LibreOffice, OLE und COM zu erfahren. Ich habe herausgefunden, dass ich OO API seine Funktionalität zugreifen können, muss ich zuerst eine OLEObject des OO Servicemanager erstellen, dann einen Desktop-Dienst erstellt ein Dokument erstellen, so etwas wie dieses:

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); 

Mein Problem ist, dass ich nicht sehe, wie man das mit OLEContainer kombiniert, um mein erwartetes Ergebnis zu erhalten. Beispiele, die ich gefunden habe (zum Beispiel this one), konnten mir auch nicht wirklich helfen, da sie eine separate Instanz von LibreOffice öffnen. Ich habe mich auch über einige Dienste von LibreOffice informiert, um eine Lösung zu finden, aber es ist ziemlich schwer für mich, die Dokumentation zu lesen.

OLE, COM und LibreOffice API ist ein neues Thema für mich und ich fühle mich dort ziemlich verloren. Also habe ich die folgende Frage:

Ist es sogar möglich, ein Dokument in einer LibreOffice-Instanz, die in einen OleContainer eingebettet ist, anzuzeigen und zu bearbeiten? Wenn ja, wie kann ich das erreichen? Wenn nein, gibt es Alternativen, um eine LibreOffice-Instanz in meiner Anwendung anzuzeigen?

+0

Haben Sie irgendwelche Beweise, dass dies überhaupt möglich ist? –

+0

Wie bereits erwähnt, verwendet MSOffice diese Funktionalität bereits und es funktioniert dort (und ich erwarte, dass auch MSOffice TOleContainer verwendet). Aber ich konnte nichts darüber finden, wie das gemacht wird. –

+0

Ich sehe nicht, wo Büro in das kommt. Sie verwenden libre office. Kann es eingebettet werden? –

Antwort

0

Es ist eine Weile her, aber ich habe den Grund für den leeren Rahmen in dem Behälter gefunden:

Während mit MSOffice arbeiten, wobei das Verfahren DoVerb ruft intern IOleDocumentSite.ActivateMe von TOleContainer, die verschiedene Attribute setzt, einschließlich FDocObj. Für LibreOffice scheint die Schnittstelle IOleDocumentSite nicht unterstützt zu werden (QueryInterface löst einen Fehler aus), daher wird ActivateMe nie aufgerufen. Dies führt dazu, dass FDocObj nicht festgelegt wird und daher ein falsches Handle in TOleContainer.GetWindow empfangen wird (anstelle des eigenen Handles von OleContainer wird das Handle des übergeordneten Elements empfangen) und das Dokument wird nicht im Container angezeigt.

Um das Problem zu lösen, habe ich FDocObj auf True vor dem Aufruf DoVerb festgelegt. Dies ist möglicherweise nicht die endgültige Lösung, da ich immer noch nicht vollständig verstehe, wie TOleContainer genau funktioniert, aber für den Moment funktioniert diese Lösung für mich.