基本过程为
先说说第一种,也就是JS发起的。
基本逻辑是 JS 是由 render 进程来进行渲染的,所以必须由 render 进程注册一个或多个方法,暴露给 JS 代码,比如说 window.cefQuery(这是默认的调用方式),调用这个方法就可以在 JS 代码段发送一个小希到浏览器的内部消息循环中。render 端接受到消息后,可以把消息再次发送给 browser 端。然后再在 browser 端进行消息处理。我程序结构中,因为是采用分离进程的方式,而且需要和上面的 win32 程序进行沟通,所以把消息处理全部放在了 Browser 端。但是在 render 端也是可以处理消息的。
理论上应该就是在 render 端封装了一个 CefProcessMessage 对象发到了 Browser 端。也就是图中的左边的上面那根线。
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"; // 默认就是这个
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