一、Off-Screen Rendering 脱屏绘制
CEF的脱屏渲染并不创建源生的浏览器窗口,而是CEF提供主应用程序在无效区域和像素buffer里渲染,然后主应用程序通过鼠标、键盘和焦点事件通知CEF。
脱屏渲染现在不支持图层混合加速图层混合加速。脱屏渲染要窗口浏览器一样接受相同的通知,包括生命周期通知等,为了使用脱屏渲染:
- 实现CefRenderHandler接口,所有方法是必需的,除非另有指示。
- 调用CefWindowInfo::SetAsOffScreen()函数和将CefWindowInfo结构传递给CefBrowserHost::CreateBrowser()之前调用CefWindowInfo::SetTransparentPainting()方法。哪里没有父窗口传递给SetAsOffScreen,那么像Centext菜单功能就不可使用。
- CefRenderHandler::GetViewRect()函数获取想要获取视图的矩阵。
- CefRenderHandler::OnPaint()被调用,以提供一个无效区域和更新的像素buffer。CefClient应用程序使用OpenGL绘制缓冲。
- 调用CefBrowserHost::WasResized()重置浏览器大小。这将导致调用GetViewRect()来检索新尺寸随后调用OnPaint()。
- CefBrowserHost::SendXXX()函数通知浏览进程的鼠标、键盘和焦点事件
- CefBrowserHost::CloseBrowser()销毁浏览器
二、投递任务
在单进程的不同线程之间可以通过 CefPostTask系列函数投递任务。在目标线程中,收到的任务会以异步方式在消息循环中执行。例如:
在UI线程中执行某个类方法:CefPostTask(TID_UI, NewCefRunnableMethod(object, &MyObject::MyMethod, param1, param2));
在UI线程中执行某个方法:CefPostTask(TID_IO, NewCefRunnableFunction(MyFunction, param1, param2));
如果主机应用程序需要获取运行循环的引用,可以使用CefTaskRunner类。
例如:获取线程的任务运行者:CefRefPtr<CefTaskRunner> task_runner = CefTaskRunner::GetForThread(TID_UI);
三、进程间通信
由于CEF3以多进程方式运行,需要在不同进程之间提供通信方式。CefBrowsert和CefFrame对象分别浏览进程和渲染进程,每个CefBrowser和CefFrame对象还有一个与之关联的惟一的ID值,将匹配两边边界过程
- 进程启动消息 为所有渲染进程提供相同的信息在启动浏览器的过程中实现CefBrowserProcessHandler::OnRenderProcessThreadCreated(),在渲染进程中传递启动消息用CefRenderProcessHandler::OnRenderThreadCreated()
- 进程运行消息 在进程生命周期的任何时刻使用进程消息通过CefProcessMessage类传递消息。这些消息与一个特定的浏览器实例相关联并通过CefBrowser::SendProcessMessage()函数发送。进程消息可通过CefProcessMessage::GetArgumentList()函数传递状态信息。
如:
CefRefPtr<CefProcessMessage> msg= CefProcessMessage::Create(“my_message”); // Retrieve the argument list object. CefRefPtr<CefListValue> args = msg>GetArgumentList(); // Populate the argument values. args->SetString(0, “my string”); args->SetInt(0, 10); // Send the process message to the render process. // Use PID_BROWSER instead when sending a message to the browser process. browser->SendProcessMessage(PID_RENDERER, msg);
从浏览进程发送的消息会到达渲染进程的 CefRenderProcessHandler::OnProcessMessageReceived()函数 从渲染进程发送的消息会到达浏览进程的CefClient::OnProcessMessageReceived()函数,如:
bool MyHandler::OnProcessMessageReceived( CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message) { // Check the message name. const std::string& message_name = message->GetName(); if (message_name == “my_message”) { // Handle the message here... return true; } return false; }
在发送的地方使用CefFrame::GetIdentifier()函数获取窗口的唯一ID,在接受进程中获取唯一ID的窗口对象使用CefBrowser::GetFrame()函数。如:
// Helper macros for splitting and combining the int64 frame ID value. #define