![]() |
Fehler bei Aufruf eines TForms mit TWebbrowser aus DLL
Hallo,
wenn ich eine Unit1.pas mit einem TWebBrowser (Standard Komponente aus Internetpallette) aus einer Applikation erzeuge klappt das ohne Probleme, aus einer DLL nicht. Unit1.pas:
Delphi-Quellcode:
Aus einer Unit2.pas (Hauptformular) kann das Form ohne Probleme erzeugt werden.
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, OleCtrls, SHDocVw, StdCtrls; type TForm1 = class(TForm) WebBrowser1: TWebBrowser; private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} end.
Delphi-Quellcode:
Das klappt super !!!
procedure TForm2.Button1Click(Sender: TObject);
begin Form1 := TForm1.Create(Application); try Form1.ShowModal; finally Form1.Free; end; end; Wenn ich nun eine DLL erzeuge: Project1.dpr:
Delphi-Quellcode:
und dann in einem Projekt2.exe die Funktion aufrufe gibts einen Fehler:
library Project1;
uses Forms, SysUtils, Classes, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} procedure showPdf; begin Form1 := TForm1.Create(Application); try Form1.ShowModal; finally Form1.Free; end; end; procedure showPdfWithApp(App: TApplication); var dllApp : TApplication; begin dllApp := Application; Application := App; Form1 := TForm1.Create(App); try Form1.ShowModal; finally Form1.Free; end; Application := dllApp; end; exports showPdf, showPdfWithApp; begin end. Unit2.pas vom Project2.dpr:
Delphi-Quellcode:
Die TWebBrowser Komponente wirft einen EOleSysError mit Meldung :
unit Unit2;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm2 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form2: TForm2; implementation {$R *.dfm} procedure showPdf; external 'Project1.dll'; procedure showPdfWithApp(app: TApplication); external 'Project1.dll'; procedure TForm2.Button1Click(Sender: TObject); begin showPdf; end; procedure TForm2.Button2Click(Sender: TObject); begin showPdfWithApp(Application); end; end. Zitat:
Ich hatte erst den Verdacht, er will die Application der Anwendung haben, aber das half nichts. (Bei MDI Fenstern aus der DLL war das so) |
Re: Fehler bei Aufruf eines TForms mit TWebbrowser aus DLL
Hi,
dann ruf doch in der DLL einfach CoInitialize auf! ;) (Das wird sonst im Application.Initialize erledigt, soweit ich weiss) mfG mirage228 |
Re: Fehler bei Aufruf eines TForms mit TWebbrowser aus DLL
Zitat:
Das ist zwar nicht die "ganze" Lösung, hat mich aber schon weiter gebracht. Wenn's fertig ist, werde ich hier die Lösung posten. Danke noch mal |
Re: Fehler bei Aufruf eines TForms mit TWebbrowser aus DLL
Zitat:
Die Komponente TWebBrowser verwendet eine Unit, die den InitProc-Pointer auf eine eigene Procedure setzt. Application.Initialize prüft ob der Zeiger gesetzt ist und ruft dann diese Procedure auf.
Delphi-Quellcode:
Da in einer DLL dieser Zeiger nicht gesetzt wird, kommt es zu diesem Fehler.
procedure TApplication.Initialize;
begin if InitProc <> nil then TProcedure(InitProc); end;
Delphi-Quellcode:
Dummerweise ist die Procedur InitComObj nur im implementation Teil der Unit definiert.
if not IsLibrary then
begin SaveInitProc := InitProc; InitProc := @InitComObj; end; Sie lässt sich also nicht direkt aufrufen. Deshalb habe ich meiner Unit folgenden initialization Abschnitt hinzugefügt. (Sollte nur ein mal im Programmstehen.) Folgenden Quelltext habe ich in die Unit1.pas aufgenommen:
Delphi-Quellcode:
...
// In ComObj wird der InitProc verbogen, aber nur wenn keine DLL :-( // : if not IsLibrary then // : begin // : SaveInitProc := InitProc; // : InitProc := @InitComObj; // : end; // Leider ist InitComObj nur lokal in der implementation definiert, // deswegen hier dieses manuelle Init var NeedToUninitialize: Boolean; initialization //InitComObj; if (CoInitFlags <> -1) and Assigned(ComObj.CoInitializeEx) then begin NeedToUninitialize := Succeeded(ComObj.CoInitializeEx(nil, CoInitFlags)); IsMultiThread := IsMultiThread or ((CoInitFlags and COINIT_APARTMENTTHREADED) <> 0) or (CoInitFlags = COINIT_MULTITHREADED); // this flag has value zero end else NeedToUninitialize := Succeeded(CoInitialize(nil)); //--InitComObj finalization if NeedToUninitialize then CoUninitialize; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz