版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
随便先提提,cefclient默认编译就是标准的浏览器。
如果不希望看到按钮和url输入框的话,那就将“window_config.with_controls = false;”就可以去掉,不过弹窗的时候还是会有,要在另外的地方修改,类似的地方自行去找。
如果要实现离屏(OSR),不用改太多,只需要改一下:
CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine();
command_line->InitFromString(::GetCommandLineW());
command_line->AppendSwitch(switches::kOffScreenRenderingEnabled);
command_line->AppendSwitchWithValue(switches::kOffScreenFrameRate, "30");
command_line->AppendSwitch(switches::kTransparentPaintingEnabled);
JavaScript和C++交互:
C++调用JavaScript比较简单:
CefRefPtr<CefBrowser> browser = rootWin->GetBrowser();
CefRefPtr<CefFrame> frame = rootWin->GetBrowser()->GetMainFrame();
frame->ExecuteJavaScript(“alert('haha')”, frame->GetURL(), 0);
如果要回调的话,要用window.cefQuery();
frame->ExecuteJavaScript("window.cefQuery({request: 'mssage aaa',onSuccess: function(response) {target.innerText = response;},onFailure: function(error_code, error_message) {}});;", frame->GetURL(), 0);
这个还没完。还要将下面这个class添加到MessageHandler里面。
namespace client {
class MsgHandler : public CefMessageRouterBrowserSide::Handler {
public:
typedef cef_termination_status_t TerminationStatus;
MsgHandler() { CEF_REQUIRE_UI_THREAD(); }
// Called due to cefQuery execution.
virtual bool OnQuery(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int64 query_id,
const CefString& request,
bool persistent,
CefRefPtr<Callback> callback) OVERRIDE
{
const std::string& request_str = request;
if (request_str.size() == 0)
{
return false;
}
//...
callback->Success(CefString());
return true;
}
};
}
有很多人不知道要在哪里添加MessageHandler,打开client_handler.cc,搜索“ClientHandler::OnAfterCreated”。
void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
browser_count_++;
if (!message_router_) {
// Create the browser-side router for query handling.
CefMessageRouterConfig config;
message_router_ = CefMessageRouterBrowserSide::Create(config);
// Register handlers with the router.
test_runner::CreateMessageHandlers(message_handler_set_);
MsgHandler *msgHandler = new MsgHandler();
message_handler_set_.insert(msgHandler);
MessageHandlerSet::const_iterator it = message_handler_set_.begin();
for (; it != message_handler_set_.end(); ++it)
{
message_router_->AddHandler(*(it), false);
}
}
// Disable mouse cursor change if requested via the command-line flag.
if (mouse_cursor_change_disabled_)
browser->GetHost()->SetMouseCursorChangeDisabled(true);
if (browser->GetHost()->GetExtension()) {
// Browsers hosting extension apps should auto-resize.
browser->GetHost()->SetAutoResizeEnabled(true, CefSize(20, 20),
CefSize(1000, 1000));
CefRefPtr<CefExtension> extension = browser->GetHost()->GetExtension();
if (extension_util::IsInternalExtension(extension->GetPath())) {
// Register the internal handler for extension resources.
extension_util::AddInternalExtensionToResourceManager(extension,
resource_manager_);
}
}
NotifyBrowserCreated(browser);
}
这些可能在其他地方也可以搜到类似的做法,但是,如果subProcess.exe没有处理好的话,也不可能收到消息的。在前面我已经发出来了,CefExecuteProcess必须要有app这个参数。重新贴一下代码:
int SubProcess(HINSTANCE hInstance, int nCmdShow)
{
CefMainArgs main_args(hInstance);
// Parse command-line arguments.
CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine();
command_line->InitFromString(::GetCommandLineW());
CefRefPtr<CefApp> app;
ClientApp::ProcessType process_type = ClientApp::GetProcessType(command_line);
//ClientApp::ProcessType process_type = ClientApp::BrowserProcess;
//ClientApp::ProcessType process_type = ClientApp::RendererProcess;
if (process_type == ClientApp::BrowserProcess)
app = new ClientAppBrowser();
else if (process_type == ClientApp::RendererProcess)
app = new ClientAppRenderer();
else if (process_type == ClientApp::OtherProcess)
app = new ClientAppOther();
return CefExecuteProcess(main_args, app, NULL);
}
我在这个坑踏进了很久没出来,苦涩啊。。。