OnBeforeClose not being called

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

OnBeforeClose not being called

Postby andpad » Mon Oct 23, 2017 3:00 pm

I have an issue where the CefLifeSpanHandler::OnBeforeClose callback function is not being called.

I've followed the cefclient example and read the wiki, so I feel like I'm doing things correctly, but perhaps not? Let me state here what's happening:

    User closes the window
    WM_CLOSE message gets processed, CloseBrowser(false) gets called, and the close gets canceled by returning 0 in the WinProc
    CefLifeSpanHandler::DoClose() gets called, closing flag gets set, and returns false
    WM_DESTROY gets processed


What's odd here is that DoClose() is returning false, but another WM_CLOSE message does not seem to be coming to close the window and trigger the OnBeforeClose event.

Here are some details on the design/architecture:
I wrapped the functionality in a dll where I exposed a function called CreateBrowserWindow(), where I give it a parent window handle. This function creates a window using CreateWindowEx (where I give it the parent window handle), and on WM_CREATE of this window I create the browser window and set it as the child by calling CefWindowInfo::SetAsChild(). So here's a summary:
Window A (created in EXE) is parent of Window B (created in dll), which is parent of Window C (browser window). The window proc for window B is in the dll as well.

Miscellaneous info:
multi_threaded_message_loop is set to 1.

Relevent Code Snippets:

WM_CLOSE logic
Code: Select all
case WM_CLOSE:
   if (micefhandler.get() && !micefhandler->IsClosing())
   {
      CefRefPtr<CefBrowser> browser = micefhandler->GetBrowser();
      if (browser.get())
      {
         // Notify the browser window that we would like to close it. This will result in a call to
         // MyHandler::DoClose() if the JavaScript 'onbeforeunload' event handler allows it.
         browser->GetHost()->CloseBrowser(true);

         //cancel the close
         return 0;
      }
   }

   //close allowed
   result = DefWindowProc(window_handle, message, w_param, l_param);
      
   break;


CefLifeSpanHandler::DoClose logic
Code: Select all
bool MICefHandler::DoClose(CefRefPtr<CefBrowser> browser)
{
   //Must be executed on the UI thread
   CEF_REQUIRE_UI_THREAD();

   base::AutoLock lock_scope(lock_);

   // Closing the main window requires special handling. See the DoClose()
   // documentation in the CEF header for a detailed description of this
   // process.
   if (m_BrowserId == browser->GetIdentifier())
   {
      // Set a flag to indicate that the window close should be allowed.
      m_bIsClosing = true;
   }

   return false;
}


Any help is appreciated. Thank you.
Last edited by andpad on Wed Oct 25, 2017 10:32 am, edited 1 time in total.
andpad
Techie
 
Posts: 29
Joined: Mon Oct 23, 2017 1:57 pm

Re: OnBeforeClose not being called

Postby magreenblatt » Mon Oct 23, 2017 3:35 pm

What thread are you creating the parent window on? Creating parent/child windows on different threads can confuse windows message delivery.
magreenblatt
Site Admin
 
Posts: 10933
Joined: Fri May 29, 2009 6:57 pm

Re: OnBeforeClose not being called

Postby andpad » Mon Oct 23, 2017 5:43 pm

magreenblatt wrote:What thread are you creating the parent window on? Creating parent/child windows on different threads can confuse windows message delivery.

I'm creating the parent window on the main thread.
andpad
Techie
 
Posts: 29
Joined: Mon Oct 23, 2017 1:57 pm

Re: OnBeforeClose not being called

Postby jthach » Thu Dec 07, 2017 2:37 pm

We are experiencing the same issue and have followed the documentation from DoClose, where we wait to close the top-level window until the flag in DoClose is set and the browser can be destroyed. The issue is that even though the top-level window is being destroyed, OnBeforeClose isn't always called. Even though we have released all references to the CefSimpleHandler and it has gone out of scope and we call CefShutdown, CEF tries to add or release references to it and our application crashes. Like the above user, we are creating the parent window on the main thread. Any idea what could be going on?
jthach
Newbie
 
Posts: 5
Joined: Fri Jan 06, 2017 2:24 pm

Re: OnBeforeClose not being called

Postby G0apher » Fri Apr 09, 2021 10:54 am

I am facing this as well. Any clue on how to track the leaking Cef objects? This is crashing the application when CefShutdown() is called.
G0apher
Techie
 
Posts: 13
Joined: Sat Sep 22, 2018 12:16 am

Re: OnBeforeClose not being called

Postby rado » Sat Apr 10, 2021 2:57 am

I had the same issue. When you are using multithreaded message loop the problem is that OnBeforeClose is called on other thread than main thread. When second WM_CLOSE comes in main thread, it destroys main application window too quickly and application ends before OnBeforeClose has time to invoke. It seems it is necessary to wait for OnBeforeClose to have clean Cef shutdown. In MFC SDI application I've solved it by handling second WM_CLOSE so that it only destroys the view, not the frame window so Cef has time to invoke OnBeforeClose. In OnBeforeClose I just send WM_CLOSE message to frame window and then Cef shuts down succesfully.
rado
Expert
 
Posts: 110
Joined: Wed Oct 05, 2011 3:32 am


Return to Support Forum

Who is online

Users browsing this forum: Google [Bot] and 16 guests