duiwebview2
项目地址
gitee地址
介绍
WebView2 Duilib 插件 本项目实现对 Webview2 封装, 以便能在duilib中调用WebView2的功能Webview2 是微软推出的 基于 Chromium 的Web控件。 与 CEF 相比的优势:在Win10(包含)之后随系统发布,不需要再随应用一起分发,这样可以有效减少应用安装包的大小,并可随微软官方补丁更新。
项目说明
duiwebview2 插件项目
demo 使用事例
bin\nativeweb 本地测试网页
bin\skin duilib界面资源
webview2.xml 文件中描述了 Webview2 控件支持的属性和事件
inc 控件头文件
环境配置
VS2022使用 NuGet 安装 Microsoft.Web.WebView2 。duiwebview2, demo 都需要安装安装 vcpkg
初始化插件
CPaintManagerUI::LoadPlugin(_T("duiwebview2.dll"));
创建控件
在界面描述文件加添加以下节点即可:
网页向Host发送消息
需将 webMessageEnabled 设为 "true"
function OnTest1(){
let cmd = {'cmd':'hello'}
window.chrome.webview.postMessage(JSON.stringify(cmd));
}
网页接收Host的消息
需将 webMessageEnabled 设为 "true"
window.chrome.webview.addEventListener('message', arg => {
let eventInfo = JSON.stringify(arg.data);
console.log(eventInfo);
});
Host接收网页消息
在 Notify(TNotifyUI& msg) 的 WebMessageReceived 事件中处理
if (msg.sType == _T("WebMessageReceived")) {
ICoreWebView2* webview = reinterpret_cast
ICoreWebView2WebMessageReceivedEventArgs* args = reinterpret_cast
wil::unique_cotaskmem_string message;
CHECK_FAILURE(args->TryGetWebMessageAsString(&message));
//将unicode转为utf8
auto msg = g_conv.to_bytes(message.get());
try {
auto cmdObj = json::parse(msg);
auto cmd = cmdObj["cmd"].get
if (cmd.compare("hello") == 0){
webview->PostWebMessageAsJson(LR"({"cmd":"hello-response"})");
}
else if (cmd.compare("runscript") == 0) {
m_pWebTest->ExecuteScript(LR"(scriptFunction(5,11);)", NULL);
}
}
catch (std::exception& e) {
ATLTRACE("%s\n", e.what());
}
}
Host向网页发送消息
//webview 为 ICoreWebView2 接口指针
webview->PostWebMessageAsJson(LR"({"cmd":"hello-response"})");
设置本地目录的虚拟映射表
如果想访问本地目录的网页,可以设置虚拟映射表
auto wv2 = static_cast
wil::com_ptr
//为本地网页目录添加资源映射
wil::com_ptr
webView2_3 = webView.try_query
if (webView2_3)
{
//这样就可以用 https://native.test/test.html 访问本地网页了
webView2_3->SetVirtualHostNameToFolderMapping(
L"native.test", L"..\\..\\nativeweb",
COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY_CORS);
}
注入本地对象供javascript调用
NativeObj为c++实现的双接口本地对象,具体可查看Demo的实现 我使用了一种简单的方法,并不标准
auto wv2 = static_cast
wv2->InjectObjectToScript
网页调用本地对象
//NativeObj为本地对象
//调用Add方法
chrome.webview.hostObjects.sync.NativeObj.Add(1,2);
//调用info属性
chrome.webview.hostObjects.sync.NativeObj.info = '哈哈哈';
window.alert(chrome.webview.hostObjects.sync.NativeObj.info)
主要属性
属性类型默认值说明homepageSTRING""主页autonaviBOOL"true"创建成功后自动导航scriptEnableBOOL"true"是否允许执行scriptdefaultScriptDialogsBOOL"true"是否允许默认script对话webMessageEnabledBOOL"true"是否允许web messagebuiltInErrorPageEnabledBOOL"false"是否允许默认错误页allowExternalDropBOOL"false"是否允许拖拽contextMenusEnabledBOOL"false"是否允许右键菜单acceleratorKeysEnabledBOOL"false"是否允许快捷键statusBarEnabledBOOL"false"是否允许状态栏zoomControlEnabledBOOL"false"是否允许放大缩小mustHttpsBOOL"true"是否必须为https
主要事件
事件的参数需要强制类型转换成最终类型
事件参数说明OnWebView2CreatedWebView2创建成功NavigationStartingICoreWebView2* msg.wParam
ICoreWebView2NavigationStartingEventArgs* msg.lParam开始导航NavigationCompletedICoreWebView2* msg.wParam
ICoreWebView2NavigationCompletedEventArgs* msg.lParam导航完成WebMessageReceivedICoreWebView2* msg.wParam
ICoreWebView2WebMessageReceivedEventArgs* msg.lParam收到web页发送的消息FrameNavigationCompletedICoreWebView2* msg.wParam
ICoreWebView2NavigationCompletedEventArgs* msg.lParamiFrame导航完成
关于应用发布
微软推荐分发模式 我是这样做的:
检查注册表确定是否已经安装webview2.如果没安装,调用Evergreen Bootstrapper引导程序安装webview2.理论上win10之后(含win10)的系统默认都安装了webview2
Demo 效果
精彩内容
发表评论