wxWidgets嵌入CEF3,并实现JavaScript调用C++代码

来源:互联网 发布:晕血学生物 知乎 编辑:程序博客网 时间:2024/06/06 03:42

由于项目选用了wxWidgets做图形界面,wx既然能和QT相提并论,自然是他的跨平台做的也相当的优秀,唯一的美中不足是资料太少。
好了废话不多说,言归正传。
我使用wxWidgets版本是3.0.2,在windows vs2013下做的项目,接下来是要移植到Mac 和Linux系统下的。
wx嵌入CEF3是参考了GitHub上的一个开源项目,也是wx官方论坛里的大神提供的,连接地址如下:
https://github.com/sjlamerton/wxWebViewChromium
参照着这个基本上把CEF嵌入到wx中是没有任何问题的,不过这个项目比较早了,编译过程中会有一个报错,这都是小错误,很好
解决。
错误类似于下面的:
error C2660: “CefExecuteProcess”: 函数不接受 2 个参数 D:\work\wxWebViewChromium-master\webview_chromium3.cpp
这是由于CEF的新版本的这些函数的参数列表发生了变化,加入了沙箱的支持,多加一个NULL参数就行了。
CEF嵌入成功之后由于项目中牵涉到了JavaScript与C++直接的通信。两种JavaScript调用C++的代码和C++执行js
1、C++调用JavaScript是非常的容易 就是代码中
wxWebViewChromium::RunScript(const wxString& javascript);的实现,这里是重新实现了wxWebView的RunScript函数,直接调
用CEF的ExecuteJavaScript()函数,具体可以参考源代码:

void wxWebViewChromium::RunScript(const wxString& javascript){    CefRefPtr<CefBrowser> browser = m_clientHandler->GetBrowser();    CefRefPtr<CefFrame> frame = browser->GetMainFrame();    frame->ExecuteJavaScript(javascript.ToStdString(), "", 0);}

2、JavaScript调用C++的代码稍微复杂一点
首先要自己实现两个类分别为:

class MyCefApp    :public CefApp,    public CefBrowserProcessHandler,    public CefRenderProcessHandler{public:    MyCefApp();    virtual ~MyCefApp(){}public:    virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler()OVERRIDE;    virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler()OVERRIDE;    virtual void OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context) OVERRIDE;    virtual void OnWebKitInitialized() OVERRIDE;    void OnContextInitialized() OVERRIDE;    void OnBeforeChildProcessLaunch(CefRefPtr<CefCommandLine> command_line) OVERRIDE;    void OnRenderProcessThreadCreated(CefRefPtr<CefListValue> extra_info) OVERRIDE;    void OnScheduleMessagePumpWork(int64 delay) OVERRIDE;protected:    IMPLEMENT_REFCOUNTING(MyCefApp);private:    //js要调用的C++函数的注册    void RegistrationCFunc(CefRefPtr<CefBrowser> browser, CefRefPtr<CefV8Value> window, const CefString& FuncName);};class CV8JsHandler :    public CefV8Handler{public:    CV8JsHandler(void);    CV8JsHandler(CefRefPtr<CefBrowser> browser);    virtual ~CV8JsHandler(void);    enum MessageType    {        FAST_REPLY_TYPE = 0,        //快捷回复        REPLY_TYPE,                 //回复        REPLY_ALL_TYPE,             //回复全部        FORWARD_TYPE,               //转发        AS_ATTACHMENT_FORWARD_TYPE, //作为附件转发        UNKNOWN_TYPE,               //未知类型    };public:    virtual bool Execute(const CefString& name,        CefRefPtr<CefV8Value> object,        const CefV8ValueList& arguments,        CefRefPtr<CefV8Value>& retval,        CefString& exception) OVERRIDE;private:    CefString NullString = "";    CefRefPtr<CefBrowser> m_browser;    void SendMyMessage(const CefString& messageContent, const CefString& Num,MessageType messageType);    IMPLEMENT_REFCOUNTING(CV8JsHandler);};

a、在MyCefApp类的MyCefApp::OnContextCreated函数中实现C++函数在JavaScript中的注册(也可以在MyCefApp::OnWebKitInitialized()中实现,是两种不同的方法我目前没有采用这一种,有兴趣的可以参照CEF官方文档实现),注册的时候需要使用下面介绍的CV8JsHandler的对象实现注册

b、要知道CEF的JavaScript使用的是V8引擎,而CV8JsHandler::Execute这个函数是V8的回调函数,当JavaScript调用C++代码的时候就会执行该回调函数,在该回调函数中通过函数名可以知道JS调用的是上一步注册的哪个C++函数。

c、关于MyCefApp类的使用是在wxWebViewChromium::StartUp函数里面,调用CefInitialize(args, settings, myApp, NULL);
其中myApp是MyCefApp的对象

经过以上三个步骤就能实现JavaScript调用C++的代码。

有什么不好的地方,还请大神指正。

以下是我封装好的类源码的地址,有需要的可以拿去用:
http://download.csdn.net/download/ellan_bm/10104752

阅读全文
0 0
原创粉丝点击