一步步CEF(3)之JavaScript与C++互动

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/ftpleopard/article/details/84937437

随便先提提,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);
	}

我在这个坑踏进了很久没出来,苦涩啊。。。

猜你喜欢

转载自blog.csdn.net/ftpleopard/article/details/84937437