文章目录

  • 1.程序入口文件-cefsimple_win.cc
  • 2.应用程序对象--SimpleApp
  • 3.应用程序句柄回调
  • 4.作者答疑

  libcef是一个封装良好的浏览器框架,它将具体的实现细节封装在抽象类中,而一般使用者可以通过继承和多态来修改它的局部功能过程,以此达到定制的目的。初学者可以先使用,然后再深究。本文从官方的一个例子初步讲解如何简单构建一个浏览器窗口。初步熟悉使用流程中的概念。

1.程序入口文件-cefsimple_win.cc

  在主程序文件中,首先打开了High-DPI支持,然后解析了进程传递进来的参数,CefExecuteProcess() 会根据不同的命令行参数来执行不同的进程,如果是浏览器进程,该函数立即返回,返回值为 -1。如果是其他进程,则在退出时才返回,返回值是一个大于0的数。接着构建一个应用程序实例,并将命令行参数和浏览器参数设置传递进App对象,运行浏览器进程消息循环,保证程序等待CefQuitMessageLoop()被调用,最后关闭CEF。注意一点,所有进程的入口点都在此,由CefExecuteProcess() 启动不同的功能的其它模块。

#include <windows.h>
#include "include/cef_sandbox_win.h"
#include "tests/cefsimple/simple_app.h"// When generating projects with CMake the CEF_USE_SANDBOX value will be defined
// automatically if using the required compiler version. Pass -DUSE_SANDBOX=OFF
// to the CMake command-line to disable use of the sandbox.
// Uncomment this line to manually enable sandbox support.
// #define CEF_USE_SANDBOX 1#if defined(CEF_USE_SANDBOX)//沙盒文件
// The cef_sandbox.lib static library may not link successfully with all VS
// versions.
#pragma comment(lib, "cef_sandbox.lib")
#endif//win32 进程入口函数
int APIENTRY wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow) {UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);// Enable High-DPI support on Windows 7 or newer.//在Windows 7或更新版本上启用High-DPI支持。CefEnableHighDPISupport();void* sandbox_info = NULL;#if defined(CEF_USE_SANDBOX)// Manage the life span of the sandbox information object. This is necessary// for sandbox support on Windows. See cef_sandbox_win.h for complete details.CefScopedSandboxInfo scoped_sandbox;sandbox_info = scoped_sandbox.sandbox_info();
#endif// Provide CEF with command-line arguments.//为CEF提供命令行参数。CefMainArgs main_args(hInstance);// CEF applications have multiple sub-processes (render, plugin, GPU, etc)// that share the same executable. This function checks the command-line and,// if this is a sub-process, executes the appropriate logic.//CEF应用程序有多个子进程(渲染、插件、GPU等)共享相同的可执行文件。该函数检查命令行,如果是子进程,则执行相应的逻辑。int exit_code = CefExecuteProcess(main_args, NULL, sandbox_info);if (exit_code >= 0) {// The sub-process has completed so return here.// 子进程已经完成,所以返回这里。return exit_code;}// Specify CEF global settings here.CefSettings settings;#if !defined(CEF_USE_SANDBOX)settings.no_sandbox = true;
#endif// SimpleApp implements application-level callbacks for the browser process.// It will create the first browser instance in OnContextInitialized() after// CEF has initialized.//SimpleApp 为浏览器进程实现应用程序级回调。 CEF 初始化后,它将在 OnContextInitialized() 中创建第一个浏览器实例。CefRefPtr<SimpleApp> app(new SimpleApp);// Initialize CEF.// 初始化CEFCefInitialize(main_args, settings, app.get(), sandbox_info);// Run the CEF message loop. This will block until CefQuitMessageLoop() is// called.//运行 CEF 消息循环。 这将阻塞,直到 CefQuitMessageLoop() 被调用。CefRunMessageLoop();// Shut down CEF.//关闭CEFCefShutdown();return 0;
}

2.应用程序对象–SimpleApp

  CefApp接口提供了不同进程的可定制回调函数,每一个进程对应一个CefApp接口。CefBrowserProcessHandler对应浏览器进程的回调,CefRenderProcessHandler对应渲染进程的回调。在在OnContextInitialized回调函数中进行应用程序参数初始化和窗口创建。

  simple_app.h文件

#ifndef CEF_TESTS_CEFSIMPLE_SIMPLE_APP_H_
#define CEF_TESTS_CEFSIMPLE_SIMPLE_APP_H_#include "include/cef_app.h"// Implement application-level callbacks for the browser process.
// 为浏览器进程实现应用级回调
class SimpleApp : public CefApp, public CefBrowserProcessHandler {public:SimpleApp();// CefApp methods:virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler()OVERRIDE {return this;}// CefBrowserProcessHandler methods:virtual void OnContextInitialized() OVERRIDE;private:// Include the default reference counting implementation.IMPLEMENT_REFCOUNTING(SimpleApp);
};#endif  // CEF_TESTS_CEFSIMPLE_SIMPLE_APP_H_

  simple_app.cc文件

#include "tests/cefsimple/simple_app.h"
#include <string>#include "include/cef_browser.h"
#include "include/cef_command_line.h"
#include "include/views/cef_browser_view.h"
#include "include/views/cef_window.h"
#include "include/wrapper/cef_helpers.h"
#include "tests/cefsimple/simple_handler.h"namespace
{// When using the Views framework this object provides the delegate// implementation for the CefWindow that hosts the Views-based browser.//使用 Views 框架时,此对象为承载基于 Views 的浏览器的 CefWindow 提供委托实现。class SimpleWindowDelegate : public CefWindowDelegate{public:explicit SimpleWindowDelegate(CefRefPtr<CefBrowserView> browser_view): browser_view_(browser_view) {}void OnWindowCreated(CefRefPtr<CefWindow> window) OVERRIDE{// Add the browser view and show the window.window->AddChildView(browser_view_);window->Show();// Give keyboard focus to the browser view.browser_view_->RequestFocus();}void OnWindowDestroyed(CefRefPtr<CefWindow> window) OVERRIDE{browser_view_ = NULL;}bool CanClose(CefRefPtr<CefWindow> window) OVERRIDE{// Allow the window to close if the browser says it's OK.//关闭窗口CefRefPtr<CefBrowser> browser = browser_view_->GetBrowser();if (browser)return browser->GetHost()->TryCloseBrowser();return true;}CefSize GetPreferredSize(CefRefPtr<CefView> view) OVERRIDE{return CefSize(800, 600);//窗口大小}private:CefRefPtr<CefBrowserView> browser_view_;IMPLEMENT_REFCOUNTING(SimpleWindowDelegate);DISALLOW_COPY_AND_ASSIGN(SimpleWindowDelegate);};}  // namespaceSimpleApp::SimpleApp() {}/*浏览器应用程序初始化*/
void SimpleApp::OnContextInitialized()
{CEF_REQUIRE_UI_THREAD();CefRefPtr<CefCommandLine> command_line =CefCommandLine::GetGlobalCommandLine();#if defined(OS_WIN) || defined(OS_LINUX)// Create the browser using the Views framework if "--use-views" is specified// via the command-line. Otherwise, create the browser using the native// platform framework. The Views framework is currently only supported on// Windows and Linux.const bool use_views = command_line->HasSwitch("use-views");
#elseconst bool use_views = false;
#endif// SimpleHandler implements browser-level callbacks.CefRefPtr<SimpleHandler> handler(new SimpleHandler(use_views));// Specify CEF browser settings here.CefBrowserSettings browser_settings;std::string url;// Check if a "--url=" value was provided via the command-line. If so, use// that instead of the default URL.//获取命令参数中网址,否则采用默认参数url = command_line->GetSwitchValue("url");if (url.empty())url = "http://www.baidu.com";if (use_views)  //Mac{// Create the BrowserView.CefRefPtr<CefBrowserView> browser_view = CefBrowserView::CreateBrowserView(handler, url, browser_settings, NULL, NULL, NULL);// Create the Window. It will show itself after creation.//创建窗口CefWindow::CreateTopLevelWindow(new SimpleWindowDelegate(browser_view));}else    //linux和windows{// Information used when creating the native window.CefWindowInfo window_info;#if defined(OS_WIN)// On Windows we need to specify certain flags that will be passed to// CreateWindowEx().window_info.SetAsPopup(NULL, "test simple cef");//窗口标题
#endif// Create the first browser window.CefBrowserHost::CreateBrowser(window_info, handler, url, browser_settings,NULL, NULL);}
}

3.应用程序句柄回调

  CefClient,CefDisplayHandler,CefLifeSpanHandler,CefLoadHandler,这些handler的都是基于功能的回调,应用开发者应该提供对应的handler实现,然后提供应用程序获取对应handler实体。
  simple_handler.h文件


#ifndef CEF_TESTS_CEFSIMPLE_SIMPLE_HANDLER_H_
#define CEF_TESTS_CEFSIMPLE_SIMPLE_HANDLER_H_#include "include/cef_client.h"
#include <list>class SimpleHandler : public CefClient,public CefDisplayHandler,//显示状态相关接口public CefLifeSpanHandler,public CefLoadHandler {public:explicit SimpleHandler(bool use_views);~SimpleHandler();// Provide access to the single global instance of this object.static SimpleHandler* GetInstance();// CefClient methods:virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE {return this;}virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE {return this;}virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE { return this; }// CefDisplayHandler methods:virtual void OnTitleChange(CefRefPtr<CefBrowser> browser,const CefString& title) OVERRIDE;// CefLifeSpanHandler methods:virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;// CefLoadHandler methods:virtual void OnLoadError(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,ErrorCode errorCode,const CefString& errorText,const CefString& failedUrl) OVERRIDE;// Request that all existing browser windows close.void CloseAllBrowsers(bool force_close);bool IsClosing() const { return is_closing_; }private:// Platform-specific implementation.void PlatformTitleChange(CefRefPtr<CefBrowser> browser,const CefString& title);// True if the application is using the Views framework.const bool use_views_;// List of existing browser windows. Only accessed on the CEF UI thread.typedef std::list<CefRefPtr<CefBrowser>> BrowserList;BrowserList browser_list_;bool is_closing_;// Include the default reference counting implementation.IMPLEMENT_REFCOUNTING(SimpleHandler);
};#endif  // CEF_TESTS_CEFSIMPLE_SIMPLE_HANDLER_H_

  simple_handler.cc文件

#include "tests/cefsimple/simple_handler.h"
#include <sstream>
#include <string>#include "include/base/cef_bind.h"
#include "include/cef_app.h"
#include "include/cef_parser.h"
#include "include/views/cef_browser_view.h"
#include "include/views/cef_window.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_helpers.h"namespace
{SimpleHandler *g_instance = NULL;// Returns a data: URI with the specified contents.std::string GetDataURI(const std::string &data, const std::string &mime_type){return "data:" + mime_type + ";base64," +CefURIEncode(CefBase64Encode(data.data(), data.size()), false).ToString();}}  // namespaceSimpleHandler::SimpleHandler(bool use_views): use_views_(use_views), is_closing_(false)
{DCHECK(!g_instance);g_instance = this;
}SimpleHandler::~SimpleHandler()
{g_instance = NULL;
}// static
SimpleHandler *SimpleHandler::GetInstance()
{return g_instance;
}void SimpleHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,const CefString &title)
{CEF_REQUIRE_UI_THREAD();if (use_views_){// Set the title of the window using the Views framework.CefRefPtr<CefBrowserView> browser_view =CefBrowserView::GetForBrowser(browser);if (browser_view){CefRefPtr<CefWindow> window = browser_view->GetWindow();if (window)window->SetTitle(title);}}else{// Set the title of the window using platform APIs.PlatformTitleChange(browser, title);}
}void SimpleHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser)
{CEF_REQUIRE_UI_THREAD();// Add to the list of existing browsers.browser_list_.push_back(browser);
}bool SimpleHandler::DoClose(CefRefPtr<CefBrowser> browser)
{CEF_REQUIRE_UI_THREAD();// Closing the main window requires special handling. See the DoClose()// documentation in the CEF header for a detailed destription of this// process.if (browser_list_.size() == 1){// Set a flag to indicate that the window close should be allowed.is_closing_ = true;}// Allow the close. For windowed browsers this will result in the OS close// event being sent.return false;
}void SimpleHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser)
{CEF_REQUIRE_UI_THREAD();// Remove from the list of existing browsers.BrowserList::iterator bit = browser_list_.begin();for (; bit != browser_list_.end(); ++bit){if ((*bit)->IsSame(browser)){browser_list_.erase(bit);break;}}if (browser_list_.empty()){// All browser windows have closed. Quit the application message loop.CefQuitMessageLoop();}
}void SimpleHandler::OnLoadError(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,ErrorCode errorCode,const CefString &errorText,const CefString &failedUrl)
{CEF_REQUIRE_UI_THREAD();// Don't display an error for downloaded files.if (errorCode == ERR_ABORTED)return;// Display a load error message using a data: URI.std::stringstream ss;ss << "<html><body bgcolor=\"white\">""<h2>Failed to load URL "<< std::string(failedUrl) << " with error " << std::string(errorText)<< " (" << errorCode << ").</h2></body></html>";frame->LoadURL(GetDataURI(ss.str(), "text/html"));
}void SimpleHandler::CloseAllBrowsers(bool force_close)
{if (!CefCurrentlyOn(TID_UI)){// Execute on the UI thread.CefPostTask(TID_UI, base::Bind(&SimpleHandler::CloseAllBrowsers, this,force_close));return;}if (browser_list_.empty())return;BrowserList::const_iterator it = browser_list_.begin();for (; it != browser_list_.end(); ++it)(*it)->GetHost()->CloseBrowser(force_close);
}//windows包含
#include <windows.h>
#include <string>#include "include/cef_browser.h"void SimpleHandler::PlatformTitleChange(CefRefPtr<CefBrowser> browser,const CefString& title) {CefWindowHandle hwnd = browser->GetHost()->GetWindowHandle();SetWindowText(hwnd, std::wstring(title).c_str());
}

4.作者答疑


  如有疑问,请留言。

libcef-cefsimple简单解析-涉及对象及关键类分析-CefApp-CefClient-CefDisplayHandler(七)相关推荐

  1. io 错误: socket closed_Tomcat NIO(9)IO线程Overall流程和关键类

    在上一篇文章里我们主要介绍了 tomcat NIO 中 poller 线程的阻塞与唤醒,根据以前文章当 poller 线程监测到连接有数据可读事件的时候,会把原始 socket 的包装对象委托到 to ...

  2. Tomcat NIO(9)-IO线程-Overall流程和关键类

    在上一篇文章里我们主要介绍了 tomcat NIO 中 poller 线程的阻塞与唤醒,根据以前文章当 poller 线程监测到连接有数据可读事件的时候,会把原始 socket 的包装对象委托到 to ...

  3. el-admin框架简单解析

    el-admin框架简单解析 el-admin 简单了解 使用框架的四大步 前端文件架构 el-admin前端部分解析 前端Vue目录结构 Layout 布局 mixins 混入模式 router 路 ...

  4. 14 | 深入解析Pod对象(一):基本概念

    今天我和你分享的主题是:深入解析 Pod 对象之基本概念. 在上一篇文章中,我详细介绍了 Pod 这个 Kubernetes 项目中最重要的概念.而在今天这篇文章中,我会和你分享 Pod 对象的更多细 ...

  5. 插件化框架DL源码的简单解析

    目前行业内已经有较多的插件化实现方案.本文主要对DL(DynamicLoadApk)这一个开源的侵入式插件化方案进行简单分析.因为Service组件插件化的实现逻辑和Activity大体相似,所以在这 ...

  6. java读取codetable_解析Java对象的equals()和hashCode()的使用

    解析Java对象的equals()和hashCode()的使用 前言 在Java语言中,equals()和hashCode()两个函数的使用是紧密配合的,你要是自己设计其中一个,就要设计另外一个.在多 ...

  7. java代理通俗简单解析

    1         代理 1.1            代理的概念和作用 代理的概念很好理解,就像黄牛代替票务公司给你提供票,经纪人代理艺人和别人谈合作.Java的代理是指实现类作为代理类的属性对象, ...

  8. [ 转载 ] Java基础10--关于Object类下所有方法的简单解析

    关于Object类下所有方法的简单解析 类Object是类层次结构的根类,是每一个类的父类,所有的对象包括数组,String,Integer等包装类,所以了解Object是很有必要的,话不多说,我们直 ...

  9. 14. 深入解析Pod对象(一)

    14. 深入解析Pod对象(一) """ 通过前面的讲解,大家应该都知道: Pod,而不是容器,它是 Kubernetes 项目中的最小编排单位.将这个设计落实到 API ...

最新文章

  1. mysql中行转列,MySQL 中行转列的方法
  2. 北京大学万小军教授:让机器进行文学创作,有什么进展和挑战?
  3. DPM2007轻松恢复Exchange邮件,DPM2007系列之三
  4. 多线程-Task、await/async
  5. Ubuntu 解决 pip 安装 lxml 出现 x86_64-linux-gnu-gcc 异常
  6. 关于MUI框架中,“侧滑导航“之“div模式下拉菜单“的a标签(超链接)的失效问题?
  7. 【论文阅读】Rich feature hierarchies for accurate object detection and semantic segmentation
  8. 万字长文,解密秒杀架构!(建议收藏)
  9. 数据获取以及处理Beta版本展示
  10. 蓝牙学习笔记之LMP协议(十二)
  11. 鸟哥惠新宸:PHP 7.1 的新特性我并不是很喜欢
  12. 法外狂徒——格雷福斯
  13. 英特尔对手机的几个痛苦领悟
  14. css 文字第二行省略号,第二行的css省略号
  15. 【VSCode】提升效率
  16. AMBA总线-结合axi-vip对axi4协议的理解1
  17. R count函数_第477期|R语言绘图之图形组合
  18. Gym - 101653T Runes [模拟]
  19. 昭阳K2450笔记本安装Linux,可能是最难拆的笔记本:lenovo 联想 昭阳K2450 升级固态硬盘的艰难历程...
  20. OPC配置DCOM解决方案

热门文章

  1. Maltab GUI课程设计——贪吃蛇小游戏
  2. turtle库使用——画布大小调整,用不同颜色填充多边形
  3. idea必要快捷键设置
  4. 稀有南美蟑螂甲壳滋生微生物可自行发光
  5. (超详细)python环境安装
  6. oracle进行rman增量恢复时报错RMAN-06094
  7. mysql 续行符_Python 字符串
  8. 12V锂电池保护电路
  9. python mkl包_免序列号安装MKL包
  10. PMP是终身有效吗?