每个CEF3应用程序都有一个相同的结构:
CEF3应用程序都是以多进程方式运行的。这些进程都可以使用相同的可执行文件和独立的可执行文件被分配在每个子进程上。每个可执行进程都有一个入口函数。
每个CEF3子进程运行时使用运行行来指定配置信息并通过CefMainArgs结构传递给CefExecuteProcess函数,CefMainArgs结构是跨平台的。
如:
 CefMainArgs main_args(argc, argv); 
 CefMainArgs main_args(hInstance);
当单可执行体时行时,入口函数CefExecuteProcess在不同进程类型之间需要区分。单可执行体结构只支持window和linux,不支持macos
当使用一个分离的子进程执行体时需要两个分离的进程和入口函数。
CEF可集成已经存在的应用程序消息循环来代替它自己的消息循环。有2种方式:
CefSettings结构允许Cef配置应用程序类型。以下列出通用的成员:
remote_debugging_port远程调试端口。范围在1024~65535
CefBrowser和CefFrame对象用于向浏览器发送命令和接受回调函数的状态信息。每个CerBrowser对象有一个主CefFrame对象描述主窗口。有零个和多个描述子窗口。例如:一个浏览器加载两个窗口会有三个CefFrame对象,一个是顶层窗口,两个子窗口。
在主窗口中加载一个URL:
browser->GetMainFrame()->LoadURL(some_url);
调用浏览的返回按钮:
browser->GoBack();
获取主窗口的HTML内容
class Visitor : public CefStringVisitor {
public: Visitor() {}
virtual void Visit(const CefString& string) OVERRIDE { // Do something with |string|... }
IMPLEMENT_REFCOUNTING(Visitor);
};
browser->GetMainFrame()->GetSource(new Visitor());
CefBrowser和CefFrame对象分别存在浏览进程和渲染进程中。在浏览进程中可通过CefBrowser::GetHoset()函数控制主机行为,如获取窗口句柄:
CefWindowHandle window_handle = browser->GetHost()->GetWindowHandle();
CefApp接口提供特殊进程回调的访问。重要的回调包括:
OnBeforeCommandLineProcessing 以编程的方式设置命令行
OnRegisterCustomSchemes 提供一个机会自定义主题
GetBrowserProcessHandler 指定浏览进程及包括 OnContextInitialized() 特定功能的处理者
GetRenderProcessHandler 渲染进程的处理者,包括JavaScript关联的回调和进程消息
 CefClient接口提供了浏览器实例的特定回调。一个CefClient实例可以被多个浏览器共享。重要的回调包括:
浏览器生命周期,上下文菜单,对话框,显示通知,拖拽事件,焦点事件,键盘事件的处理者
OnProcessMessageReceived 从渲染进程中发来的IPC消息的接受。 
Browser Life Space 以调用 CefBrowserHost::CreateBrowser()或CefBrowserHost::CreateBrowserSync()函数开始。 方便执行逻辑,包括CefBrowserProcessHandler::OnContextInitialized()或像WM_CREATE消息处理的调用。
CefLifeSpaceHandler类提供了管理浏览器生命周期的回调。
void MyClient::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
  // Must be executed on the UI thread.
  REQUIRE_UI_THREAD();
  // Protect data members from access on multiple threads.
  AutoLock lock_scope(this);  // Deprecated -- see the “Threads” section.
  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() 销毁浏览进程 如:browser->GetHost()->CloseBrowser(false)
如果浏览器是其他窗口的父窗口,那么这个关闭事件会引起父窗口的系统函数调用。那父窗口需要调用 CloseBrowser(false) 并等待第二个系统调用的关闭事件来指示浏览进程允许关闭。
如果关闭通过Javascript事件或DoClose()回调函数处理,那第二个系统关闭事件就不会被发送。
IsClosing()测试是否关闭,如果是第一次的系统关闭事件就返回false,每二次返回true; 
第一个系统关闭事件是在窗口的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;
}
DoClose() 设置m_blsClosing标识并设置第二次系统关闭事件为false
bool MyClient::DoClose(CefRefPtr<CefBrowser> browser) {
  // Must be executed on the UI thread.
  REQUIRE_UI_THREAD();
  // Protect data members from access on multiple threads.
  AutoLock lock_scope(this);
  // 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()) {
    // Notify the browser that the parent window is about to close.
    browser->GetHost()->ParentWindowWillClose();
    // 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 在接受第二次OS关闭事件之前需要调用OnBeforeCloseb函数释放浏览器进程的引用。
原文:http://www.cnblogs.com/h2zZhou/p/6871872.html