4166am金沙.信心之选(中国)有限公司

文章分享

开放、平等、协作、快速、分享

当前位置:4166am金沙.信心之选>文章分享

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

摘录:HCTech 无锡和控电子   时间:2020-08-07   访问量:3618

由于项目选用了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:workwxWebViewChromium-masterwebview_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 browser = m_clientHandler->GetBrowser();


    CefRefPtr 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 GetBrowserProcessHandler()OVERRIDE;

    virtual CefRefPtr GetRenderProcessHandler()OVERRIDE;

    virtual void OnContextCreated(CefRefPtr browser, CefRefPtr frame, CefRefPtr context) OVERRIDE;

    virtual void OnWebKitInitialized() OVERRIDE;


    void OnContextInitialized() OVERRIDE;

    void OnBeforeChildProcessLaunch(CefRefPtr command_line) OVERRIDE;

    void OnRenderProcessThreadCreated(CefRefPtr extra_info) OVERRIDE;

    void OnScheduleMessagePumpWork(int64 delay) OVERRIDE;

protected:

    IMPLEMENT_REFCOUNTING(MyCefApp);

private:

    //js要调用的C++函数的注册

    void RegistrationCFunc(CefRefPtr browser, CefRefPtr window, const CefString& FuncName);

};


class CV8JsHandler :

    public CefV8Handler

{

public:

    CV8JsHandler(void);

    CV8JsHandler(CefRefPtr 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 object,

        const CefV8ValueList& arguments,

        CefRefPtr& retval,

        CefString& exception) OVERRIDE;

private:

    CefString NullString = "";

    CefRefPtr 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

————————————————

版权声明:本文为CSDN博主「Ellan_BM」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/Ellan_BM/java/article/details/78450042


上一篇:微孔雾化片中雾化量的控制原理

下一篇:JsonView online

Baidu
sogou