文章目录

    • 1.应用程序
    • 2.客户端
    • 3.浏览器生命周期
    • 4.作者答疑

1.应用程序

  该CefApp接口提供对特定接口回调。重要的回调包括:

  • OnBeforeCommandLineProcessing提供了以编程方式设置命令行参数的机会。有关更多信息,请参阅“命令行参数”部分。
  • OnRegisterCustomSchemes提供注册自定义方案的机会。有关更多信息,请参阅“请求处理”部分。
  • GetBrowserProcessHandler返回特定于浏览器进程的功能的处理程序,包括 OnContextInitialized() 方法。
  • GetRenderProcessHandler返回特定于渲染过程的功能的处理程序。这包括与 JavaScript 相关的回调和处理消息。有关更多信息,请参阅JavaScriptIntegration Wiki 页面和“进程间通信”部分。

  一个示例 CefApp 实现可以在cefsimple/simple_app.h和cefsimple/simple_app.cc 中看到。

2.客户端

  该CefClient接口提供对浏览器的实例特有的回调。单个 CefClient 实例可以在任意数量的浏览器之间共享。重要的回调包括:

  • 浏览器生命周期、上下文菜单、对话框、显示通知、拖动事件、焦点事件、键盘事件等处理程序。大多数处理程序是可选的。有关不实现特定处理程序的副作用(如果有),请参阅 cef_client.h 中的文档。
  • OnProcessMessageReceived在从渲染进程接收到 IPC 消息时调用。有关更多信息,请参阅“进程间通信”部分。

  一个示例 CefClient 实现可以在cefsimple/simple_handler.h和cefsimple/simple_handler.cc 中看到。

3.浏览器生命周期

  浏览器生命周期从调用 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 应用程序。

4.作者答疑


  如有疑问,请留言。