该CefApp接口提供对特定接口回调。重要的回调包括:
一个示例 CefApp 实现可以在cefsimple/simple_app.h和cefsimple/simple_app.cc 中看到。
该CefClient接口提供对浏览器的实例特有的回调。单个 CefClient 实例可以在任意数量的浏览器之间共享。重要的回调包括:
一个示例 CefClient 实现可以在cefsimple/simple_handler.h和cefsimple/simple_handler.cc 中看到。
浏览器生命周期从调用 CefBrowserHost::CreateBrowser() 或 CefBrowserHost::CreateBrowserSync() 开始。执行此逻辑的便利位置包括 CefBrowserProcessHandler::OnContextInitialized() 回调或特定于平台的消息处理程序,如 Windows 上的 WM_CREATE。
// Information about the window that will be created including parenting, size, etc.
// The definition of this structure is platform-specific.
CefWindowInfo info;
// On Windows for example...
info.SetAsChild(parent_hwnd, client_rect);
// Customize this structure to control browser behavior.
CefBrowserSettings settings;
// CefClient implementation.
CefRefPtr<MyClient> client(new MyClient);
// Create the browser asynchronously. Initially loads the Google URL.
CefBrowserHost::CreateBrowser(info, client.get(), “http://www.google.com”, settings, NULL);
CefLifeSpanHandler类提供了一些必要的管理浏览器寿命的回调。以下是相关方法和成员的摘录。
class MyClient : public CefClient,
public CefLifeSpanHandler,
...
{
// CefClient methods.
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE
{
return this;
}
// CefLifeSpanHandler methods.
void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
// Member accessors.
CefRefPtr<CefBrowser> GetBrower()
{
return m_Browser;
}
bool IsClosing()
{
return m_bIsClosing;
}
private:
CefRefPtr<CefBrowser> m_Browser;
int m_BrowserId;
int m_BrowserCount;
bool m_bIsClosing;
IMPLEMENT_REFCOUNTING(MyClient);
};
OnAfterCreated() 方法将在浏览器对象创建后立即调用。宿主应用程序可以使用此方法来保持对主浏览器对象的引用。
void MyClient::OnAfterCreated(CefRefPtr<CefBrowser> browser)
{
// Must be executed on the UI thread.
REQUIRE_UI_THREAD();
if (!m_Browser.get())
{
// Keep a reference to the main browser.
m_Browser = browser;
m_BrowserId = browser->GetIdentifier();
}
// Keep track of how many browsers currently exist.
m_BrowserCount++;
}
要销毁浏览器,请调用 CefBrowserHost::CloseBrowser()。
// 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(false);
如果浏览器是另一个窗口的父窗口,则关闭事件可能源自该父窗口的 OS 函数(例如,通过单击父窗口上的 X)。然后父窗口需要调用 CloseBrowser(false) 并等待第二个操作系统关闭事件以指示浏览器已允许关闭。如果关闭被 JavaScript ‘onbeforeunload’ 事件处理程序或 DoClose() 回调取消,则不会发送第二个操作系统关闭事件。请注意以下示例中的 IsClosing() 检查——它将为第一个 OS 关闭事件返回 false,为第二个(在调用 DoClose 之后)返回 true。在 Windows 上的父窗口 WndProc 中处理:
case WM_CLOSE:
if (g_handler.get() && !g_handler->IsClosing())
{
CefRefPtr<CefBrowser> browser = g_handler->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(false);
// Cancel the close.
return 0;
}
}
// Allow the close.
break;
case WM_DESTROY:
// Quitting CEF is handled in MyHandler::OnBeforeClose().
return 0;
}
在 Linux 上处理“delete_event”信号:
gboolean delete_event(GtkWidget *widget, GdkEvent *event, GtkWindow *window)
{
if (g_handler.get() && !g_handler->IsClosing())
{
CefRefPtr<CefBrowser> browser = g_handler->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(false);
// Cancel the close.
return TRUE;
}
}
// Allow the close.
return FALSE;
}
在 OS X 上关闭更复杂。请参阅cefsimple/cefsimple_mac.mm中的注释以全面了解关闭在该平台上的工作原理。DoClose() 方法设置 m_bIsClosing 标志并返回 false 以发送第二个操作系统关闭事件。
bool MyClient::DoClose(CefRefPtr<CefBrowser> browser)
{
// Must be executed on the UI thread.
REQUIRE_UI_THREAD();
// 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;
}
// Allow the close. For windowed browsers this will result in the OS close
// event being sent.
return false;
}
当操作系统函数接收到第二个操作系统关闭事件时,它允许父窗口实际关闭。这将导致对 OnBeforeClose() 的调用。确保在 OnBeforeClose() 回调中释放对浏览器对象的任何引用。
void MyHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser)
{
// Must be executed on the UI thread.
REQUIRE_UI_THREAD();
if (m_BrowserId == browser->GetIdentifier())
{
// Free the browser pointer so that the browser can be destroyed.
m_Browser = NULL;
}
if (--m_BrowserCount == 0)
{
// All browser windows have closed. Quit the application message loop.
CefQuitMessageLoop();
}
}
有关每个平台上完整的工作示例,请参阅 cefclient 应用程序。
如有疑问,请留言。