I do example based on cefclient project.
modify client_renderer.cc, class ClientRenderDelegate implements CefV8Handler's interface Execute.
class ClientRenderDelegate : public ClientAppRenderer::Delegate,
CefV8Handler
virtual bool Execute(const CefString& name,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE {
if (name.compare("myfunc") == 0) {
// Return my string value.
retval = CefV8Value::CreateString("My Value!");
return true;
}
else if (name.compare("registercb") == 0) {
if (arguments.size() == 1 && arguments[0]->IsFunction()) {
js_callback_ = arguments[0].get();
js_context_ = CefV8Context::GetCurrentContext();
}
return true;
}
// Function does not exist.
return false;
}JS call native function
in ClientRenderDelegate OnContextCreated(), register a function named myfun,
// Retrieve the context's window object.
CefRefPtr<CefV8Value> object = context->GetGlobal();
// Create a new V8 string value. See the "Basic JS Types" section below.
CefRefPtr<CefV8Value> str = CefV8Value::CreateString("My Value!");
// Add the string to the window object as "window.myval". See the "JS Objects" section below.
object->SetValue("myval", str, V8_PROPERTY_ATTRIBUTE_NONE);
CefRefPtr<CefV8Handler> myhandler = this;
CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("myfunc", myhandler);
object->SetValue("myfunc", func, V8_PROPERTY_ATTRIBUTE_NONE);
myhandler is ClientRenderDelegate object which inherite CefV8Handler, implements Execucte()
in JS,
<script>
/*
alert(window.myval); // this is for object->SetValue("myval", str, V8_PROPERTY_ATTRIBUTE_NONE) */
alert(window.myfunc()); </script>
native call JS
in ClientRenderDelegate OnContextCreated(), register a function named registercb,
object->SetValue("registercb",
CefV8Value::CreateFunction("registercb", myhandler),
V8_PROPERTY_ATTRIBUTE_NONE); define 2 member val,
CefRefPtr<CefV8Context> js_context_;
CefRefPtr<CefV8Value> js_callback_;in Execute(), save JS function callback and render context.
function n2jFunc() {
alert("native call js function");
}
window.registercb(n2jFunc);in root_window_win.cc, replace reload button's method,
case IDC_NAV_RELOAD: // Reload button
if (CefRefPtr<CefBrowser> browser = GetBrowser()) {
//browser->Reload();
{
// Create the message object.
CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("calljs");
// Retrieve the argument list object.
CefRefPtr<CefListValue> args = msg->GetArgumentList();
// Populate the argument values.
args->SetString(0, "calljs");
args->SetInt(0, 10);
// Send the process message to the render process.
// Use PID_BROWSER instead when sending a message to the browser process.
browser->SendProcessMessage(PID_RENDERER, msg);
_cwprintf(L" send mesage calljs to render \n");
}
}Send a message calljs from browser process to render process,
in ClientRenderDelegate OnProcessMessageReceived(), run JS function n2jFunc()
const std::string& message_name = message->GetName();
// MessageBox(NULL, L" TEST", L"EditWndProc receive message", MB_OK);
if (message_name == "calljs" ) {
//browser->GetMainFrame()->ExecuteJavaScript("alert('ExecuteJavaScript works!');",
// browser->GetMainFrame()->GetURL(), 0);
if (js_callback_) {
CefV8ValueList args;
CefString str = message->GetArgumentList()->GetString(0);
args.push_back(CefV8Value::CreateString(str));
args.push_back(CefV8Value::CreateInt(message->GetArgumentList()->GetInt(1)));
js_callback_->ExecuteFunctionWithContext(js_context_, NULL, args);
}
return true;
}
return message_router_->OnProcessMessageReceived(browser, source_process,
message);
本文介绍了一个具体的客户端项目中如何通过 CefV8Handler 的实现来进行 JavaScript 和 Native 代码之间的调用。主要内容包括:修改 client_renderer.cc 文件实现 CefV8Handler 接口;在 JavaScript 中调用本地函数并注册回调;从浏览器进程向渲染进程发送消息以调用 JavaScript 函数。
961

被折叠的 条评论
为什么被折叠?



