种地 发表于 2024-11-30 15:22:05

MFC使用 Microsoft Edge Web View2 欣赏器控件显示网页

Web View2

Microsoft Edge WebView2 控件允许在本机应用中嵌入 web 技能(HTML、CSS 以及 JavaScript)。 WebView2 控件使用 Microsoft Edge 作为绘制引擎,以在本机应用中显示 web 内容。
https://i-blog.csdnimg.cn/direct/c34fa0367b804059b7e658e1bc00098f.jpeg#pic_center
MFC使用WebView2显示网页内容

1.1 新建项目

https://i-blog.csdnimg.cn/direct/0b9759e1cd2a444d854e23e103f54b99.png#pic_center
1.2 下载和安装Web View2包

通过菜单“项目”-“管理NuGet程序包”,下载相关包。
https://i-blog.csdnimg.cn/direct/883f55e05ffd46ff89cf1ac7794b914b.png#pic_center
在“欣赏”分页的左上角的搜索栏中,键入 Microsoft.Web.WebView2。 或者,复制并粘贴下面的单行代码块。 然后选择“ Microsoft.Web.WebView2”。以及在右侧选择对应的版本,然后点击按钮安装。
https://i-blog.csdnimg.cn/direct/d6824cde8a2c44efb44e77f608dfd253.png#pic_center
主动弹窗下载提示框,点击确定按钮。
https://i-blog.csdnimg.cn/direct/ab42ceb22330463e873218ba9ab9d39b.png#pic_center
输出下载的日志信息。
https://i-blog.csdnimg.cn/direct/9b234555b32b429189e1b274a0ae5549.png#pic_center
在项目的代码文件夹里会主动创建子文件夹packages,内里生存了下载的相关包文件夹:Microsoft.Web.WebView2.1.0.902.49 。
https://i-blog.csdnimg.cn/direct/26a3366f8a3e4e3c93ff9375be8eab28.png#pic_center
再下另一个包:Microsoft.Windows.ImplementationLibrary。
稍后,你将安装 Windows 实现库 (WIL) - 仅限标头的 C++ 库,通过适用于 Windows COM 编码模式的可读、范例安全的 C++ 接口,使 Windows 上的开发人员的生活更加轻松。 可通过 Visual Studio 中的 办理方案资源管理器 为项目安装此 Microsoft.Windows.ImplementationLibrary 包。
在 “NuGet” 窗口中,单击“ 欣赏 ”选项卡。在左上角的搜索栏中,键入 Microsoft.Windows.ImplementationLibrary。 或者,复制并粘贴下面的单行代码块。 然后选择 “Microsoft.Windows.ImplementationLibrary”。
https://i-blog.csdnimg.cn/direct/1349a31831244dc680c54d409fe3cb91.png#pic_center
安装。
https://i-blog.csdnimg.cn/direct/f483c4c07c604b9fa1064b6dff2fe76d.png#pic_center
同样在项目文件夹里会下载子文件夹:Microsoft.Windows.ImplementationLibrary.1.0.191107.2 。
https://i-blog.csdnimg.cn/direct/186b0d44e5824c5a920c4bc5cd711132.png#pic_center
https://i-blog.csdnimg.cn/direct/43a86897ffb34fdabda3193fbb95a34c.png#pic_center
项目文件夹的文件packages.config:
https://i-blog.csdnimg.cn/direct/0c18d2bb85694b6389af8398dec0dea4.png#pic_center
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Web.WebView2" version="1.0.1901.177" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.230629.1" targetFramework="native" />
</packages>
1.3 添加依赖项

工程–>右键–>生成依赖项(B)。
https://i-blog.csdnimg.cn/direct/6070fd4b72a94055b1d265fbcd32e6c0.png#pic_center
https://i-blog.csdnimg.cn/direct/6dda210e06cd47a08c46c6142ba39a34.png#pic_center
1.4 添加Web控件

《1》添加变量和头文件

#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;

https://i-blog.csdnimg.cn/direct/564dbf6d16724d629f9219f2ced43314.png#pic_center
《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 WebView
        CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr,
                Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
                        (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>(
                        (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>(
                        (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>(
                                        (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);
        };
}
https://i-blog.csdnimg.cn/direct/7692743e4182417d954059b77d6567df.png#pic_center
1.5 运行效果

《1》依赖动态库整理

在 packages 目录下搜索缺少的依赖动态库。
https://i-blog.csdnimg.cn/direct/fd5926d87ce34acc8a2aed79dd2d703f.png#pic_center
搜索 "WebView2Loader.dll" ,拷贝到项目Debug目录下。
https://i-blog.csdnimg.cn/direct/c905bb2c953b4bd49b5b61076952402c.png#pic_center
《2》运行程序

https://i-blog.csdnimg.cn/direct/27233f87c4bd42a080cd0317b0ed0b56.png#pic_center
《3》百度导航

https://i-blog.csdnimg.cn/direct/093d865b2bfd4f6f96588b6a0218f6ed.png#pic_center
1.6 注意事项

在代码开始和结束的位置添加如下代码。
//初始化位置
CoInitialize(NULL);
//程序销毁
CoUninitialize();

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: MFC使用 Microsoft Edge Web View2 欣赏器控件显示网页