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:
<?xml version="1.0" encoding="utf-8"?><packages><packageid="Microsoft.Web.WebView2"version="1.0.1901.177"targetFramework="native"/><packageid="Microsoft.Windows.ImplementationLibrary"version="1.0.230629.1"targetFramework="native"/></packages>
1.3 添加依赖项
工程–>右键–>生成依赖项(B)。
1.4 添加Web控件
《1》添加变量和头文件
#include<iostream>#include<wrl.h>#include<wil/com.h>#include"WebView2.h"
using namespace Microsoft::WRL;// Pointer to WebViewControllerstatic wil::com_ptr<ICoreWebView2Controller> webviewController;// Pointer to WebView windowstatic wil::com_ptr<ICoreWebView2> webview;
《2》在OnCreate事件函数中添加代码
单文档或者多文档项目添加如下代码。
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 WebViewCreateCoreWebView2EnvironmentWithOptions(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 -->return0;}
如果是对话框项目,则在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 WebViewCreateCoreWebView2EnvironmentWithOptions(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 目录下搜索缺少的依赖动态库。
搜索
"WebView2Loader.dll"
,拷贝到项目Debug目录下。
《2》运行程序
《3》百度导航
1.6 注意事项
在代码开始和结束的位置添加如下代码。
//初始化位置CoInitialize(NULL);//程序销毁CoUninitialize();
版权归原作者 码村长 所有, 如有侵权,请联系我们删除。