当前位置: 首页 > 工具软件 > miniblink > 使用案例 >

浏览器嵌入组件miniblink使用笔记

殳勇
2023-12-01

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>
 类似资料: