CEF3和本地程序交互机制
2014-12-02 20:34
309 查看
CEF中一个页面的框架如下图所示:
CefBrowser:一个普通的浏览器页面(HTML)
CefFrame:每一个页面都由至少一个frame组成,最顶层的为mainframe
context:JS执行环境,每个frame都有自己独立的context,CEF中使用V8JavaScriptEngine解析和执行JS代码
后端和前端的通信分为两个部分:
示例:
CefRefPtr<CefBrowser> browser = ...;
CefRefPtr<CefFrame> frame = browser->GetMainFrame();
frame->ExecuteJavaScript("alert('ExecuteJavaScript works!');",
frame->GetURL(), 0);
可以得知,C++端执行JS的通用流程为:
1.获取页面引用
2.获取目标frame引用
3.在目标frame上调用ExecuteJavaScript执行JS
槽点:函数ExecuteJavaScript的返回值为空,函数中也没有其他形式获取JS执行的返回值。那么JS的返回值如何获取?
CefValue表示JS环境中的一个对象,其可以表示JS中所有变量,切其自身可以嵌套。特别重要的一点,前端的window对象在后端也是一个CefV8Value,并且可以通过CefV8Context取到它。
JS调用C++的实质是:以CefV8Value的形式包装C++对象,并将其绑定到特定frame的JS执行环境的window对象上,如此JS代码就可以直接对其读写(属性)或者调用(函数)。
A. window binding,将自定义数据绑定到JS context的window对象上
1.在回调CefRenderProcessHandler的OnContextCreated()中注册。注册过程:
1.1获取CefV8Value形式的window对象
1.2构造数据
1.3绑定到window对象上
代码示例:
void MyRenderProcessHandler::OnContextCreated(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) {
CefRefPtr<CefV8Value> object = context->GetGlobal();// 获取到window
CefRefPtr<CefV8Value> str = CefV8Value::CreateString("My Value!");
object->SetValue("myval", str, V8_PROPERTY_ATTRIBUTE_NONE);
}
2.特别注意:在frame reload的时候,需要重新绑定。frame reload其实就是重新创建了context,需要重新执行绑定过程,这很好理解。
3.CefV8Value的setValue方法就是将数据绑定到对象上
B.extensions,将预定义的JS代码注册到context中,并且一旦注册,不可修改。这种方式威力很弱,我想只会在特殊的场景下选它。
在CefRenderProcessHandler的回调OnWebKitInitialized()中执行注册
示例:
C.数据构造
1. JS基本类型,CEF支持创建基本JS数据类型,比如undefined, null, bool, int, double, date and string。使用静态函数CefV8Value::Create*()
2.JS数组,CefV8Value::CreateArray()
3.JS对象,CefV8Value::CreateObject(NULL)
4.JS function, CefV8Value::CreateFunction();
D.属性读写和函数实现
1.对象读写
创建CefV8Value时,关联一个CefV8Accessor,并实现它的get和set,示例:
//创建时关联CefV8Accessor
CefRefPtr<CefV8Accessor> accessor = …;
CefRefPtr<CefV8Value> obj = CefV8Value::CreateObject(accessor);
//实现自己的CefV8Accessor
2.函数实现
创建函数时,绑定自己实现的CefV8Handler,示例:
CefRefPtr<CefV8Handler> handler = …;
CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("myfunc", handler);
//实现自己的CefV8Handler
CefBrowser:一个普通的浏览器页面(HTML)
CefFrame:每一个页面都由至少一个frame组成,最顶层的为mainframe
context:JS执行环境,每个frame都有自己独立的context,CEF中使用V8JavaScriptEngine解析和执行JS代码
后端和前端的通信分为两个部分:
一.C++ call JS:
由框架图可以知道,后端执行JS的实质是:在特定的frame上执行JS代码片段示例:
CefRefPtr<CefBrowser> browser = ...;
CefRefPtr<CefFrame> frame = browser->GetMainFrame();
frame->ExecuteJavaScript("alert('ExecuteJavaScript works!');",
frame->GetURL(), 0);
可以得知,C++端执行JS的通用流程为:
1.获取页面引用
2.获取目标frame引用
3.在目标frame上调用ExecuteJavaScript执行JS
槽点:函数ExecuteJavaScript的返回值为空,函数中也没有其他形式获取JS执行的返回值。那么JS的返回值如何获取?
二.JS call C++
C++和JS对象的映射关系:CefValue表示JS环境中的一个对象,其可以表示JS中所有变量,切其自身可以嵌套。特别重要的一点,前端的window对象在后端也是一个CefV8Value,并且可以通过CefV8Context取到它。
JS调用C++的实质是:以CefV8Value的形式包装C++对象,并将其绑定到特定frame的JS执行环境的window对象上,如此JS代码就可以直接对其读写(属性)或者调用(函数)。
A. window binding,将自定义数据绑定到JS context的window对象上
1.在回调CefRenderProcessHandler的OnContextCreated()中注册。注册过程:
1.1获取CefV8Value形式的window对象
1.2构造数据
1.3绑定到window对象上
代码示例:
void MyRenderProcessHandler::OnContextCreated(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) {
CefRefPtr<CefV8Value> object = context->GetGlobal();// 获取到window
CefRefPtr<CefV8Value> str = CefV8Value::CreateString("My Value!");
object->SetValue("myval", str, V8_PROPERTY_ATTRIBUTE_NONE);
}
2.特别注意:在frame reload的时候,需要重新绑定。frame reload其实就是重新创建了context,需要重新执行绑定过程,这很好理解。
3.CefV8Value的setValue方法就是将数据绑定到对象上
B.extensions,将预定义的JS代码注册到context中,并且一旦注册,不可修改。这种方式威力很弱,我想只会在特殊的场景下选它。
在CefRenderProcessHandler的回调OnWebKitInitialized()中执行注册
示例:
void MyRenderProcessHandler::OnWebKitInitialized() { std::string extensionCode = "var test;" "if (!test)" " test = {};" "(function() {" " test.myval = 'My Value!';" "})();"; CefRegisterExtension("v8/test", extensionCode, NULL); }
C.数据构造
1. JS基本类型,CEF支持创建基本JS数据类型,比如undefined, null, bool, int, double, date and string。使用静态函数CefV8Value::Create*()
2.JS数组,CefV8Value::CreateArray()
3.JS对象,CefV8Value::CreateObject(NULL)
4.JS function, CefV8Value::CreateFunction();
D.属性读写和函数实现
1.对象读写
创建CefV8Value时,关联一个CefV8Accessor,并实现它的get和set,示例:
//创建时关联CefV8Accessor
CefRefPtr<CefV8Accessor> accessor = …;
CefRefPtr<CefV8Value> obj = CefV8Value::CreateObject(accessor);
//实现自己的CefV8Accessor
class MyV8Accessor : public CefV8Accessor { public: MyV8Accessor() {} virtual bool Get(const CefString& name, const CefRefPtr<CefV8Value> object, CefRefPtr<CefV8Value>& retval, CefString& exception) OVERRIDE { if (name == "myval") { // Return the value. retval = CefV8Value::CreateString(myval_); return true; } return false; } virtual bool Set(const CefString& name, const CefRefPtr<CefV8Value> object, const CefRefPtr<CefV8Value> value, CefString& exception) OVERRIDE { if (name == "myval") { if (value.IsString()) { myval_ = value.GetStringValue(); } else { exception = "Invalid value type"; } return true; } return false; } CefString myval_; IMPLEMENT_REFCOUNTING(MyV8Accessor); };
2.函数实现
创建函数时,绑定自己实现的CefV8Handler,示例:
CefRefPtr<CefV8Handler> handler = …;
CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("myfunc", handler);
//实现自己的CefV8Handler
class MyV8Handler : public CefV8Handler { public: MyV8Handler() {} virtual bool Execute(const CefString& name, CefRefP 8d1c tr<CefV8Value> object, const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval, CefString& exception) OVERRIDE { if (name == "myfunc") { retval = CefV8Value::CreateString("My Value!"); return true; } return false; } IMPLEMENT_REFCOUNTING(MyV8Handler); };
相关文章推荐
- CEF3和本地程序交互机制
- 我的第一个 Android 程序,基于 Intent 的组件交互机制
- SilverLight浏览器交互之:将SilverLight程序安装在本地
- 谷歌chrome 插件(扩展)开发——进阶篇(c#本地程序和插件交互)上
- 基于QT webkit 本地C++与Web交互程序心得浅谈(本人新手)
- Android深入探究笔记之一 -- 我的第一个 Android 程序,基于 Intent 的组件交互机制
- 谷歌chrome 插件(扩展)开发——进阶篇(c#本地程序和插件交互)下
- Oracle FAQ: 未在本地计算机上注册"OraOLEDB.Oracle"提供程序 (The 'OraOLEDB.Oracle' provider is not registered on the local machine) solution
- .NET 异常捕获机制的小技巧应用(实例:端口扫描程序)
- 孙鑫VC++讲座笔记-(1)Windows程序内部运行机制
- 本地调试的程序上传到虚拟主机请注意:
- .NET+Oracle 9i时产生的"未在本地计算机上注册“OraOLEDB.Oracle.1”提供程序"
- “Visual Studio .NET 无法创建或打开应用程序。问题很可能是因为本地WEB本地服务器上没有安装所需的组件。请运行Visual Studio .NET安装程序并添加WEB开发组件“的一种解决方案
- 程序与程序员的交互,以日志居多
- 网页交互及xml的一些属性对程序的影响
- 孙鑫VC++讲座笔记-(1)Windows程序内部运行机制
- 解读Scorm(2):课件与平台交互机制
- 调用本地的程序打开制定文件
- 静态对象、全局对象与程序的运行机制
- 本实例程序可以列出本地硬盘上所有驱动器