CEF | CEF 浏览器客户端功能详解
背景
VS2017+Qt5.14.2+cef89 实现基于 CEF 框架的客户端。上一篇文章已经介绍过如何搭建 Qt+CEF 开发环境,并且成功移植运行了 cefsimple 项目。如果不满足于 cefsimple 现有的功能,想开发更多的功能,比如实现浏览器的前进、后退、刷新、跳转页面时不创建新的窗口、设置 cookie、调用控制台等功能。就需要深挖一下 cef 的控制类有哪些,支持的功能接口有哪些……
cefsimple 示例详解
文件目录
这里的文件目录是直接生成的 cef.sln 打开后的文件目录。移植到 Qt 项目中时,主要用到了 simple_app.cc、simple_app.h、simple_handler.cc、simple_handler.h、simple_handler_win.cc 文件和 cefsimple_win.cc 文件中的 wWinMain 函数中的内容。
具体实现
1.main 函数
main 函数主要用来在程序启动时对 CEF 进行初始化设置和启动,并在程序结束时关闭 CEF。
CefEnableHighDPISupport(): 在进程启动时设置 High-DPI 为启用状态。DPI 全称是 dots per inch (DPI), 也就是每英寸的点数,在显示器上就是每英寸的像素个数。这个接口函数在使用时一般不为人所注意,但是如果稍有不慎,会造成打开的网页不能填满窗口的问题。
GetModuleHandle(nullptr): GetModuleHandle 是一个计算机函数,功能是获取一个应用程序或动态链接库的模块句柄。只有在当前进程的场景中,这个句柄才会有效。其实就是获取示例的句柄。
CefMainArgs: 表示 CefExecuteProcess 参数的类。
CefRefPtr<CefApp> app(new SimpleApp): CEF 创建对象形式如 CefRefPtr<SimpleApp> app(new SimpleApp);或者 CefRefPtr<SimpleApp> app = new SimpleApp();创建的指针引用计数由 CefRefPtr 管理,CefRefPtr 通过调用 AddRef()和 Release()方法自动管理引用计数。
CefExecuteProcess(): 这个函数应该在应用程序入口点进行调用来执行二级进程。它可以从一个可执行的浏览器客户端或从一个单独的执行的指定的 CefSettings 来开启二级进程。即 CefExecuteProcess 生成一个功 CEF 浏览器运行的线程。保证 browser 的独立运行。注意这里创建失败的话,就直接退出程序。
CefSettings: 是一个包含浏览器相关设置的结构体。
no_sandbox: 沙盒是在受限的安全环境中运行应用程序的一种做法,这种做法是要限制授予应用程序的代码访问权限。沙盒中的所有改动对操作系统不会造成任何损失。设置为 ture 以禁止子进程的沙盒。
multi_threaded_message_loop: 设置多线程消息循环。设置为 false 时,可以调用 CefRunMessageLoop 或者 CefDoMessageLoopWork 函数来触发 Cef 消息循环,这时浏览器进程的 UI 线程就是调用 CefRunMessageLoop 或者 CefDoMessageLoopWork 函数的线程。当为 true 时,CEF 将在单独的线程上运行 Browser 的界面,而不是在主线程上。一般默认为 false,通过使用定时器进行事件触发 CefDoMessageLoopWork 来进行事件处理。(仅在 windows 上支持此选项)
CefInitialize(): 初始化 CEF。
CefRunMessageLoop(): 因为上面我们将 multi_threaded_message_loop 设置为 false,所以需要调用 CefRunMessageLoop()函数来出发 CEF 的消息循环。结束消息循环调用 CefQuitMessageLoop()。
CefShutdown(): 关闭 CEF。
至此,CEF 完成了 SimpleApp 的创建以及 CEF 的初始化、启动、开启消息循环、关闭等工作。我自在使用过程中加了一些东西,大家在开发过程中可以作为参考,不懂的地方建议直接点进去看 cef 的注释,讲的很清楚。
2.SimpleHandler 类
SimpleHandler 类继承了 CefClient、CefDisplayHandler、CefLifeSpanHandler、CefLoadHandler 这几个类。并重载了这些类中的部分方法。这些 handler 的都是基于功能的回调类,应用开发者应该提供对应的实现,然后提供应用程序获取对应的 handler 实体。
CefClient: 提供了一些获取 Handler 的方法。
CefDisplayHandler: 回调类,用来处理与页面状态相关的事件,如页面加载情况的变化,地址栏变化,标题变化等。
CefLifeSpanHandler: 回调类,主要用来处理与浏览器生命周期相关的事件,和浏览器对象的创建、销毁以及弹出框的管理。
CefLoadHandler: 回调类,主要用来处理浏览器页面加载状态的变化,如页面加载开始,完成,出错等。
另:如果我们需要浏览器响应按键消息,还可以继承 CefKeyboardHandler 类。
CefKeyboardHandler: 回调类,主要用来处理键盘输入事件。
3.SimpleApp 类
SimpleApp 类继承了 CefApp、CefBrowserProcessHandler 这两个类。并重载了这两类中的部分方法。\
CefApp 是一个接口类,主要用于提供获取三种 handler 的接口。GetResourceBundleHandler、 GetBrowserProcessHandler、GetRenderProcessHandler 这三个方法分别可以得到对应的回调 handler。同时如果继承了这三种 handler 就可以在这些时机处理自己的回调业务。就像后面继承的 CefBrowserProcessHandler,可以实现 browser 进程的回调,用于执行 browser 进程生命周期中的重要回调。
CefBrowserProcessHandler 实现对浏览器进程的回调。在 OnContextInitialized 回调函数中进行应用程序参数初始化和窗口创建。
cefsimple 中的 OnContextInitialized()回调函数内容较复杂,很多我们都用不到。简化后的函数可以是:
创建 SimpleHandler。
CefBrowserSettings: 是一个结构体,里面保存了对浏览器的一些设置,包括设置标准字体、语言、默认编码等信息。
url: 是将要访问的网页的网址。
CefWindowInfo: 是表示窗口信息的类。可以设置浏览器窗口以何种方式显示出来以及窗口的大小。有三种显示方式:SetAsChild、SetAsPopup 和 SetAsWindowless。
SetAsPopup: 创建一个弹出窗口的浏览器。
SetAsChild: 将浏览器创建为子窗口。后续我们实现将浏览器嵌入 QWidget 就是用这个方式来实现。
SetAsWindowless: 创建没有窗口的浏览器。所有实现将通过 CefRenderHandler 接口来操作。一般浏览器都是用作可视化显示的,这个方式一般不使用。
版权声明: 本文为 InfoQ 作者【YOLO.】的原创文章。
原文链接:【http://xie.infoq.cn/article/4609b1f7c2252ec0985028c91】。未经作者许可,禁止转载。
评论