Page 1 of 1
Troubles with BrowserCompMsg
Posted: Sun Aug 26, 2018 12:02 pm
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!
Re: Troubles with BrowserCompMsg
Posted: Sun Aug 26, 2018 12:37 pm
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.
Re: Troubles with BrowserCompMsg
Posted: Mon Aug 27, 2018 10:33 am
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;
Re: Troubles with BrowserCompMsg
Posted: Tue Dec 03, 2024 9:30 am
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!
Re: Troubles with BrowserCompMsg
Posted: Tue Dec 03, 2024 2:27 pm
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

Re: Troubles with BrowserCompMsg
Posted: Sat Dec 07, 2024 2:32 am
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?
Re: Troubles with BrowserCompMsg
Posted: Sat Dec 07, 2024 5:43 pm
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.
Re: Troubles with BrowserCompMsg
Posted: Sun Dec 08, 2024 12:55 am
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!
Re: Troubles with BrowserCompMsg
Posted: Tue Dec 10, 2024 1:03 pm
by coater
may be this is a bug of "109.1.18+gf1c41e4+chromium-109.0.5414.120"