![]() |
Delphi-Version: 10.1 Berlin
CEF4Delphi - Richtige Initialisierung in bestehendes Projekt
Huhu Leute,
ich hab heute ein kniffliges Thema. Das Problem beschäftigt mich jetzt schon ein paar Tage und ich habe schon diverse Foren abgeklappert, nun seid ihr meine "letzte Hoffnung". ^^ Zuvor hatte ich schon im CEF Forum geschrieben, den Beitrag könnt ihr ![]() Aber nochmal von vorne.. Ich versuche in unser ERP System eine PWA (Progressive Web App) einzubinden. Da TWebBrowser scheinbar nur den IE unterstützt, da es auf den "OS Browser" zurückgreift, musste ich nach einer Alternative suchen. Und da kommt Chromium ins Spiel. Soweit so gut, ich habe die Packages runtergeladen, in Delphi eingebunden und die Demos compiliert. Das hat auch da wunderbar funktioniert. Blöd nur, dass es im richtigen Projekt nicht mehr so reibungslos läuft. Das Projekt bildet sich aus der Main Application, einen APP-Server und eine beträchtlichen Anzahl von Modulen (.bpl Files). Eben so ein Modul habe ich dann auch erstellt und erstmal nackig eingebunden, hat funktioniert. Jetzt scheint die Kommunikation zwischen der Main Application und den .bpl Files nicht ganz so einfach zu sein. Die .dpr der Main App musste angepasst werden, um die CEF Komponenten zu initialisieren. Siehe hier:
Delphi-Quellcode:
Auch hier erstmal alles gut, wenn CEF erfolgreich initialisiert wurde, startet die App. Und das tut sie auch. Allerdings wird in der PWA Form nicht erkannt, dass die Initialisierung erfolgt ist und der Timer bleibt hängen. Hier mal ein kurzer Auszug:
program ERP;
uses Forms, Vcl.Themes, Vcl.Styles, (...) uCEFApplication; {$R *.RES} // CEF3 needs to set the LARGEADDRESSAWARE flag which allows 32-bit processes to use up to 3GB of RAM. {$SetPEFlags $20} begin {$IFDEF DEBUG} ReportMemoryLeaksOnShutdown := True; GlobalCEFApp.SingleProcess := True; {$ENDIF} //VirtualUI.StdDialogs := True; GlobalCEFApp := TCefApplication.Create; if GlobalCEFApp.StartMainProcess then begin Application.Initialize; Application.Title := 'ERP'; //Application.MainFormOnTaskbar := True; Application.CreateForm(TERPModulesFrame, ERPModulesFrame); //Application.OnException := ERPModulesFrame.GlobalHandleExceptions; Application.Run; end; GlobalCEFApp.Free; GlobalCEFApp := nil; end.
Delphi-Quellcode:
procedure TPWAModuleForm.FormShow(Sender: TObject);
begin // For simplicity, this demo blocks all popup windows and new tabs ChromiumWindow1.ChromiumBrowser.OnBeforePopup := Chromium_OnBeforePopup; Logging('Chromium_OnBeforePopup: Popups and new Tabs blocked', 'FormShow'); // You *MUST* call CreateBrowser to create and initialize the browser. // This will trigger the AfterCreated event when the browser is fully // initialized and ready to receive commands. // GlobalCEFApp.GlobalContextInitialized has to be TRUE before creating any browser // If it's not initialized yet, we use a simple timer to create the browser later. if not(ChromiumWindow1.CreateBrowser) then begin Timer1.Enabled := True; Logging('Timer1 enabled | !ChromiumWindow1.CreateBrowser: Browser not created yet', 'FormShow'); end; end;
Delphi-Quellcode:
Das Log File sieht dann so aus:
procedure TPWAModuleForm.Timer1Timer(Sender: TObject);
begin Timer1.Enabled := False; Logging('Timer1 disabled', 'Timer1Timer'); if not(ChromiumWindow1.CreateBrowser) and not(ChromiumWindow1.Initialized) then begin Timer1.Enabled := True; Logging('Chromium not initialized | Browser not created | Timer started', 'Timer1Timer'); end; end;
Code:
Also wie ihr sehen könnt, wird im Timer Event immer wieder geschaut, ob die Initialisierung erfolgt ist. Ich stelle mir die Frage, wie ich der .bpl klar machen kann, dass in der .dpr von der Main App die Initialisierung abgeschlossen ist?
[13.11.2019 08:19:39]
Procedure: WMMove Message: ChromiumWindow1.NotifyMoveOrResizeStarted [13.11.2019 08:19:39] Procedure: GetModuleDescription Message: succeeded [13.11.2019 08:19:39] Procedure: WMMove Message: ChromiumWindow1.NotifyMoveOrResizeStarted [13.11.2019 08:19:39] Procedure: WMMove Message: ChromiumWindow1.NotifyMoveOrResizeStarted [13.11.2019 08:19:39] Procedure: FormShow Message: Chromium_OnBeforePopup: Popups and new Tabs blocked [13.11.2019 08:19:39] Procedure: FormShow Message: Timer1 enabled | !ChromiumWindow1.CreateBrowser: Browser not created yet [13.11.2019 08:19:39] Procedure: FormCreate Message: Trigger: FCanClose False | FClosing False [13.11.2019 08:19:40] Procedure: Timer1Timer Message: Timer1 disabled [13.11.2019 08:19:40] Procedure: Timer1Timer Message: Chromium not initialized | Browser not created | Timer started [13.11.2019 08:19:40] Procedure: GoBtnClick Message: Succeeded! | New URL loaded [13.11.2019 08:19:41] Procedure: Timer1Timer Message: Timer1 disabled [13.11.2019 08:19:41] Procedure: Timer1Timer Message: Chromium not initialized | Browser not created | Timer started [13.11.2019 08:19:42] Procedure: Timer1Timer Message: Timer1 disabled [13.11.2019 08:19:42] Procedure: Timer1Timer Message: Chromium not initialized | Browser not created | Timer started [13.11.2019 08:19:43] Procedure: Timer1Timer Message: Timer1 disabled [13.11.2019 08:19:43] Procedure: Timer1Timer Message: Chromium not initialized | Browser not created | Timer started [13.11.2019 08:19:44] Procedure: FormCloseQuery Message: Visible False | FClosing True | ChromiumWindow1 closed Sorry für diese Wall of Text und ich danke euch für eventuelle Ratschläge. :) |
AW: CEF4Delphi - Richtige Initialisierung in bestehendes Projekt
Das TPWAModuleForm ist in der BPL?
Denkanstoß: Wie würdest du von deiner Main-EXE aus ein Modul benachrichtigen, wenn es in einer geladenen DLL oder gar in einer externen Anwendung liegen würde? |
AW: CEF4Delphi - Richtige Initialisierung in bestehendes Projekt
Zitat:
Zitat:
|
AW: CEF4Delphi - Richtige Initialisierung in bestehendes Projekt
Ein bisschen Lesestoff (nein, ist nicht optional - bitte lesen):
![]() Du brauchst sozusagen sowas wie:
Delphi-Quellcode:
unit MiPWAFrm;
interface procedure DingensKirchenIstFertigGeladen; exports // gleiche Technik wie bei DLLs DingensKirchenIstFertigGeladen; implementation uses Dialogs; procedure DingensKirchenIstFertigGeladen; begin ShowMessage('Ich wurde von der Main-App aus gerufen und sage damit dem BPL-Package, dass in der Main-App jetzt alles fertig ist' + sLineBreak + 'Ja, auch Übergabeparameter sind damit möglich!' + sLineBreak + 'Und ja, das ist nur ganz beispielhafter Beispielcode, den du noch sinnvoll für deine Anwendung abändern musst!'); if Asssigned(MeineFormularVariable) then MeineFormularVariable.DingensKirchenIstGeladen := True; end; end. |
AW: CEF4Delphi - Richtige Initialisierung in bestehendes Projekt
Ok danke dir ich werde mir das anschauen und versuchen, es so gut es geht umzusetzen.
|
AW: CEF4Delphi - Richtige Initialisierung in bestehendes Projekt
Hallo,
ich habe genau das gleiche Problem. Wie hast Du es damals gelöst? Gruß |
AW: CEF4Delphi - Richtige Initialisierung in bestehendes Projekt
In 2024 nimmt man lieber gleich TEdgeBrowser und "überspringt" CEF4Delphi.
Spart einen mittlerweile fast 1/2 GB an sonst nötigen Bereistellungen im eigenen Programm einfach Einfach den Browser nehmen, der bei 99,9% schon eh als integrierbares Control installiert ist. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:46 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