MFC和Javascript交互-Cef

本文中使用的是Cef加载网页,实现网页中javascript和mfc代码之间相互调用,即是mfc调用javascript,javascript调用mfc代码。

一、javascript调用mfc代码
①搭建mfc加载cef的框架,并加载网页,这部分内容在网上有很多博文,不过会遇到一些崩溃,或者无法正常退出,或者多进程和单进程问题,或者加载网页慢等问题,在我其他博文中有一部分解决方案介绍,这里跳过这部分。
②首先是在SimpleApp类中重写虚函数OnContextCreated,这部分相当于是订阅javascript调用信息,回调信息在CefV8Handler中实现,头文件定义如下:

virtual void OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context) OVERRIDE;

在具体实现中代码如下:

// The var type can accept all object or variable
CefRefPtr<CefV8Value> pV8 = context->GetGlobal();
// bind function 
CefRefPtr<CSimpleV8Handler> pJsHandler(new CSimpleV8Handler());
CefRefPtr<CefV8Value> pFunc = CefV8Value::CreateFunction(CefString("JSCallCppCB"), pJsHandler);
pV8->SetValue(CefString("JSCallCppCB"), pFunc, V8_PROPERTY_ATTRIBUTE_NONE);

这里的字符串“JSCallCppCB"是需要记住的,这个名字可以修改,但是要保持这个名字和javascript上调用的名字一样,不然是不能调用成功的,后面介绍javascript上怎么写。
③在cef的CefV8Handler的继承类CSimpleV8Handler中重写虚函数Execute,这部分相当于实现cef的回调处理。头文件定义入下:

virtual bool Execute(const CefString& name, CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments,CefRefPtr<CefV8Value>& retval, CefString& exception) OVERRIDE;

在具体实现中的代码如下:

bool CSimpleV8Handler::Execute(const CefString& name, CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments,CefRefPtr<CefV8Value>& retval, CefString& exception)
{
	if (name == CefString("JSCallCppCB")){		//这里根据回调名字区分
		if (arguments.size() ==2 ){				//判断网页上传递的形参个数
			CefString str = arguments[0]->GetStringValue();		//获取第一个形参的值
			int value = arguments[1]->GetIntValue();			//获取第二个形参的值
			//做一些其他事情
			return true;
		}
	}
	return false;
}

在这里遇到一个神奇的问题,就是打断点无论如何都停不下来,开始我以为代码根本没执行,但是弹出一个信息提示框发现是有提示框的,但就是断点不起作用,在另一篇文章里面有详细说明,另外在文末的连接中有一个完整的代码。
④最关注的就是网页上如何调用这个方法了,下面试javascript调用代码,很简单:

   var str = document.getElementById('cefInput').value;
   window.JSCallCppCB(str,1);

注意这里的函数名和cef中的订阅名字是一样的,和回调中的名字也是一样的,直到这里就可以完美的从javascript中调用mfc代码了,参数可以传递多个。

二、mfc调用javascript代码
①mfc代码
这部分有点点不一样了,网上有直接在v8引擎中调用的,不过这个调用代码写在哪儿看需求,我是直接写在浏览器的Dlg中的,实现如下:

if (m_simpleClient.get()){
	CefRefPtr<CefBrowser>browser = m_simpleClient->GetBrowser(m_hWnd);
	if (browser){
		CefRefPtr<CefFrame> frame = browser->GetMainFrame();
		CString jscall = _T("ChangeText('");
		jscall += str;
		jscall += _T("');");
		frame->ExecuteJavaScript(jscall.GetBuffer(), frame->GetURL(), 0);
	}
}

其中m_simpleClient是cef浏览器句柄,这个是在创建浏览器的时候的一个类变量,如果不清楚怎么创建cef浏览器,请网上查阅。
②javascript代码

function ChangeText(v){
    //做一些事情
}

这里也可以传递多个参数,只需要在c++代码中组装好调用的字符串,javascript中写好定义即可,注意参数一致。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值