瀏覽器嵌入組件miniblink使用筆記

miniblink龍泉寺掃地僧基於chromium內核開發的一款開源瀏覽器嵌入組件,相對於BlzFans早期開發的WKE組件,在HTML5支持、JS引擎速度、新Web標準兼容性上都有較大改進,而且項目較爲活躍,作者還貼心地wke和cef的接口,方便了原有基於WKE項目遷移到miniblink上。近期有幸得到項目主要作者的指點,現將其用於演示功能的WKEXE項目的學習使用筆記記錄如下:

在WKEXE項目中添加菜單欄

與原版WKE演示項目wkeBrowser不同,使用miniblink可以不用在自己的代碼中創建程序窗口,而是通過main.cpp中調用的如下函數完成:

void RunApplication(Application* app);

由於不是我們的代碼創建窗口,故無法像wkeBrowser一樣在RegisterClassEx中指定菜單。要爲WKEXE添加菜單欄並響應菜單消息有兩種辦法:

(1)像wkeBrowser一樣,自己創建窗口和菜單,然後把wke相關的消息用wke的接口發過去
(2)動態創建菜單後,通過SetWindowLongPtr函數hook到WKEXE的hwnd的窗口函數處理菜單相關消息

考慮到如果自己創建窗口的話,渲染後的貼圖也得自己在WKEXE中實現一遍,所以我就選擇了第二種方法:

首先要獲得wkexe的進程實例,在main.cpp中添加:

HINSTANCE gHinstance; //用於保存 wkexe 進程實例

在函數WinMain中把hInstance保存到全局變量gHinstance中:

gHinstance = hInstance;

在main.cpp裏,添加如下全局變量:

extern HINSTANCE gHinstance; //用於保存 wkexe 進程實例
HWND gHwnd; //用於保存 wkexe 窗口句柄
WNDPROC OldProc; //用於保存 wkexe 窗口原始消息循環回調地址
wkeWebView gWkeWebView; //wkeWebView

在main.cpp的CreateWebWindow裏,調用如下代碼添加菜單:

HMENU hMenu = LoadMenu(gHinstance, MAKEINTRESOURCE(IDR_MENU1));
gHwnd = wkeGetHostHWND(app->window);
gWkeWebView = app->window;
SetMenu(gHwnd, hMenu);
OldProc = (WNDPROC)SetWindowLongPtr(gHwnd, GWL_WNDPROC, (LONG)NewProc);

同時在main.cpp中添加菜單消息回調代碼:

//wkexe新回調函數
LRESULT CALLBACK NewProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_COMMAND:
        {
            switch (LOWORD(wParam))
            {
                case ID_EXIT: 
                    MessageBox(NULL, L"您單擊了退出菜單", L"wkexe", MB_OK);
                    SendMessage(hWnd, WM_CLOSE, NULL, NULL);
                    break;
                default: 
                    break;
            }
        }
        return 0;
        //達到過濾消息後,恢復原來在OldProc中保存着的回調函數
        default:
        return CallWindowProc(OldProc, hWnd, message, wParam, lParam);
    }
}

C++調用JavaScript

和wke一樣,wkexe也可以通過相同的wkeRunJS函數調用JavaScript代碼,但不同的是,如果C++代碼想要獲得JavaScript的返回值,需要在調用的JS代碼前加上return:

jsRet = wkeRunJS(gWkeWebView, "return funcforcplusplus(\"\xe4\xbd\xa0\xe5\xa5\xbd ABCDEFG\")");
jsRetStr = jsToStringW(wkeGlobalExec(gWkeWebView), jsRet);
MessageBox(hWnd, jsRetStr, L"runJS返回", 0);

JavaScript調用C++

同wke一樣,JS調用C++代碼也需要綁定,在RunApplication函數中CreateWebWindow之前添加如下代碼:

jsBindFunction("msgBox", js_msgBox, 2);//JS調用C++

同時在app.cpp文件中添加:

//JS調用C++
jsValue JS_CALL js_msgBox(jsExecState es)
{
    const wchar_t* text = jsToStringW(es, jsArg(es, 0));
    const wchar_t* title = jsToStringW(es, jsArg(es, 1));
    MessageBox(NULL, text, title, 0);
    return jsStringW(es, L"C++返回字符串");

}

這裏有個BUG需要注意,miniblink的jsToStringW函數目前只能處理JavaScript傳入的字符串參數(作者將在下步更新代碼時修正),如果前端msgBox函數傳入的參數不是字符串類型,那麼會得到空值。

附上前端測試用的HTML代碼如下:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>WKE Test Web Page</title>
<script>
function funcforcplusplus(instr){
    document.getElementById('result').value=instr;
    return navigator.userAgent;
    //return "JavaScript Return 返回啦";
}
</script>
</head>
<body>
<p>WKE Test Web Page</p>
<a href='#' onclick="document.getElementById('result').value=msgBox('TEST Function from JS to Cpp','來自Javascript的調用');">LINK</a>
<textarea rows='6' cols='36' id='result'>hello</textarea>
</body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章