In my OSR-based tabbed browser, When I click a link in one tab, a new tab with a new TChromium is created and display the content of web page in the link.
But I found a strange thing. Some events in the new TChromium will be sent to the original TChromium which has the link too, including OnPaint, OnAfterCreated events and so on.
Why? How to stop it?
And if web page of the link has flash, the sound will be overlapped. After close the tab, the sound doesn't disappear.
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.
How to stop copying events to the original TChromium?
- salvadordf
- Posts: 4564
- Joined: Thu Feb 02, 2017 12:24 pm
- Location: Spain
- Contact:
Re: How to stop copying events to the original TChromium?
Each TChromium has a ICefClient field that manages many browser events.
When the TChromium.OnBeforePopup event is triggered you need to create a new ICefClient that will be used in the new tab or window. This is what happens in the PopupBrowser and PopupBrowser2 demos.
By default, CEF will use the same ICefClient from the original browser for the new browser. If you don't create a new ICefClient in the TChromium.OnBeforePopup event then CEF will use the same ICefClient and many events from both browsers will be triggered in the original TChromium. This is what happens in the MiniBrowser demo and this is the reason why that demo calls Chromium1.IsSameBrowser or checks Chromium1.BrowserId = browser.Identifier in those events.
Please, read the code comments in the PopupBrowser demo for more details.
When the TChromium.OnBeforePopup event is triggered you need to create a new ICefClient that will be used in the new tab or window. This is what happens in the PopupBrowser and PopupBrowser2 demos.
By default, CEF will use the same ICefClient from the original browser for the new browser. If you don't create a new ICefClient in the TChromium.OnBeforePopup event then CEF will use the same ICefClient and many events from both browsers will be triggered in the original TChromium. This is what happens in the MiniBrowser demo and this is the reason why that demo calls Chromium1.IsSameBrowser or checks Chromium1.BrowserId = browser.Identifier in those events.
Please, read the code comments in the PopupBrowser demo for more details.
Re: How to stop copying events to the original TChromium?
Thank you for your advice!
I read PopupBrowser demo carefully and modify my program according to the code comments.
The issue is fixed, but a new issue is found. When I close the popup tab, calling windows api destorywindow will fail (getlasterr=5 access denied). But the createwindow's thread and destorywindow' thread is the same.
I read PopupBrowser demo carefully and modify my program according to the code comments.
The issue is fixed, but a new issue is found. When I close the popup tab, calling windows api destorywindow will fail (getlasterr=5 access denied). But the createwindow's thread and destorywindow' thread is the same.
- salvadordf
- Posts: 4564
- Joined: Thu Feb 02, 2017 12:24 pm
- Location: Spain
- Contact:
Re: How to stop copying events to the original TChromium?
destroywindow sends a WM_DESTROY message to the control being destroyed but it also sends it to all its children controls.
Consider all TChromium events as being executed in a different thread and never create or destroy VCL controls in those events.
Sometimes, modifying a VCL component doesn't look like is creating or destroying anything and it seems harmless but the VCL code is calling RecreateWnd internally. If that happens inside a TChromium event you will get the error you mention.
If you use a Handle property inside a TChromium event check if it's allocated before using it like this :
If you try to use unallocated handles then Delphi will create them inside a TChromium event which is in a different thread. This can also be the cause of the "access denied" error.
Consider all TChromium events as being executed in a different thread and never create or destroy VCL controls in those events.
Sometimes, modifying a VCL component doesn't look like is creating or destroying anything and it seems harmless but the VCL code is calling RecreateWnd internally. If that happens inside a TChromium event you will get the error you mention.
If you use a Handle property inside a TChromium event check if it's allocated before using it like this :
Code: Select all
if MyControl.HandleAllocated then
begin
...
MyControl.Handle
...
end;
Re: How to stop copying events to the original TChromium?
Thank you for your advise! The issue is fixed now. 
