We're having problems to get a stable implementation of this.
The CEF code comments are not crystal clear and it remains to be determined what the correct / best solution for this is.
Our application has two modes:
* MDI mode, with standard MDI child windows inside a main form MDI frame window
* Floating mode, with each child window "floating" on the desktop
The CEF browser window is implemented as a child window, along with other non-browser child windows.
We first tried using OnCloseQuery in the TCEFBrowserForm window. That (more or less) works in the floating mode, but in MDI mode, if you try to close the main window, the CanClose := False in the CEF window code, like this:
Code: Select all
procedure TCEFBrowserForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
inherited;
if CanClose and not FChromiumClosed then
begin
FChromiumClosed := True;
Chromium.CloseBrowser(False);
CanClose := False;
end
else
CanClose := CanClose and FChromiumClosed;
end;
procedure TCEFBrowserForm.ChromiumClose(Sender: TObject; const browser: ICefBrowser; out Result: Boolean);
begin
inherited;
Result := True;
Close;
end;
stops the process of closing other windows and the application itself - standard TForm logic:
Code: Select all
function TCustomForm.CloseQuery: Boolean;
var
I: Integer;
begin
if FormStyle = fsMDIForm then
begin
Result := False;
for I := 0 to MDIChildCount - 1 do
if not MDIChildren[I].CloseQuery then Exit;
end;
Result := True;
if Assigned(FOnCloseQuery) then FOnCloseQuery(Self, Result);
end;
So that does not work. Our next idea was to hook OnClose instead and change the Action from caFree to caHide - to delay the actual closing of the window, but that causes crashes. Have tried variants of:
Code: Select all
procedure TCEFBrowserForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
inherited;
if not FChromiumClosed and (Action = caFree) then
begin
FChromiumClosed := True;
Chromium.CloseBrowser(True);
Action := caHide;
end;
end;
procedure TCEFBrowserForm.ChromiumClose(Sender: TObject; const browser: ICefBrowser; out Result: Boolean);
begin
inherited;
Result := True;
// Result := False;
FChromiumClosed := True;
Release; //??
// Close;
end;
Often it never gets to ChromiumClose at all - and the hidden MDI forms are forcibly freed in the TApplication.DoneComponents code.
Then some message handling code crashes.
I also noticed the advice to call cef_quit_message_loop. It does not look like CEF4Delphi calls this anywhere, so I added it to our main application:
Code: Select all
procedure TInfrontMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Assigned(cef_quit_message_loop) then
cef_quit_message_loop;
But that didn't help.
Starting to feel stuck here.