Win32 应用中的 WebView2 入门

在本文中,你将 () 设置开发工具,了解如何将 WebView2 代码添加到 Win32 应用项目,并在此过程中了解 WebView2 概念。

本教程首先打开添加了 WebView2 代码的现有 Win32 应用项目。 项目使用属于存储库的 Win32_GettingStarted (WebView2GettingStarted.sln) 目录 WebView2Samples 。 若要使用本文,请执行以下操作:

  1. 克隆存储库或将 WebView2Samples 存储库下载到本地驱动器。
  2. 运行已完成的项目。
  3. (可选)从 HelloWebView.cpp 中删除 WebView2 代码以还原 Win32 基线应用。
  4. 按照本文中有关添加和了解 WebView2 代码的剩余步骤进行操作。

本教程未创建新项目;不使用 Visual Studio 中的项目模板来创建新项目。 相反,请从存储库中已完成的项目开始。

已完成的项目

WebView2Samples 存储库中提供了已完成的教程项目:

  • 示例名称: Win32_GettingStarted
  • 存储库目录: Win32_GettingStarted
  • 解决方案文件: WebView2GettingStarted.sln

步骤 1 - 安装 Visual Studio

本教程需要Microsoft Visual Studio,而不是Microsoft Visual Studio Code。

  1. 如果尚未安装Microsoft Visual Studio,请参阅在为 WebView2 设置开发环境中的安装 Visual Studio。 按照其中的步骤执行 Visual Studio 的基本默认安装。

然后返回到此页,继续下面的操作。

步骤 2 - 克隆或下载 WebView2采样存储库

在本教程的步骤中添加的代码已添加到示例存储库中。 下面的可选步骤允许从 HelloWebView.cpp中删除 WebView2 代码,以便可以根据需要自行添加它。

为了使本教程重点介绍特定于 WebView2 的编码,我们从现有的 Microsoft Visual Studio 项目开始, (WebView2GettingStarted 存储在 GitHub 存储库中的 WebView2Samples) 。 我们将添加 WebView2 功能 - 实际上,这些功能已添加,但请遵循设置和说明步骤。

我们将开始使用的现有 Visual Studio 项目是标准 C++ Win32 桌面应用程序中的示例代码的一部分。 有关新窗口或选项卡中的基础标准 Win32 应用示例的信息,请参阅 演练: (C++) 创建传统的 Windows 桌面应用程序


克隆或下载 WebView2Samples 存储库,如下所示:

  1. 如果尚未,请克隆或下载 WebView2Samples 存储库。 为此,请在单独的窗口或选项卡中,按照为 WebView2 设置开发环境中的下载 WebView2Samples 存储库克隆 WebView2 采样存储库中的步骤操作。

然后将存储库复制到本地驱动器后返回此处,并继续执行以下步骤。

步骤 3 - 打开已完成的解决方案 (WebView2GettingStarted.sln)

从包含单个主窗口的基本桌面项目开始。 我们将从 WebView2Samples 存储库中的现有应用项目开始,在上一步中从 GitHub 克隆或下载该项目。

  1. 打开 Visual Studio (而不是 Visual Studio Code) 。

  2. 打开 WebView2GettingStarted.sln,位于路径 <your repo directory>/WebView2Samples/GettingStartedGuides/Win32_GettingStarted/WebView2GettingStarted.sln:。

步骤 4 - 在出现提示时安装工作负载

Visual Studio 安装程序可能会打开并提示你安装工作负载:

Visual Studio 安装程序提示安装“使用 C++ 进行桌面开发”工作负载

如果 Visual Studio 安装程序提示安装工作负荷:

  1. 选择 带有C++的桌面开发 卡,以便显示复选标记。

  2. 如果需要,还可以选择本教程) 不需要的 .NET 桌面开发 卡 (,以便此卡上也显示复选标记。

  3. 单击“ 安装 ”按钮。

安装程序将关闭。

重新定位项目

可能会显示“Visual Studio 查看解决方案操作 ”对话框,提示你是否要 重新定位项目

Visual Studio 的“查看解决方案操作”对话框,提示重新定位项目

  1. 如果出现该对话框,可以单击“ 确定”。

WebView2GettingStarted 解决方案将在 Visual Studio 中打开。 解决方案包含单个项目: WebView2GettingStarted,其中包含单个.cpp文件: HelloWebView.cpp

步骤 5 - 在 Visual Studio 中查看打开的项目

如果 WebView2GettingStarted 项目未在 Visual Studio 中打开,请在 Visual Studio 中打开它:

  1. 打开 WebView2GettingStarted.sln,位于路径 <your repo directory>/WebView2Samples/GettingStartedGuides/Win32_GettingStarted/WebView2GettingStarted.sln:。

  2. 在“解决方案资源管理器”中,展开“ 源文件” 节点,然后选择“ HelloWebView.cpp”。

    HelloWebView.cpp 在 Visual Studio 的代码编辑器中打开。

    “WebView2GettingStarted.sln”文件从克隆或下载的 WebView2 存储库,在 Visual Studio 中打开,在解决方案资源管理器中打开

上面的屏幕截图显示了一些 WebView2 代码 (#include "WebView2.h") ,在克隆 (下载) 存储库后,该文件中已立即存在这些代码。

设置解决方案以使用 Win10 SDK 和 Visual Studio 工具集

只有较旧版本的 Visual Studio 才需要此步骤,因此可以跳过此步骤。 但在任何情况下,都可以查看此 UI:

  1. 在 Visual Studio 的解决方案资源管理器中,右键单击 “WebView2GettingStarted”项目 (与) 同名的解决方案,然后选择“ 属性”。

  2. 选择“配置属性常规”>,如果不是) 的正确设置,则 (:

    1. 修改 Windows SDK 版本 以使用 Win10 SDK。

    2. 修改 平台工具集 以使用 Visual Studio 工具集。

    这些修改仅适用于旧 版 Visual Studio。

    下面是显示一些有效设置的 Visual Studio 2017 屏幕截图:

    在 Visual Studio 2017 中,将 Windows SDK 版本设置为 10,将平台工具集设置为 Visual Studio

    下面是 Visual Studio 2022 屏幕截图:值已正确,因此无需更改:

    在 Visual Studio 2022 中,Windows SDK 版本已为 10,平台工具集已是 Visual Studio

继续执行以下步骤。

步骤 6 - 生成并运行存储库的已完成项目

此时,开发环境已设置为在 Visual Studio 中的调试模式下运行 Win32 WebView2 应用,并添加 WebView2 功能。


若要确认系统已设置 WebView2 编码,请在调试模式下运行项目,如下所示:

  1. 选择“ 调试>”“开始调试 ” (F5) 以生成并运行项目。

    示例应用首先打开一个弹出窗口,其中显示将加载的 URL 以及 “确定” 按钮:

    示例应用在空的 WebView2 窗口中显示一个带有 URL 和“确定”按钮的弹出窗口

  2. 单击“ 确定” 按钮关闭弹出窗口,然后继续转到 URL:

    WebView2 窗口现在显示网页内容:必应网站。 http://www.bing.com

    示例应用现在显示必应网站

  3. 关闭 WebView 示例 窗口。

步骤 7 - (WIL) 更新或安装 Windows 实现库

WIL 已安装到存储库中的项目中,但请逐步完成这些步骤来了解设置并检查项目的设置。

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

本教程还使用 Windows 运行时C++模板库 (WRL) - 一种模板库,提供创作和使用 Windows 运行时组件的低级别方法。


从 Visual Studio 中安装 Windows 实现库 (WIL) ,如下所示:

  1. 在 Visual Studio 中,确保 WebView2GettingStarted 解决方案仍处于打开状态。

  2. 解决方案资源管理器中,右键单击 “WebView2GettingStarted ”项目节点 (而不是解决方案节点) 然后选择“ 管理 NuGet 包”。

    管理 NuGet 包

  3. “NuGet” 窗口中,单击“ 浏览 ”选项卡。

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

    Microsoft.Windows.ImplementationLibrary
    

    在 Visual Studio 的 NuGet 包管理器中选择 Microsoft.Windows.ImplementationLibrary 包:

    在 Visual Studio 的 NuGet 包管理器中选择“Microsoft.Windows.ImplementationLibrary”包

    若要缩放,请右键单击“ >在新选项卡中打开图像”。

    如果未看到 列出 Microsoft.Windows.ImplementationLibrary ,请检查 NuGet 源位置,如下所示:

    1. 选择 “工具>选项>”“NuGet 包管理器>包源”。

    2. 请确保在 包源 中存在 指向 的 nuget.comhttps://api.nuget.org/v3/index.json

    3. 如果包源不包含该源,请在“名称”文本框中和https://api.nuget.org/v3/index.json”文本框中输入 nuget.com 。 然后单击“ 更新 ”和 “确定”。

  5. 在右上角,单击“ 安装 ”按钮 (或“ 更新 ”按钮) 。 NuGet 将 Windows 实现库 (WIL) 下载到计算机。

现在已安装 WINDOWS 实现库 (WIL) ,以及 Windows 运行时C++模板库 (WRL) 。

继续执行以下步骤。

步骤 8 - 更新或安装 WebView2 SDK

存储库中已完成的项目已安装项目的 WebView2 SDK 版本。 如果使用 Win32 项目模板从头开始创建项目,则需要安装项目的 WebView SDK 包,如此处所述。

接下来,更新 (或) WebView2 SDK 安装。 WebView2 SDK 包括由 Microsoft Edge 提供支持的 WebView2 控件,使你能够在本机应用程序中嵌入 web 技术 (HTML、CSS 和 JavaScript) 。


更新 (或) 安装 WebView2 SDK,如下所示:

  1. 在 Visual Studio 中,确保 WebView2GettingStarted 解决方案已打开,如上所述。

  2. “解决方案资源管理器”中,右键单击 “WebView2GettingStarted ”项目节点 (而不是 “WebView2GettingStarted ”解决方案节点) 然后选择“ 管理 NuGet 包”。

    “NuGet 包管理器”选项卡和面板将在 Visual Studio 中打开。

    管理 NuGet 包

  3. 如果已为项目安装了 WebView2 SDK,则与存储库项目一样,请在 “NuGet” 窗口中单击“ 已安装 ”选项卡或“ 更新 ”选项卡。

  4. 或者,如果要在新项目中安装 WebView2 SDK,请单击“ 浏览 ”选项卡。

  5. 在搜索栏右侧,清除“ 包括预发行版 ”复选框 (,除非你知道需要预发行版本的 SDK) 。

  6. 在左上角的搜索栏中,键入 Microsoft.Web.WebView2。 或者,复制并粘贴下面的单行代码块。 然后选择“ Microsoft.Web.WebView2”。

    Microsoft.Web.WebView2
    
  7. 在右侧窗口中,单击“ 更新 (”或 “安装) ”。 NuGet 将 WebView2 SDK 下载到计算机。

    在 Visual Studio 的 NuGet 包管理器中选择“Microsoft.Web.WebView2”包

  8. 关闭 “NuGet 包管理器 ”选项卡。

WebView2 SDK 现已更新或安装,因此开发环境现在已设置为将 WebView2 功能添加到 Win32 应用。

继续执行以下步骤。

步骤 9 - 选择性地从HelloWebView.cpp中删除 WebView2 代码

如果要按照以下步骤将 WebView2 代码 HelloWebView.cpp 添加到自己,请删除 WebView2 代码的两个块,如下所示:

  1. 在 中 HelloWebView.cpp,删除以下代码:

    // include WebView2 header
    #include "WebView2.h"
    
  2. 在 中 HelloWebView.cpp,删除这两个注释行之间的代码行,但保留这两个注释行:

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

步骤 10 - 在 HelloWebView.cpp 中包含 WebView2.h 标头

在上面,我们执行了以下操作:

  • 克隆或下载了示例存储库,其中包括包含标准C++ Windows 桌面应用程序的现有项目。
  • 更新或安装了 WINDOWS 实现库 (WIL) 。
  • 更新或安装了 WebView2 SDK,以添加 WebView2 功能。
  • (可选)从 HelloWebView.cpp中删除了 WebView2 代码。

接下来,将 WebView2 功能添加到应用,如下所示:

  1. 在 Visual Studio 中,确保 WebView2GettingStarted 解决方案处于打开状态。

  2. 在“解决方案资源管理器”中,展开“源文件”,然后单击。HelloWebView.cpp

  3. 如果以下代码尚不存在,请将以下代码粘贴到 的最后 HelloWebView.cpp#include 行后面:

    // include WebView2 header
    #include "WebView2.h"
    

    请确保该 include 部分如下所示:

    ...
    #include <wrl.h>
    #include <wil/com.h>
    // include WebView2 header
    #include "WebView2.h"
    
  4. 请注意使用的标头:

    • wrl.h - Windows 运行时C++模板库 (WRL) - 提供创作和使用 Windows 运行时组件的低级别方法的模板库。

    • wil/com.h - Windows 实现库 (WIL) - 一种仅限标头的C++库,通过适用于常见 Windows 编码模式的可读、类型安全的C++接口,使 Windows 开发人员的生活更加轻松。

    • WebView2.h - WebView2 控件由 Microsoft Edge 提供支持,使你能够在本机应用程序中嵌入 web 技术 (HTML、CSS 和 JavaScript) 。

  5. 选择“ 全部>文件保存 ” (Ctrl+Shift+S) 保存项目。

源代码文件和项目已准备好针对 WebView2 API 使用和生成。

继续执行以下步骤。

步骤 11 - 生成空示例应用

  1. 选择“ 调试>”“开始调试 ” (F5) 以生成并运行项目。

    示例应用将打开并显示一个空窗口:

    示例应用显示一个空窗口

    现在,你有一个正在运行的空 Win32 桌面应用,具有潜在的 WebView2 功能。

  2. 关闭 “WebView 示例 应用”窗口。

继续执行以下步骤。

步骤 12 - 在父窗口中添加 WebView2 控件

接下来,将 WebView2 控件添加到主窗口。

你将使用 CreateCoreWebView2Environment 方法设置环境,并找到为控件提供支持的 Microsoft Edge 浏览器。

请注意,如果要重写以下默认值,可以改用该方法 CreateCoreWebView2EnvironmentWithOptions的“with options”版本:

  • 浏览器位置
  • 用户数据文件夹
  • 浏览器标志

完成方法后 CreateCoreWebView2Environment ,你将:

  • ICoreWebView2Environment::CreateCoreWebView2Controller 回调中 ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler 运行 方法。

  • ICoreWebView2Controller::get_CoreWebView2运行 方法以获取关联的 WebView2 控件。

现在,若要执行上述操作,请在回调中执行以下操作:

  • 设置更多设置。
  • 调整 WebView2 控件的大小,以填充 100% 的父窗口。
  • 然后在 Win32 应用中的 WebView2 控件中显示 Bing.com 网站。

  1. 在 中 HelloWebView.cpp,找到以下代码:

       UpdateWindow(hWnd);
    
       // <-- WebView2 sample code starts here -->
    
  2. 如果以下代码尚不存在,请将以下代码粘贴到 中 HelloWebView.cpp。 将代码粘贴到 行 // <-- WebView2 sample code starts here -->// <-- WebView2 sample code ends 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/");
    
                   // Step 4 - Navigation events
    
                   // Step 5 - Scripting
    
                   // Step 6 - Communication between host and web content
    
                   return S_OK;
                }).Get());
             return S_OK;
          }).Get());
    
  3. 选择“ 全部>文件保存 ” (Ctrl+Shift+S) 保存项目。

生成必应示例应用

  1. F5 生成并运行项目。

    如果首先删除了所有 WebView2 代码,则此时将有一个 Win32 窗口,该窗口填充了一个包含网页内容的 WebView2 控件:

    必应窗口

  2. 关闭 “WebView 示例 应用”窗口。

    或者,如果保留所有 WebView2 代码,此时会在空的 WebView2 窗口中打开包含必应警报对话框的弹出 WebView2 窗口。 单击“ 确定” 按钮关闭“必应”对话框。 现在,WebView2 控件由必应页面内容填充:

    示例应用显示具有必应对话框的初始空窗口

  3. 如果 WebView 示例 应用窗口处于打开状态,请将其关闭。

继续执行以下步骤。

步骤 13 - 导航事件

在上一步中,我们讨论了使用 ICoreWebView2::Navigate 方法导航到 URL。 在导航期间,WebView2 会触发一系列事件,主机可以侦听这些事件:

  1. NavigationStarting

  2. SourceChanged

  3. ContentLoading

  4. HistoryChanged

  5. NavigationCompleted

    如果现在需要更多信息,请在新窗口或选项卡中查看 WebView2 应用的导航事件

导航事件

在错误情况下,可能会发生以下一个或多个事件,具体取决于导航是否继续到错误网页:

  • SourceChanged
  • ContentLoading
  • HistoryChanged

如果发生 HTTP 重定向,则一行中有多个 NavigationStarting 事件。


例如,使用导航事件,请注册 NavigationStarting 事件的处理程序,以取消任何非 https (不安全) 请求,如下所示。

  1. 如果尚不存在,请将以下代码粘贴到 HelloWebView.cpp步骤 3 代码下方的 中:

    // 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);
    

现在,应用不会打开任何非 https 站点。 可以使用类似的机制来完成其他任务,例如将导航限制为在自己的域中。

继续执行以下步骤。

步骤 14 - 脚本

使用主机应用在运行时将 JavaScript 代码注入 WebView2 控件。 可以任务 WebView2 运行任意 JavaScript 或添加初始化脚本。 注入的 JavaScript 将应用于所有新的顶级文档和任何子帧,直到删除 JavaScript。

注入的 JavaScript 以特定的计时运行:

  • 创建全局对象后运行它。
  • 在运行 HTML 文档中包含的任何其他脚本之前运行它。

  1. 如果以下代码不存在,请将以下代码粘贴到 HelloWebView.cpp中:

    // 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());
    
  2. 选择“ 全部>文件保存 ” (Ctrl+Shift+S) 保存项目。

    现在,WebView2 冻结 Object 并返回页面文档一次。

如果代码必须按顺序运行,请使用回调

脚本注入 API (和其他一些 WebView2 API) 是异步的。 因此,如果代码必须按特定顺序运行,则应使用回调。

继续执行以下步骤。

步骤 15 - 主机和 Web 内容之间的通信

主机和 Web 内容还可以通过 postMessage 方法相互通信。 WebView2 控件中运行的 Web 内容可以通过 方法发布到主机 window.chrome.webview.postMessage ,并且该消息由主机上的任何已注册 ICoreWebView2WebMessageReceivedEventHandler 事件处理程序处理。

同样,主机可以通过 或 ICoreWebView2::PostWebMessageAsJSON 方法向 Web 内容ICoreWebView2::PostWebMessageAsString发送消息,并且消息由从侦听器添加的window.chrome.webview.addEventListener处理程序捕获。 此通信机制允许 Web 内容通过传递消息来要求主机运行本机 API 来使用本机功能。

例如,尝试在 WebView2 中输出文档 URL 时,将执行以下步骤来了解该机制:

  1. 主机注册一个处理程序,以将收到的消息返回给 Web 内容。

  2. 主机向 Web 内容注入一个脚本,该内容注册处理程序以打印来自主机的消息。

  3. 主机向 Web 内容注入一个脚本,用于将 URL 发布到主机。

  4. 将触发主机的处理程序,并返回消息 (url) 到 Web 内容。

  5. 将触发 Web 内容的处理程序,并打印来自主机的消息, (URL) 。


让主机应用和 Web 内容通过 postMessage进行通信,如下所示:

  1. 如果尚不存在,请将以下代码粘贴到 HelloWebView.cpp中:

    // 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);
    
  2. 选择“ 全部>文件保存 ” (Ctrl+Shift+S) 保存项目。

  3. F5 生成并运行项目。

    示例应用首先打开一个弹出窗口,其中显示将加载的 URL 以及 “确定” 按钮:

    示例应用在空的 WebView2 窗口中显示一个带有 URL 和“确定”按钮的弹出窗口

  4. 单击“ 确定” 按钮关闭弹出窗口,然后继续转到 URL:

    WebView2 窗口现在显示网页内容:必应网站。 http://www.bing.com

    示例应用现在显示必应网站

  5. 准备就绪后,关闭 WebView 示例 窗口。

恭喜,你已生成一个 Win32 应用,该应用托管并使用 WebView2 控件! 现在,你的开发环境已针对 WebView2 应用开发进行设置,以便在 Win32 应用中包括 WebView2 控件。 你还介绍了 WebView2 编程概念。

API 参考

另请参阅