How to corectly handle pop-ups without crashing Delphi

Lu53
Posts: 8
Joined: Mon Jan 20, 2020 1:02 pm

How to corectly handle pop-ups without crashing Delphi

Post by Lu53 » Thu Feb 13, 2020 6:42 pm

Dear All,

the website I have to deal with uses pop-ups. In the demos I looked into, pop-ups are simply disabled:

Code: Select all

Procedure TMainForm.Chromium1BeforePopup(....);
  Result := (targetDisposition in [WOD_NEW_FOREGROUND_TAB, WOD_NEW_BACKGROUND_TAB, WOD_NEW_POPUP, WOD_NEW_WINDOW]);
I have no idea what exactly this Result := line does, but, in order to allow pop-ups, I found out that just commenting out the Result := ... line does the job. So now I get pop-ups. Fine!

When the user later on closes a popup, I get a Chromium1Close followed (!!) by a Chromium1BeforeClose. In the demos, these events are handled like this;

Code: Select all

Procedure TMainForm.Chromium1Close(...);
   PostMessage(Handle, CEF_DESTROY, 0, 0);
   aAction := cbaDelay;
 
and 

Procedure TMainForm.Chromium1BeforeClose(...);
     CEFSentinel1.Start;
Unfortunately, this shuts down the whole app.

What I did to help myself was this:

Code: Select all

Procedure TMainForm.Chromium1Close(...);
   If browser=Chromium1.Browser then
    Begin   
     aAction := cbaDelay;
     PostMessage(Handle, CEF_DESTROY, 0, 0);
    End
   Else 
     aAction := cbaClose;
 
and 

Procedure TMainForm.Chromium1BeforeClose(...);
   If browser=Chromium1.Browser then
     CEFSentinel1.Start;
This SEEMS to work in that the pop-ups close and the program continues, but somehow this destabilizes Delphi, in particular in my case, the exception handling mechanism. In any try .. except on E:Exception do ... end following the close, that occurs anywhere in the code, I get an AV when accessing E.

My question is: How do I have to correctly handle pop-ups and not mess the rest of my program?

Thank you very much for any idea on this!

Lu

dilfich
Posts: 225
Joined: Thu Nov 30, 2017 1:17 am

Re: How to corectly handle pop-ups without crashing Delphi

Post by dilfich » Thu Feb 13, 2020 7:08 pm

Code: Select all

  Chromium1.LoadURL(targetUrl);  
  Result := True;
Or is this option not suitable?

Lu53
Posts: 8
Joined: Mon Jan 20, 2020 1:02 pm

Re: How to corectly handle pop-ups without crashing Delphi

Post by Lu53 » Thu Feb 13, 2020 7:42 pm

Thank you for your input, Dilfich!
Unfortunately, I'm not sure to where you are trying to point me to.
Maybe this extra info helps: The website I have to deal with is not under my control, so I have to live with the popups.

User avatar
salvadordf
Posts: 2640
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: How to corectly handle pop-ups without crashing Delphi

Post by salvadordf » Fri Feb 14, 2020 7:46 am

Hi,

Most of the demos block popup windows because they show how to do one or two things. Adding popup handling to all of them would complicate the code.

There are 2 ways to handle popup windows :
  • Letting CEF create the new popup windows : This option is used by the MiniBrowser demo.
  • Creating the popup windows from Delphi code : This option is used by the PopupBrowser2 demo.
If you don't need to create Delphi forms for the popups then use the code in the MiniBrowser demo. Notice that many events in that demo call the Chromium1.IsSameBrowser function because using this option for the popup windows will use the same TChromium component for your main browser AND the browser in the new popup windows. This means that all the browser events in the popup windows will trigger TChromium events in your main form too.

If you need absolute control of all the forms created by the browser then you have to use the code in the PopupBrowser2 demo. The challenge with this solution is that you have to create and destroy the popup forms in the main application thread but the TChromium events are executed in a CEF thread. This is the reason why this demo creates a hidden form that will be used as a popup form when CEF needs to show a popup window. All that process has to be protected by critical sections and coordinated with windows messages.

Dilfich mentioned an alternative way to show popup windows. You would only need to block the popup windows and copy their URL to load them with your TChromium components. This is much easier but you will have issues if the web page that created the popup window tries to modify the browser in the popup window and you'll also have issues handling POST requests with this solution.

Lu53
Posts: 8
Joined: Mon Jan 20, 2020 1:02 pm

Re: How to corectly handle pop-ups without crashing Delphi

Post by Lu53 » Fri Feb 14, 2020 12:12 pm

Thank you Salvador for your explanations!
I'll checkk the resources you mentioned.
Regards, Lu

coater
Posts: 114
Joined: Sat Sep 29, 2018 1:51 pm

Re: How to corectly handle pop-ups without crashing Delphi

Post by coater » Fri Feb 28, 2020 2:14 pm

How to show DevTools for popup browser?
Keen for your help, thank you!

User avatar
salvadordf
Posts: 2640
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: How to corectly handle pop-ups without crashing Delphi

Post by salvadordf » Sat Feb 29, 2020 8:18 am

coater wrote:
Fri Feb 28, 2020 2:14 pm
How to show DevTools for popup browser?
Keen for your help, thank you!
In this case I would use a custom Delphi form for the popup window that includes a second TCEFWindowParent for the DevTools.

coater
Posts: 114
Joined: Sat Sep 29, 2018 1:51 pm

Re: How to corectly handle pop-ups without crashing Delphi

Post by coater » Sat Feb 29, 2020 2:12 pm

salvadordf wrote:
Sat Feb 29, 2020 8:18 am
coater wrote:
Fri Feb 28, 2020 2:14 pm
How to show DevTools for popup browser?
Keen for your help, thank you!
In this case I would use a custom Delphi form for the popup window that includes a second TCEFWindowParent for the DevTools.
Is it possible to use the same DevTools as main browser?

User avatar
salvadordf
Posts: 2640
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: How to corectly handle pop-ups without crashing Delphi

Post by salvadordf » Sun Mar 01, 2020 8:04 am

I haven't tried it but I guess it's also possible.

If you let CEF create the window popups you could also show the DevTool by adding a custom context menu option.

Then use the regular TChromium.ShowDevTools function for the main browser and a custom code for all other popup browsers like this :

Code: Select all

procedure TForm1.Chromium1ContextMenuCommand(Sender: TObject;
  const browser: ICefBrowser; const frame: ICefFrame;
  const params: ICefContextMenuParams; commandId: Integer;
  eventFlags: Cardinal; out Result: Boolean);
var
  TempPoint : TPoint;
  TempInfo : TCefWindowInfo;
  TempClient : ICefClient;
  TempSettings : TCefBrowserSettings;
begin
  Result := False;

  case commandId of
    MINIBROWSER_CONTEXTMENU_SHOWDEVTOOLS :
      if Chromium1.IsSameBrowser(browser) then
        begin
          TempPoint.x := params.XCoord;
          TempPoint.y := params.YCoord;
          Chromium1.ShowDevTools(TempPoint, nil);
        end
       else
        try
          WindowInfoAsPopUp(TempInfo, browser.Host.WindowHandle, 'DevTools');
          TempClient := TCustomClientHandler.Create(Chromium1, True);
          FillChar(TempSettings, SizeOf(TCefBrowserSettings), 0);
          browser.Host.ShowDevTools(@TempInfo, TempClient, @TempSettings, nil);
        finally  
          TempClient := nil
        end; 
  end;
end;
This code assumes you have a TChromium component called Chromium1

User avatar
salvadordf
Posts: 2640
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: How to corectly handle pop-ups without crashing Delphi

Post by salvadordf » Sun Mar 01, 2020 8:40 am

I tested that code in the MiniBrowser demo and uploaded it to GitHub.

Download CEF4Delphi again and load this address in the MiniBrowser demo to test it :
https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_win_open3

Post Reply