Cef的JavaScript和MFC通信

在我另一篇文章里面介绍了如何在JavaScript中调用MFC的代码和MFC中调用JavaScript的代码,但是文中提到一个问题:
在vs代码CSimpleV8Handler::Execute中打断点始终停不下来,一直以为是电脑问题,纠结了很久,最后发现是因为我加载cef的时候用的是多进程模式,代码设置如下:

	void* sandbox_info = NULL;
	CefMainArgs main_args(AfxGetApp()->m_hInstance);
	CefRefPtr<SimpleApp> app(new SimpleApp);
	CefSettings settings;
	settings.no_sandbox = true;
	//settings.single_process = true;
	settings.multi_threaded_message_loop = true;
	CefInitialize(main_args, settings, app.get(), sandbox_info);

如果放开那句注释,断点是可以停下来的,到此才发现问题所在,因为v8的消息在另一个进程中(Render进程),根本不在当前cef浏览器进程中,所以断点是不会起作用的,如果只是使用单进程模式,就没啥问题。
如果一定要用多进程模式,这里打不了断点,而且这里也访问不了当前窗口的任何句柄(我就是因为需要调用窗口中其他控件,获取到的空间指针和主窗口指针都是空),查了一下,要在代码中真正的访问mfc窗口的句柄,需要将Render进程中的消息传递到Browser进程中,在Browser进程中去访问才可以,下面介绍如何将消息回传到Browser进程中:
发送消息使用CefBrowser::SendProcessMessage(),SendProcessMessage第一个参数是CefProcessId,给Browser进程发送,就用PID_BROWSER,给Render进程发送,就用PID_RENDERER。所以在v8代码中,写成下面这样:

if (arguments.size() ==1 ){			
	CefString str = arguments[0]->GetStringValue();
	CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("JSCallCppMsg");
	CefRefPtr<CefListValue> args = msg->GetArgumentList();
	args->SetSize(1);
	args->SetString(0, str);
	CefV8Context::GetCurrentContext()->GetBrowser()->SendProcessMessage(PID_BROWSER, msg);
	return true;
}

其中字符串JSCallCppMsg是随便定义的,是用来在Browser进程中用来区分消息用的。在Browser进程中需要重写一个方法:OnProcessMessageReceived,整个方法的定义是在CefClient类中,cef_client.h中定义如下:

virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,CefProcessId source_process,CefRefPtr<CefProcessMessage> message) {
	return false;
}

在SimpleHandler中重写这个方法,代码如下:

bool SimpleHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message) {
	const std::string& messageName = message->GetName();
	if (messageName == "JSCallCppMsg"){
		CefRefPtr<CefListValue> args = message->GetArgumentList();
		CefString str = args->GetString(0);
		::SendMessage(AfxGetApp()->m_pMainWnd->GetSafeHwnd(), WM_TESTSENDMSG, 0, (LPARAM)str.c_str());
		return true;
	}
	return false;
}

其中SendMessage是用来向MFC主窗口发送消息的,因为那些控件需要在主窗口中才能拿到,所以将消息传递到主窗口中,至于为什么不用PostMessage,原因是PostMessage发送消息后不等待消息处理,这里的字符串是临时变量,本段代码执行完成后就销毁了,MFC消息循环中拿到的字符串就是乱码。

本文中用到的代码可以在https://download.csdn.net/download/youyicc/12113708地址上下载,这是一个基于VS2013的mfc上显示cef浏览器和ie插件浏览器,实现cef的JavaScript和ie的JavaScript相互调用的示例代码。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值