由于項目選用了wxWidgets做圖形界面,wx既然能和QT相提并論,自然是他的跨平臺做的也相當(dāng)?shù)膬?yōu)秀,唯一的美中不足是資料太少。
好了廢話不多說,言歸正傳。
我使用wxWidgets版本是3.0.2,在windows vs2013下做的項目,接下來是要移植到Mac 和Linux系統(tǒng)下的。
wx嵌入CEF3是參考了GitHub上的一個開源項目,也是wx官方論壇里的大神提供的,連接地址如下:
https://github.com/sjlamerton/wxWebViewChromium
參照著這個基本上把CEF嵌入到wx中是沒有任何問題的,不過這個項目比較早了,編譯過程中會有一個報錯,這都是小錯誤,很好
解決。
錯誤類似于下面的:
error C2660: “CefExecuteProcess”: 函數(shù)不接受 2 個參數(shù) D:workwxWebViewChromium-masterwebview_chromium3.cpp
這是由于CEF的新版本的這些函數(shù)的參數(shù)列表發(fā)生了變化,加入了沙箱的支持,多加一個NULL參數(shù)就行了。
CEF嵌入成功之后由于項目中牽涉到了JavaScript與C++直接的通信。兩種JavaScript調(diào)用C++的代碼和C++執(zhí)行js
1、C++調(diào)用JavaScript是非常的容易 就是代碼中
wxWebViewChromium::RunScript(const wxString& javascript);的實(shí)現(xiàn),這里是重新實(shí)現(xiàn)了wxWebView的RunScript函數(shù),直接調(diào)
用CEF的ExecuteJavaScript()函數(shù),具體可以參考源代碼:
void wxWebViewChromium::RunScript(const wxString& javascript)
{
CefRefPtr<CefBrowser> browser = m_clientHandler->GetBrowser();
CefRefPtr<CefFrame> frame = browser->GetMainFrame();
frame->ExecuteJavaScript(javascript.ToStdString(), "", 0);
}
2、JavaScript調(diào)用C++的代碼稍微復(fù)雜一點(diǎn)
首先要自己實(shí)現(xiàn)兩個類分別為:
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要調(diào)用的C++函數(shù)的注冊
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, //快捷回復(fù)
REPLY_TYPE, //回復(fù)
REPLY_ALL_TYPE, //回復(fù)全部
FORWARD_TYPE, //轉(zhuǎn)發(fā)
AS_ATTACHMENT_FORWARD_TYPE, //作為附件轉(zhuǎn)發(fā)
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函數(shù)中實(shí)現(xiàn)C++函數(shù)在JavaScript中的注冊(也可以在MyCefApp::OnWebKitInitialized()中實(shí)現(xiàn),是兩種不同的方法我目前沒有采用這一種,有興趣的可以參照CEF官方文檔實(shí)現(xiàn)),注冊的時候需要使用下面介紹的CV8JsHandler的對象實(shí)現(xiàn)注冊
b、要知道CEF的JavaScript使用的是V8引擎,而CV8JsHandler::Execute這個函數(shù)是V8的回調(diào)函數(shù),當(dāng)JavaScript調(diào)用C++代碼的時候就會執(zhí)行該回調(diào)函數(shù),在該回調(diào)函數(shù)中通過函數(shù)名可以知道JS調(diào)用的是上一步注冊的哪個C++函數(shù)。
c、關(guān)于MyCefApp類的使用是在wxWebViewChromium::StartUp函數(shù)里面,調(diào)用CefInitialize(args, settings, myApp, NULL);
其中myApp是MyCefApp的對象
經(jīng)過以上三個步驟就能實(shí)現(xiàn)JavaScript調(diào)用C++的代碼。
有什么不好的地方,還請大神指正。
以下是我封裝好的類源碼的地址,有需要的可以拿去用:
http://download.csdn.net/download/ellan_bm/10104752
————————————————
版權(quán)聲明:本文為CSDN博主「Ellan_BM」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Ellan_BM/java/article/details/78450042
上一篇:微孔霧化片中霧化量的控制原理
下一篇:JsonView online
24小時免費(fèi)咨詢
請輸入您的聯(lián)系電話,座機(jī)請加區(qū)號