资源地址:
源码:https://gitlab.com/xiliumhq/chromiumembedded/cefglue
官方论坛:http://www.magpcss.org/ceforum/
cef:http://opensource.spotify.com/cefbuilds/index.html
里面有各个版本的下载;
很少写博客,写的不好,请多多包含,主要是记录工作中的一些问题,和园子里朋友一起讨论学习。
写埋坑记录之前,我先介绍下为什么会使用这个webkit内核的浏览器组件,我是wpf项目使用富文本编辑器,话说wpf平台里面原生支持比较好的富文本编辑器还真没用,还有一个原因我这个编辑器还要集成数学公式的输入输出,那就必须要自定义控件显现,考虑到web端的通用,最后决定用百度编辑器UEDITORjq插件。
cefglue底层是C/C++项目,主要是通过平台调用p/invoke实现。cefglue代码下载地址是:,动态链接库下载地址:,注意要FQ。
代码结构我就不说了,里面有winform wpf 等版本,当然主要的功能已经实现,如果需要特定功能需额外定制。出于项目需要,我主要实现了有一下几个功能。
1.执行js获取返回值。
2.js回调后台方法。
获取返回值,CEF使用V8引擎实现javascript操作。浏览器中的每一个Frame都有它自己的JS上下文,上下文提供一种线程安全机制来执行页面上的JS代码
JS运行在独立的渲染进程中,同渲染线程同一个线程。渲染进程的中的主线程使用TID_RENDERER来标示,所有的V8操作必须在这个线程上执行。JS执行相关的回调通过CefRenderProcessHandler暴露出来实现回调。主要代码:protected override bool OnProcessMessageReceived(CefBrowser browser, CefProcessId sourceProcess, CefProcessMessage message)
{ string[] items = message.Name.Split(new char[] { '|' });if (items.Length == 0) return false;switch (items[0])
{ case "EvaluateScript":{ CefV8Value value = CefV8Value.CreateString("t");CefV8Exception exp;browser.GetMainFrame().V8Context.TryEval(items[1], out value, out exp);CommonObj.JsEvaResult = null;if (value == null){ CommonObj.flag = true;return true;}elseif (value.IsArray){}
elseif (value.IsString){ CommonObj.JsEvaResult = value.GetStringValue();}elseif (value.IsInt){ CommonObj.JsEvaResult = value.GetIntValue();}elseif (value.IsDouble){ CommonObj.JsEvaResult = value.GetDoubleValue();}elseif (value.IsBool){ CommonObj.JsEvaResult = value.GetBoolValue();}elseif (value.IsDate){ CommonObj.JsEvaResult = value.GetDateValue();}CommonObj.flag = true;return true;}从写CefRenderProcessHandler基类OnProcessMessageReceived方法,此处一定要注意,在外部多线程环境里面执行,一定要封送渲染线程上下文环境,要不无法回调。
2.js回调后台,第一种方法:网上有很多朋友通过ajax请求实现,原理是截获请求报文,获取请求参数,实现动态反射。第二种方法:浏览器窗口中的每个页面都有V8上下文。上下文包含了页面中所有的变量、对象和方法,如果我们注册了CefV8HandlerV8上下文处理器,并且在本地代码中保存当前上下文的引用和JS函数那么可以轻松实现js回调。
主要思路,代码太多,如果需要代码的可以给我留言:
1.生成本地js和页面js映射。2.实现V8引擎,从写Excute方法。3.创建js回调类,包含页面js函数声明方法,主要是为了V8Excute方法里面动态反射调用。
到现在为止,js回调后台方法实现,但是新的问题来了。没办法确定是哪个浏览器里面的js触发的回调。我的做法是,在每个浏览器加载页面完成的时候生成一个GUID标识浏览器对象id,执行页面js函数,写入到页面隐藏域里面,便于后面的回调传入这个标识ID。
目前项目中用到的就这几个功能,写的不好不要拍砖,需要源代码的可以给我留言。