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.

Bug-fix for MultiThreadedMessageLoop = False

Post Reply
hvassbotn
Posts: 29
Joined: Tue Apr 25, 2017 3:02 pm
Location: Oslo, Norway
Contact:

Bug-fix for MultiThreadedMessageLoop = False

Post by hvassbotn »

We couldn't get MultiThreadedMessageLoop mode to work (application-level keyboard shortcuts stopped working etc), so we turned it off, but then FInitialized was never set to True.

The easiest fix was this:

Code: Select all

procedure TChromium.doOnAfterCreated(const browser: ICefBrowser);
begin
//  if MultithreadApp and (FBrowser = nil) then
  if {MultithreadApp and} (FBrowser = nil) then // HV
    begin
      FBrowser := browser;
      if (FBrowser <> nil) then FBrowserId := FBrowser.Identifier;
    end;

  Internal_UpdatePreferences;

  FInitialized := (FBrowser <> nil) and (FBrowserId <> 0);

  if Assigned(FOnAfterCreated) then FOnAfterCreated(Self, browser);
end;
The get the InstanceCount to work in MultiThreadedMessageLoop = False mode, we had to make two more changes:

Code: Select all

constructor TVCLClientHandler.Create(const crm: IChromiumEvents; renderer : Boolean);
begin
  inherited Create(crm, renderer);

  if not(MultithreadApp) and not(ExternalMessagePump) then
    begin
      if (CefInstances = 0) then CefTimer := SetTimer(0, 0, USER_TIMER_MINIMUM, @TimerProc);
    end;
  InterlockedIncrement(CefInstances);  // HV: Bug-fix
end;

destructor TVCLClientHandler.Destroy;
begin
  try
    try
      InterlockedDecrement(CefInstances); // HV: Bug-fix
      if not(MultithreadApp) and not(ExternalMessagePump) then
        begin
          if (CefInstances = 0) and (CefTimer <> 0) then
            begin
              KillTimer(0, CefTimer);
              CefTimer := 0;
            end;
        end;
User avatar
salvadordf
Posts: 4563
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: Bug-fix for MultiThreadedMessageLoop = False

Post by salvadordf »

I'll take a look at this over the weekend.
User avatar
salvadordf
Posts: 4563
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: Bug-fix for MultiThreadedMessageLoop = False

Post by salvadordf »

I'll take a deeper look at the MultithreadApp issue.

Meanwhile, the shortcuts can be fixed if you implement Application.OnMessage and Handle the WM_KEYDOWN, WM_KEYUP, WM_SYSCHAR, WM_SYSKEYDOWN, WM_SYSKEYUP and WM_CHAR messages;
hvassbotn
Posts: 29
Joined: Tue Apr 25, 2017 3:02 pm
Location: Oslo, Norway
Contact:

Re: Bug-fix for MultiThreadedMessageLoop = False

Post by hvassbotn »

Hm.

By what happens technically when you enable multi-threaded message handling?

The VCL message handling loop does not run at all?

Or it does run in the main thread, but does not see any of the messages sent to the browser window?

> Application.OnMessage and Handle the WM_KEYDOWN, WM_KEYUP, WM_SYSCHAR, WM_SYSKEYDOWN, WM_SYSKEYUP and WM_CHAR messages;

That is not easy to do, as the actual handling and implementation of those can be spread among a number of components today (action lists, actions, right-click menu, skinning library, etc).

And I'm not sure it would help. Why would messages be caught by Application.OnMessage if they are not caught by the normal VCL message flow?

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

Re: Bug-fix for MultiThreadedMessageLoop = False

Post by salvadordf »

hvassbotn wrote: Tue May 02, 2017 7:52 am Hm.
By what happens technically when you enable multi-threaded message handling?
The VCL message handling loop does not run at all?
Or it does run in the main thread, but does not see any of the messages sent to the browser window?
I didn't explain it as I should have.

The bug was in the initialization of TChromium when you set ClobalCEFApp.MultiThreadedMessageLoop := False;
This had nothing to do with other threads.

ClobalCEFApp.MultiThreadedMessageLoop is later used in the GlobalCEFApp initialization with the TCefSettings record and it's used to have the browser process message loop run in a separate thread.
hvassbotn wrote: Tue May 02, 2017 7:52 am > Application.OnMessage and Handle the WM_KEYDOWN, WM_KEYUP, WM_SYSCHAR, WM_SYSKEYDOWN, WM_SYSKEYUP and WM_CHAR messages;
That is not easy to do, as the actual handling and implementation of those can be spread among a number of components today (action lists, actions, right-click menu, skinning library, etc).
And I'm not sure it would help. Why would messages be caught by Application.OnMessage if they are not caught by the normal VCL message flow?
/H
I don't know the code of your application. I was just suggesting a common solution to many keyboard shortcuts problems when you use CEF3 or TWebBrowser.

You will also need to implement TChromium.OnPreKeyEvent and set isKeyboardShortcut := True when the key is considered a shortcut.
Post Reply