文章分享

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

当前位置:首页>文章分享

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

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

由于项目选用了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<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

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

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

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


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

下一篇:JsonView online

在线咨询

点击这里给我发消息 售前咨询专员

点击这里给我发消息 售后服务专员

在线咨询

免费通话

24小时免费咨询

请输入您的联系电话,座机请加区号

免费通话

微信扫一扫

微信联系
返回顶部