这是一个非常简单的QT + CEF窗口应用程序,请参阅https://github.com/GreatTux/CefMinGWQt
当我关闭主窗口CEF触发断点时: 我想我在这里失败了:
void CefBrowserMainParts::PostMainMessageLoopRun() {
....
#ifndef NDEBUG
// No CefBrowserContext instances should exist at this point.
DCHECK_EQ(0, CefBrowserContext::DebugObjCt);
#endif
}
我不知道释放浏览器资源的正确方法是什么,我在网上看了很多例子,几乎所有这些都在我的Windows 7 + vs2010环境中遇到了这个问题
我也试过这个但是没有工作
void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
if(m_browser.get())
m_browser = NULL;
==== trace ===
libcef.dll!base::debug::BreakDebugger() Line 21 C++
libcef.dll!logging::LogMessage::~LogMessage() Line 604 C++
libcef.dll!CefBrowserMainParts::PostMainMessageLoopRun() Line 189 C++
libcef.dll!content::BrowserMainLoop::ShutdownThreadsAndCleanUp() Line 946 + 0x27 bytes C++
libcef.dll!content::BrowserMainRunnerImpl::Shutdown() Line 293 C++
libcef.dll!CefMainDelegate::ShutdownBrowser() Line 659 + 0x1b bytes C++
libcef.dll!CefContext::FinalizeShutdown() Line 462 C++
libcef.dll!CefContext::Shutdown() Line 345 C++
libcef.dll!CefShutdown() Line 171 C++
libcef.dll!cef_shutdown() Line 192 C++
qtloop.exe!CefShutdown() Line 180 + 0x8 bytes C++
qtloop.exe!main(int argc=1, char * * argv=0x00375b90) Line 35 C++
qtloop.exe!WinMain(HINSTANCE__ * __formal=0x00fe0000, HINSTANCE__ * __formal=0x00fe0000, HINSTANCE__ * __formal=0x00fe0000, HINSTANCE__ * __formal=0x00fe0000) Line 113 + 0xd bytes C++
qtloop.exe!__tmainCRTStartup() Line 547 + 0x2c bytes C
qtloop.exe!WinMainCRTStartup() Line 371 C
答案 0 :(得分:2)
关闭主窗口时,Qt不会立即破坏它,所以cef浏览器不会释放。此时app.exec()返回,并且运行了CefShowDown()并触发调试检查。
我也遇到了同样的问题。 这是因为当你关闭Cef时,浏览器也没有空闲
DCHECK_EQ(0,CefBrowserContext :: DebugObjCt);
我读了这篇文章并阅读了cef close process的源代码 https://github.com/fanfeilong/cefutil/blob/master/doc/CEF_Close.md
我解决了问题,关键是,当你打电话
GETHOST() - &GT; CloseBrowser(假)
在cef上嵌入父窗口的closeEvent并忽略第一个closeEvent
然后,如果用户允许关闭,cef将再次发送接近父根窗口。
void CefBrowserHostImpl::PlatformCloseWindow() {
if (window_info_.window != NULL) {
HWND frameWnd = GetAncestor(window_info_.window, GA_ROOT);
PostMessage(frameWnd, WM_CLOSE, 0, 0);
}
}
当您重新开始第二次关闭时,您需要确保关闭窗口并将窗口立即嵌入。 Cef需要WM_DESTROY事件来释放资源并调用OnBeforeClose。
答案 1 :(得分:0)
您需要关闭钩子窗口操作,并确保先关闭cef浏览器。
标准流程为(摘自cef注释,有一些修改):
//
// 1. User clicks the window close button which sends a close notification to
// the application's top-level window.
// 2. Application's top-level window receives the close notification and:
// A. Calls CefBrowserHost::CloseBrowser(false).
// B. Cancels the window close.
// 3. JavaScript 'onbeforeunload' handler executes and shows the close
// confirmation dialog (which can be overridden via
// CefJSDialogHandler::OnBeforeUnloadDialog()).
// 4. User approves the close.
// 5. JavaScript 'onunload' handler executes.
// 6. Application's DoClose() handler is called. Application will:
// A. Set a flag to indicate that the next close attempt will be allowed.
// B. Return false.
// 7. Sends an close notification to the application's top-level window.
// 8. Application's top-level window receives the close notification and
// allows the window to close based on the flag from #6B.
// 9. Application's top-level window is destroyed.
// 10. Application's OnBeforeClose() handler is called and the browser object
// is destroyed.
// 11. Application exits by calling CefQuitMessageLoop() if no other browsers
// exist.
///
我已经基于QT + CEF OSR编写了一个名为QCefWidget的项目。 它具有完善的退出逻辑。 你可以参考