CEF消息传递实战(实测可用,新鲜出炉)

2023-12-21 20:04:04


CEF框架中,主要的消息传递方向,从消息产生的源头,我觉得可以分成两种:

  • 由JS发起,也就是界面有一些按钮之类,通过输入,点击等方式需要传入到C++代码中,也就是浏览器中。
  • 由C++代码产生的数据(也就是浏览器内部)需要展示在界面上,也就是需要JS代码来展示这些数据。这些数据又可以分成两个源头:
    • 在Browser进程中产生,也就是浏览器主进程中产生,需要通过进程间通信,将数据通过消息发送到Render端,再由Render端的V8Script引擎通过JS来渲染。我这里主要讲这一种
    • 在Render中产生,这个就想对比较简单,直接在Render端的V8Script引擎通过JS来渲染就行。

基本过程为

先说说第一种,也就是JS发起的。

JS 调用 C++本地方法:消息

  1. 基本逻辑是 JS 是由 render 进程来进行渲染的,所以必须由 render 进程注册一个或多个方法,暴露给 JS 代码,比如说 window.cefQuery(这是默认的调用方式),调用这个方法就可以在 JS 代码段发送一个小希到浏览器的内部消息循环中。render 端接受到消息后,可以把消息再次发送给 browser 端。然后再在 browser 端进行消息处理。我程序结构中,因为是采用分离进程的方式,而且需要和上面的 win32 程序进行沟通,所以把消息处理全部放在了 Browser 端。但是在 render 端也是可以处理消息的。

  2. 理论上应该就是在 render 端封装了一个 CefProcessMessage 对象发到了 Browser 端。也就是图中的左边的上面那根线。

  3. render 端

  • 创建一个CefRefPtr<CefMessageRouterRendererSide>,用于向 JS,或者是 window 这个对象注册一个窗口方法。
    CefRefPtr<CefMessageRouterRendererSide> message_router_; // 成员变量
    
    void OnWebKitInitialized(CefRefPtr<ClientAppRenderer> app) OVERRIDE {
      if (CefCrashReportingEnabled()) {
        // Set some crash keys for testing purposes. Keys must be defined in the
        // "crash_reporter.cfg" file. See cef_crash_util.h for details.
        CefSetCrashKeyValue("testkey_small1", "value1_small_renderer");
        CefSetCrashKeyValue("testkey_small2", "value2_small_renderer");
        CefSetCrashKeyValue("testkey_medium1", "value1_medium_renderer");
        CefSetCrashKeyValue("testkey_medium2", "value2_medium_renderer");
        CefSetCrashKeyValue("testkey_large1", "value1_large_renderer");
        CefSetCrashKeyValue("testkey_large2", "value2_large_renderer");
        }

        // Create the renderer-side router for query handling.
        CefMessageRouterConfig config;
        message_router_ = CefMessageRouterRendererSide::Create(config);
    }

message_router_相当于就转发给了Browser。这段代码相当于就是上图中左边下面那根线的发送端。
CefMessageRouterConfig config中有两个关键的东西,也就是说往V8Script引擎中的window对象中注入了两个方法,一个是cefQuery,还有一个是cefQueryCancel。这个可以通过js_query_function和js_cancel_function来制定:

config.js_query_function = "cefQuery"; // 默认就是这个
  1. browser 端,也就是在 SimpleHandler 类中,这个类的定义和继承关系为:
  class SimpleHandler : public CefClient,
                      public CefDisplayHandler,
                      public CefLifeSpanHandler,
                      public CefLoadHandler,
                      public CefRequestHandler
  • 创建一个CefRefPtr<CefMessageRouterBrowserSide>,用于接收消息的组件。
    void SimpleHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
      CEF_REQUIRE_UI_THREAD();

      cout << "dllmain" << endl;
      CefMessageRouterConfig con

文章来源:https://blog.csdn.net/pcgamer/article/details/135134659
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。