MFC使用 Microsoft Edge Web View2 浏览器控件显示网页

码村长 2024-08-17 12:33:07 阅读 77

Web View2

Microsoft Edge WebView2 控件允许在本机应用中嵌入 web 技术(HTML、CSS 以及 JavaScript)。 WebView2 控件使用 Microsoft Edge 作为绘制引擎,以在本机应用中显示 web 内容。

在这里插入图片描述

MFC使用WebView2显示网页内容

1.1 新建项目

在这里插入图片描述

1.2 下载和安装Web View2包

通过菜单“项目”-“管理NuGet程序包”,下载相关包。

在这里插入图片描述

在“浏览”分页的左上角的搜索栏中,键入 Microsoft.Web.WebView2。 或者,复制并粘贴下面的单行代码块。 然后选择“ Microsoft.Web.WebView2”。以及在右侧选择对应的版本,然后点击按钮安装。

在这里插入图片描述

自动弹窗下载提示框,点击确定按钮。

在这里插入图片描述

输出下载的日志信息。

在这里插入图片描述

在项目的代码文件夹里会自动创建子文件夹packages,里面保存了下载的相关包文件夹:Microsoft.Web.WebView2.1.0.902.49 。

在这里插入图片描述

再下另一个包:Microsoft.Windows.ImplementationLibrary。

稍后,你将安装 Windows 实现库 (WIL) - 仅限标头的 C++ 库,通过适用于 Windows COM 编码模式的可读、类型安全的 C++ 接口,使 Windows 上的开发人员的生活更加轻松。 可通过 Visual Studio 中的 解决方案资源管理器 为项目安装此 Microsoft.Windows.ImplementationLibrary 包。

在 “NuGet” 窗口中,单击“ 浏览 ”选项卡。在左上角的搜索栏中,键入 Microsoft.Windows.ImplementationLibrary。 或者,复制并粘贴下面的单行代码块。 然后选择 “Microsoft.Windows.ImplementationLibrary”。

在这里插入图片描述

安装。

在这里插入图片描述

同样在项目文件夹里会下载子文件夹:Microsoft.Windows.ImplementationLibrary.1.0.191107.2 。

在这里插入图片描述

在这里插入图片描述

项目文件夹的文件packages.config:

在这里插入图片描述

<code><?xml version="1.0" encoding="utf-8"?>code>

<packages>

<package id="Microsoft.Web.WebView2" version="1.0.1901.177" targetFramework="native" />code>

<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.230629.1" targetFramework="native" />code>

</packages>

1.3 添加依赖项

工程–>右键–>生成依赖项(B)。

在这里插入图片描述

在这里插入图片描述

1.4 添加Web控件

《1》添加变量和头文件

<code>#include <iostream>

#include <wrl.h>

#include <wil/com.h>

#include "WebView2.h"

using namespace Microsoft::WRL;

// Pointer to WebViewController

static wil::com_ptr<ICoreWebView2Controller> webviewController;

// Pointer to WebView window

static wil::com_ptr<ICoreWebView2> webview;

在这里插入图片描述

《2》在OnCreate事件函数中添加代码

单文档或者多文档项目添加如下代码。

<code>int CMFCApplication9View::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CView::OnCreate(lpCreateStruct) == -1)

return -1;

HWND hWnd = this->m_hWnd;

// TODO: 在此添加您专用的创建代码

// <-- WebView2 sample code starts here -->

// Step 3 - Create a single WebView within the parent window

// Locate the browser and set up the environment for WebView

CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr,

Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(

[hWnd](HRESULT result, ICoreWebView2Environment* env) -> HRESULT {

// Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window hWnd

env->CreateCoreWebView2Controller(hWnd, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(

[hWnd](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT {

if (controller != nullptr) {

webviewController = controller;

webviewController->get_CoreWebView2(&webview);

}

// Add a few settings for the webview

// The demo step is redundant since the values are the default settings

wil::com_ptr<ICoreWebView2Settings> settings;

webview->get_Settings(&settings);

settings->put_IsScriptEnabled(TRUE);

settings->put_AreDefaultScriptDialogsEnabled(TRUE);

settings->put_IsWebMessageEnabled(TRUE);

// Resize WebView to fit the bounds of the parent window

RECT bounds;

::GetClientRect(hWnd, &bounds);

webviewController->put_Bounds(bounds);

// Schedule an async task to navigate to Bing

webview->Navigate(L"https://www.bing.com/");

// <NavigationEvents>

// Step 4 - Navigation events

// register an ICoreWebView2NavigationStartingEventHandler to cancel any non-https navigation

EventRegistrationToken token;

webview->add_NavigationStarting(Callback<ICoreWebView2NavigationStartingEventHandler>(

[](ICoreWebView2* webview, ICoreWebView2NavigationStartingEventArgs* args) -> HRESULT {

wil::unique_cotaskmem_string uri;

args->get_Uri(&uri);

std::wstring source(uri.get());

if (source.substr(0, 5) != L"https") {

args->put_Cancel(true);

}

return S_OK;

}).Get(), &token);

// </NavigationEvents>

// <Scripting>

// Step 5 - Scripting

// Schedule an async task to add initialization script that freezes the Object object

webview->AddScriptToExecuteOnDocumentCreated(L"Object.freeze(Object);", nullptr);

// Schedule an async task to get the document URL

webview->ExecuteScript(L"window.document.URL;", Callback<ICoreWebView2ExecuteScriptCompletedHandler>(

[](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT {

LPCWSTR URL = resultObjectAsJson;

//doSomethingWithURL(URL);

return S_OK;

}).Get());

// </Scripting>

// <CommunicationHostWeb>

// Step 6 - Communication between host and web content

// Set an event handler for the host to return received message back to the web content

webview->add_WebMessageReceived(Callback<ICoreWebView2WebMessageReceivedEventHandler>(

[](ICoreWebView2* webview, ICoreWebView2WebMessageReceivedEventArgs* args) -> HRESULT {

wil::unique_cotaskmem_string message;

args->TryGetWebMessageAsString(&message);

// processMessage(&message);

webview->PostWebMessageAsString(message.get());

return S_OK;

}).Get(), &token);

// Schedule an async task to add initialization script that

// 1) Add an listener to print message from the host

// 2) Post document URL to the host

webview->AddScriptToExecuteOnDocumentCreated(

L"window.chrome.webview.addEventListener(\'message\', event => alert(event.data));" \

L"window.chrome.webview.postMessage(window.document.URL);",

nullptr);

// </CommunicationHostWeb>

return S_OK;

}).Get());

return S_OK;

}).Get());

// <-- WebView2 sample code ends here -->

return 0;

}

如果是对话框项目,则在OnInitDialog事件函数中添加代码。

BOOL CMFCWebView2Dlg::OnInitDialog()

{

CDialogEx::OnInitDialog();

// 将“关于...”菜单项添加到系统菜单中。

// IDM_ABOUTBOX 必须在系统命令范围内。

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != nullptr)

{

BOOL bNameValid;

CString strAboutMenu;

bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);

ASSERT(bNameValid);

if (!strAboutMenu.IsEmpty())

{

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

}

}

// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动

// 执行此操作

SetIcon(m_hIcon, TRUE);// 设置大图标

SetIcon(m_hIcon, FALSE);// 设置小图标

CoInitialize(NULL);

HWND hWnd = this->m_hWnd;

// TODO: 在此添加您专用的创建代码

// <-- WebView2 sample code starts here -->

// Step 3 - Create a single WebView within the parent window

// Locate the browser and set up the environment for WebView

CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr,

Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(

[hWnd](HRESULT result, ICoreWebView2Environment* env) -> HRESULT

{

// Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window hWnd

env->CreateCoreWebView2Controller(hWnd, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(

[hWnd](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT {

if (controller != nullptr) {

webviewController = controller;

webviewController->get_CoreWebView2(&webview);

}

// Add a few settings for the webview

// The demo step is redundant since the values are the default settings

wil::com_ptr<ICoreWebView2Settings> settings;

webview->get_Settings(&settings);

settings->put_IsScriptEnabled(TRUE);

settings->put_AreDefaultScriptDialogsEnabled(TRUE);

settings->put_IsWebMessageEnabled(TRUE);

// Resize WebView to fit the bounds of the parent window

RECT bounds;

::GetClientRect(hWnd, &bounds);

webviewController->put_Bounds(bounds);

// Schedule an async task to navigate to Bing

webview->Navigate(L"https://www.bing.com/");

// <NavigationEvents>

// Step 4 - Navigation events

// register an ICoreWebView2NavigationStartingEventHandler to cancel any non-https navigation

EventRegistrationToken token;

webview->add_NavigationStarting(Callback<ICoreWebView2NavigationStartingEventHandler>(

[](ICoreWebView2* webview, ICoreWebView2NavigationStartingEventArgs* args) -> HRESULT {

wil::unique_cotaskmem_string uri;

args->get_Uri(&uri);

std::wstring source(uri.get());

if (source.substr(0, 5) != L"https") {

args->put_Cancel(true);

}

return S_OK;

}).Get(), &token);

// </NavigationEvents>

// <Scripting>

// Step 5 - Scripting

// Schedule an async task to add initialization script that freezes the Object object

webview->AddScriptToExecuteOnDocumentCreated(L"Object.freeze(Object);", nullptr);

// Schedule an async task to get the document URL

webview->ExecuteScript(L"window.document.URL;", Callback<ICoreWebView2ExecuteScriptCompletedHandler>(

[](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT {

LPCWSTR URL = resultObjectAsJson;

//doSomethingWithURL(URL);

return S_OK;

}).Get());

// </Scripting>

// <CommunicationHostWeb>

// Step 6 - Communication between host and web content

// Set an event handler for the host to return received message back to the web content

webview->add_WebMessageReceived(Callback<ICoreWebView2WebMessageReceivedEventHandler>(

[](ICoreWebView2* webview, ICoreWebView2WebMessageReceivedEventArgs* args) -> HRESULT {

wil::unique_cotaskmem_string message;

args->TryGetWebMessageAsString(&message);

// processMessage(&message);

webview->PostWebMessageAsString(message.get());

return S_OK;

}).Get(), &token);

// Schedule an async task to add initialization script that

// 1) Add an listener to print message from the host

// 2) Post document URL to the host

webview->AddScriptToExecuteOnDocumentCreated(

L"window.chrome.webview.addEventListener(\'message\', event => alert(event.data));" \

L"window.chrome.webview.postMessage(window.document.URL);",

nullptr);

// </CommunicationHostWeb>

return S_OK;

}).Get());

return S_OK;

}).Get());

return TRUE; // 除非将焦点设置到控件,否则返回 TRUE

}

《3》在OnSize事件函数中添加代码

void CMFCApplication9View::OnSize(UINT nType, int cx, int cy)

{

CView::OnSize(nType, cx, cy);

// TODO: 在此处添加消息处理程序代码

if (webviewController != nullptr) {

RECT bounds;

GetClientRect(&bounds);

webviewController->put_Bounds(bounds);

};

}

在这里插入图片描述

1.5 运行效果

《1》依赖动态库整理

在 packages 目录下搜索缺少的依赖动态库。

在这里插入图片描述

搜索 <code>"WebView2Loader.dll" ,拷贝到项目Debug目录下。

在这里插入图片描述

《2》运行程序

在这里插入图片描述

《3》百度导航

在这里插入图片描述

1.6 注意事项

在代码开始和结束的位置添加如下代码。

<code>//初始化位置

CoInitialize(NULL);

//程序销毁

CoUninitialize();



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。