写点什么

CEF | CEF 浏览器客户端功能详解

作者:YOLO.
  • 2022-10-18
    河北
  • 本文字数:2831 字

    阅读完需:约 1 分钟

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 的注释,讲的很清楚。


int main(int argc, char *argv[]){    // Create CEF    CefEnableHighDPISupport();    HINSTANCE hInstance = GetModuleHandle(nullptr);    CefMainArgs main_args(hInstance);    CefRefPtr<ClientApp> app(new ClientApp);    int exit_code = CefExecuteProcess(main_args, app.get(), nullptr);    if (exit_code >= 0) {        return exit_code;    }
// 主程序 QApplication a(argc, argv);
// Init CEF CefSettings settings; settings.no_sandbox = true; settings.multi_threaded_message_loop = true; settings.persist_session_cookies = true; CefString(&settings.cache_path).FromString(storagePath.toStdString()); CefString(&settings.root_cache_path).FromString(storagePath.toStdString()); CefString(&settings.locale).FromString("zh-CN"); // 浏览器语言设置为中文 CefString(&settings.accept_language_list).FromString("zh-CN"); // 浏览器语言设置为中文 CefInitialize(main_args, settings, app.get(), nullptr); // 运行主程序 int ret = a.exec(); // Shut down CEF. CefShutdown(); return ret;}
复制代码
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 接口来操作。一般浏览器都是用作可视化显示的,这个方式一般不使用。

发布于: 刚刚阅读数: 3
用户头像

YOLO.

关注

还未添加个人签名 2022-05-06 加入

还未添加个人简介

评论

发布
暂无评论
CEF | CEF浏览器客户端功能详解_qt_YOLO._InfoQ写作社区