您的位置:首页 > 其它

CEF 嵌入到MFC的流程,包括启动CEF以及CEF程序的关闭流程。

2017-05-23 22:52 417 查看
CEF嵌入到MFC的例子很多,网上也很容易可以找到,我用的CEF版本是cef_binary_3.2171.1979_windows32,开发环境是VS2008。

大致流程是:

1,在应用程序InitInstance()中,初始化CEF:

void* sandbox_info = NULL;
CefMainArgs main_args(theApp.m_hInstance);
CefRefPtr<ClientApp> app(new ClientApp);

int exit_code = CefExecuteProcess(main_args, app.get(), sandbox_info);
if (exit_code >= 0) {
// The sub-process has completed so return here.
return exit_code;
}

CefSettings settings;
//CefSettingsTraits::init(&settings);
settings.single_process = true;
settings.no_sandbox = true;
settings.multi_threaded_message_loop=true;
CefInitialize(main_args, settings, app.get(), sandbox_info);

这里用的是单进程模式;

2,创建浏览器。

在要创建浏览器的窗口里,创建浏览器,例如在一个对话框里OnInitDialog()函数里:

CRect rt;
GetClientRect(&rt);

CefWindowInfo window_info;

window_info.SetAsChild(this->GetSafeHwnd(), rt);
m_handler = new ClientHandler();
m_handler->SetMainWindowHandle(m_hWnd);
CefBrowserSettings browser_settings;
std::string url;
url = "www.baidu.com";
CefBrowserHost::CreateBrowser(window_info, m_handler.get(), url, browser_settings, NULL);

这里的m_handler是继承了CefClient以及其他接口类的一个类,用来管理浏览器的行为,例如加载、重新加载、前进、后退等,基本上是围绕这个类做文章。
至此已经创建好了一个浏览器。要丰富浏览器的功能,则需要继承更多的接口类并实现对应的方法。cefclient方法已经实现了较多的接口,可以参考。

主要讲下关闭CEF程序的流程。

之前在网上看到的都说在应用程序的ExitInstance()中调用CefShutdown(),实践了一下发现在退出时会崩溃。在网上看了一些资料,其中
https://github.com/fanfeilong/cefutil/blob/master/doc/CEF_Close.md
这里说的比较好,我也是参照这个来说以下的关闭流程。

1,在退出应用程序前,一般是窗口收到WM_CLOSE消息的响应函数OnClose中,需要调用browser->GetHost()->CloseBrowser(false);来关闭一个浏览器,也有关闭所有浏览器的方法(见cefclient例子里的ClientHandler::CloseAllBrowsers),调用了CloseBrowser后,CEF会调用DoClose,然后会再发一个WM_CLOSE给窗口,此时继续进入到OnClose中,这时就可以关闭窗口了,因此OnClose的实现大概是这样的:

if (m_handler.get() && !m_handler->IsClosing()) {
CefRefPtr<CefBrowser> browser = m_handler->GetBrowser();
if (browser.get()) {
// Notify the browser window that we would like to close it. This
// will result in a call to ClientHandler::DoClose() if the
// JavaScript 'onbeforeunload' event handler allows it.
browser->GetHost()->CloseBrowser(false);

// Cancel the close.

return ;
}
}

// Allow the close
CDialog::OnClose();

如果这是个顶层窗口,即app的m_pMainWnd,那么执行CDialog::OnClose()之后,会有个群发的WM_DESTROY,此时CEF会调用OnBeforeClose,指示浏览器马上要关闭了,cefclient中还增加了判断浏览器个数为0,则发送退出消息,指示应用程序可以退出了。
如果承载了浏览器的对话框不是顶层窗口,那么在第二次进入OnClose,即允许窗口关闭的流程时,需要告诉顶层窗口,顶层窗口收到此消息后,再执行顶层窗口的OnClose。

2,在所有浏览器都关闭之后,MFC应用程序就可以退出了,网上的说法是在ExitInstance()里调用CefShutdown(),实践证明在Debug模式下会崩溃,后来我改到在

InitInstance 返回前调用,则不会有问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: