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(msg.wParam);

ICoreWebView2WebMessageReceivedEventArgs* args = reinterpret_cast(msg.lParam);

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(msg.pSender);

wil::com_ptr webView = wv2->GetWebView2();

//为本地网页目录添加资源映射

wil::com_ptr webView2_3;

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(msg.pSender);

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 效果

精彩内容

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: