CEF方面的研究(五) CEF中C++与JS交互

时间:2022-09-22 09:07:32

C++与JS的交互,相信不用多说,必是精髓。

在写这篇博客之前,我不得不说之前遇到的一个问题:不管怎么搞,都不能回调到C++函数中。原因是什么呢?我没有实例化Cefapp。不实例化cefapp也能加载出页面,正常的进行显示,但是在js代码中写回调,回调不到C++中!为什么会犯这么低级的错误呢?实际上,在刚刚接触CEF代码时,真的是一头雾水,在网上各种抄代码,抄的最后“四不像”。以至于,自己的代码都是东拼西凑出来的,里面的逻辑一团糟。到研究到交互时,完了,怎么搞都回调不上来,什么settings.single_process = true啊,统统不好使。(不过这个是将来断点调试的关键代码!大家必须写上!)

下面,我来给大家写一下该怎么进行回调。

一、首先clientapp类应该继承CefRenderProcessHandler类,然后重写virtual void OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,CefRefPtr<CefV8Context> context) OVERRIDE;这个函数。这个函数就是用来绑定js的回调函数的。

二、其次写一个重载CefV8Handler的子类,重写virtual bool Execute(
const CefString& name  /*JavaScript调用的C++方法名字*/,
CefRefPtr<CefV8Value> object /*JavaScript调用者对象*/, 
const CefV8ValueList& arguments /*JavaScript传递的参数*/, 
CefRefPtr<CefV8Value>& retval /*返回给JS的值设置给这个对*/, 
CefString& exception/*通知异常信息给JavaScript*/);函数,将来js的函数会回调到这里。

三、在html代码中假如window打头的回调函数代码。

接下来,我给大家举个例子。

OnContextCreated函数中添加如下代码:

CefRefPtr<CefV8Value> window = context->GetGlobal();// 获取到window
// 添加js创建函数
CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("NativeLogin", m_v8Handler);//new ClientAppExtensionHandler(this));
window->SetValue("NativeLogin", func, V8_PROPERTY_ATTRIBUTE_NONE);

Execute中添加如下代码

if (name == "NativeLogin") 
{
if (arguments.size() == 2)
{
CefString strUser = arguments.at(0)->GetStringValue();
CefString strPassword = arguments.at(1)->GetStringValue();


TCHAR szLog[256] = { 0 };
_stprintf_s(szLog, 256, _T("user - %s, password - %s\r\n"), strUser.c_str(), strPassword.c_str());
OutputDebugString(szLog);
}
return true;
}

网页中代码可以这么写

function Login(){
        //alert(window.NativeLogin(document.getElementById("userName").value, document.getElementById("password").value));
window.NativeLogin(document.getElementById("userName").value, document.getElementById("password").value);
 
 }


<form>
UserName: <input type="text" id="userName" />&nbsp;&nbsp;Password: 
<input type="text" id="password" />&nbsp;&nbsp;<input  type="button" value="Login" onclick="Login()"/></form>


这样点击网页上Login按钮时,在Execute函数中打断点,就会进到函数体内。这样一个简单的js回调就完成了。

如果想要扩展其灵活性,就需要读者对其下功夫了,举一反三触类旁通嘛!