Einzelnen Beitrag anzeigen

Benutzerbild von Minz3
Minz3

Registriert seit: 18. Jul 2019
Ort: Thüringen
48 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#1

CEF4Delphi - Richtige Initialisierung in bestehendes Projekt

  Alt 13. Nov 2019, 09:01
Delphi-Version: 10.1 Berlin
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 hier finden.

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:
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.
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:
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:
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;
Das Log File sieht dann so aus:
Code:
[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
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?

Sorry für diese Wall of Text und ich danke euch für eventuelle Ratschläge.
Attention:
Brain.exe has stopped working. Reboot the system in 3... 2... 1... ... ... ... Attempt failed.

Geändert von Minz3 (13. Nov 2019 um 09:12 Uhr)
  Mit Zitat antworten Zitat