Disclosure Statement: This site contains affiliate links, which means that I may receive a commission if you make a purchase using these links. As an eBay Partner, I earn from qualifying purchases.
If you find these projects useful please consider becoming a sponsor with Patreon, GitHub or Liberapay.

Troubles with BrowserCompMsg

Post Reply
User avatar
RedOctober
Posts: 8
Joined: Sat Jul 07, 2018 12:59 pm
Location: Montenegro
Contact:

Troubles with BrowserCompMsg

Post by RedOctober »

Hello,

I have this code:

Code: Select all

procedure TForm1.Chromium1BrowserCompMsg(var aMessage: TMessage; var aHandled: Boolean);
var
  Handled: Boolean;
  url_to_open: string;
begin
  if (Chromium1 = nil) or (aMessage.MSG <> 528) OR (Handled = true) then
    exit;
  if (aMessage.MSG = 528)
    memo1.Lines.Add('Clicked on browser');
end;
Everything is fine, but: when I do a SINGLE click on browser I have a lot of firing this event (from 3 to 30), although I should have only one for each click. What's going wrong? Thanks in advance for answers!
User avatar
salvadordf
Posts: 4564
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: Troubles with BrowserCompMsg

Post by salvadordf »

As you know, CEF3 doesn't expose mouse events when you use it in "normal mode" and another user called Winexcel suggested that it could be useful to intercept all the missing Windows messages.

CEF3 creates a few child components inside TCEFWindowParent and the TChromium.OnBrowserCompMsg, TChromium.OnWidgetCompMsg and TChromium.OnRenderCompMsg events are used to intercept the messages to those components.

The MiniBrowser demo uses one of those events to show the mouse coordinates but there's a known bug and this only works for the first web page loaded from the address edit box.

What you get in those events are all the Windows messages sent to those components and perhaps some custom CEF3 messages.

None of those events are supported by CEF3 and even if you find a fix for the bug commented previously, it would be risky to use them in a commercial app.

It's recommended to use alternative ways to get mouse clicks :
  • Using TChromium in OSR mode. Take a look at the SimpleOSRBrowser demo.
  • Using TChromium in normal mode but adding some JavaScript code that calls a JavaScript extension every time you click in the document. The JSRTTIExtensiondemo has almost all the code you need for this.
User avatar
RedOctober
Posts: 8
Joined: Sat Jul 07, 2018 12:59 pm
Location: Montenegro
Contact:

Re: Troubles with BrowserCompMsg

Post by RedOctober »

Hello Salvador,

thanks for your answer! Well, in my project I use a significantly modified part of JSRTTIExtensiondemo code. For example:

Code: Select all

procedure TMiniBrowserFrm.Chromium1LoadingStateChange(Sender: TObject; const browser: ICefBrowser; isLoading, canGoBack, canGoForward: Boolean);
begin
  if not(Chromium1.IsSameBrowser(browser)) or FClosing then
    exit;

  if isLoading=False then
  begin
    Chromium1.browser.MainFrame.ExecuteJavaScript('document.body.addEventListener("mouseover", function(evt){' + 'function nodeToString ( node ) {  var tmpNode = document.createElement( "div" );tmpNode.appendChild( node.cloneNode( true ) );' +
      ' var str = tmpNode.outerHTML; tmpNode = node = null; return str;};function getpath(n){' + 'var ret = nodeToString(n);return ret};' + 'var element = evt.target;' + 'var tag = element.tagName.toLowerCase();' +
      'var id = element.id ? "#"+element.id:"";' + 'var classes = element.classList.toString().replace(/\s/, ".");' + 'var classes = classes ? "."+classes:"";' + 'var width = window.getComputedStyle(element).width;' +
      'var height = window.getComputedStyle(element).height;' + 'var return_str=tag+id+classes;' + 'myextension.mouseover(getpath(evt.target)+"["+return_str+"]")}' + ')', 'about:blank', 0);
  end;
end; 
So each time I have a DOM element name and attributes when mouse over, like this:

Code: Select all

<div><div class="ui fluid button">Sign In</div></div>[div.ui.fluid button]
Then I catch a click, but via messages, because through javascript it is not always possible to correctly handle the mouse click event. So I fixed my code a bit:

Code: Select all

procedure TMiniBrowserFrm.Chromium1BrowserCompMsg(var aMessage: TMessage; var aHandled: Boolean);
begin
  //dom_element - this is the variable where mouseover's DOM element is stored
  if (Chromium1 = nil) or (aMessage.Msg <> 528) OR (Handled = true) then
    exit;

  //This is my fix. If current DOM element is equal with previous DOM element - then do nothing
  if (prev_dom_element = dom_element) then
    exit;

  if (aMessage.Msg = 528) AND (Length(dom_element) < 300) AND (Length(trim(dom_element)) > 1) AND (pos('<', dom_element) > 0) then
  begin
    prev_dom_element := dom_element; 
    if (pos('[a#error_page_open_dns_help]', dom_element) > 0) then
    begin
      ShellExecute(Handle, 'open', pchar('https://1.1.1.1/'), nil, nil, SW_NORMAL);
    end;
   // And so on
  end;
end;
coater
Posts: 187
Joined: Sat Sep 29, 2018 1:51 pm

Re: Troubles with BrowserCompMsg

Post by coater »

salvadordf wrote: Sun Aug 26, 2018 12:37 pm As you know, CEF3 doesn't expose mouse events when you use it in "normal mode" and another user called Winexcel suggested that it could be useful to intercept all the missing Windows messages.

CEF3 creates a few child components inside TCEFWindowParent and the TChromium.OnBrowserCompMsg, TChromium.OnWidgetCompMsg and TChromium.OnRenderCompMsg events are used to intercept the messages to those components.

The MiniBrowser demo uses one of those events to show the mouse coordinates but there's a known bug and this only works for the first web page loaded from the address edit box.

What you get in those events are all the Windows messages sent to those components and perhaps some custom CEF3 messages.

None of those events are supported by CEF3 and even if you find a fix for the bug commented previously, it would be risky to use them in a commercial app.

It's recommended to use alternative ways to get mouse clicks :
  • Using TChromium in OSR mode. Take a look at the SimpleOSRBrowser demo.
  • Using TChromium in normal mode but adding some JavaScript code that calls a JavaScript extension every time you click in the document. The JSRTTIExtensiondemo has almost all the code you need for this.
procedure WMParentNotify(var Message: TWMParentNotify); message WM_PARENTNOTIFY;
procedure TChildForm.WMParentNotify(var Message: TWMParentNotify);
if (Message.Msg = WM_PARENTNOTIFY) and ( (Message.Unused1 = 513) or (Message.Unused2 = 513) ) then

MSG of those mouse events will be upto mainform event happened in annother browser!
coater
Posts: 187
Joined: Sat Sep 29, 2018 1:51 pm

Re: Troubles with BrowserCompMsg

Post by coater »

It is very strange that Chromium_OnRenderCompMsg cannot obtain the message in render when browser is opened by difference JS code.
this not: <a onclick="_openDetailedInfo('1A',this)" in a web ,
this done:<a class="highlight_ALL" href="javascript:openDetailedInfo('A','6')" in a web :roll:
Last edited by coater on Sun Dec 08, 2024 12:56 am, edited 1 time in total.
coater
Posts: 187
Joined: Sat Sep 29, 2018 1:51 pm

Re: Troubles with BrowserCompMsg

Post by coater »

procedure TChildForm.FormCreate(Sender: TObject);:
Chromium := TChromium.Create(self);
Chromium.OnRenderCompMsg := MiniBrowserFrm.Chromium_OnRenderCompMsg;
Chromium.onBeforePopup := MiniBrowserFrm.Chromium_onBeforePopup;

all is same! just popup created by different JS code! WHY???

I think it has some relation with CreateClientHandler(var windowInfo: TCefWindowInfo; var client: ICefClient; const targetFrameName: string; const popupFeatures: TCefPopupFeatures): Boolean
client may be different?
User avatar
salvadordf
Posts: 4564
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: Troubles with BrowserCompMsg

Post by salvadordf »

The OnRenderCompMsg event only works for the current browser.

If you used the PopupBrowser2 demo as a template for your application and each window has a different TChromium component then you need to use the Chromium.OnRenderCompMsg event on each window.
coater
Posts: 187
Joined: Sat Sep 29, 2018 1:51 pm

Re: Troubles with BrowserCompMsg

Post by coater »

YES, I create a form with a chromium, and so on for every new window. By [Chromium.OnRenderCompMsg := MiniBrowserFrm.Chromium_OnRenderCompMsg] in the form I can obtain messages in different new window by Chromium.OnRenderCompMsg, but one not! This one is a pop up window triggered by [ <a onclick="_openDetailedInfo('1A',this)"] in a web. But in the same web, I can obtain the messages in a pop up window triggered by [ "<a class="highlight_ALL" href="javascript:openDetailedInfo('A','6')"] in the same web.

In the same web!!!
So, it is very strange!
coater
Posts: 187
Joined: Sat Sep 29, 2018 1:51 pm

Re: Troubles with BrowserCompMsg

Post by coater »

may be this is a bug of "109.1.18+gf1c41e4+chromium-109.0.5414.120"
Post Reply