Поделиться через


Пример приложения Win32

Приложение WebView2APISample демонстрирует использование элемента управления WebView2 и API WebView2 для добавления функций в приложение Win32 C++.

  • Имя примера: WebView2APISample
  • Каталог репозитория: WebView2APISample
  • Файл решения: WebView2Samples.sln (находится в родительском каталоге, \SampleApps\)
  • Имя проекта в Обозреватель решений: WebView2APISample

WebView2APISample внедряет элемент управления WebView2 в собственное приложение Win32.

Этот пример создан как проект Win32 Visual Studio 2019. Он использует C++ и HTML,CSS/JavaScript в среде WebView2.

WebView2APISample демонстрирует ряд обработчиков событий WebView2 и методов API, которые позволяют собственному приложению Win32 напрямую взаимодействовать с элементом управления WebView2 и наоборот.

Этот пример и файл решения уникальны: он содержит копию других примеров в Обозреватель решений.

WebView2APISample — это гибридное приложение, созданное с помощью элемента управления WebView2 Microsoft Edge; то есть это приложение сочетает в себе собственную сторону и сторону веб-приложения браузера. См. раздел Подход к гибридному приложению в статье Общие сведения о Microsoft Edge WebView2.

В окне запущенного приложения WebView2APISample отображается версия пакета SDK для WebView2, а также версия и путь к среде выполнения WebView2. Для вас предоставляется множество полезных меню и элементов меню:

Окно приложения WebView2APISample с версией пакета SDK для WebView2, версией и путем к среде выполнения WebView2

Если вы впервые используете WebView, рекомендуется сначала ознакомиться с руководством Начало работы с WebView2 в приложениях Win32, в котором описывается создание приложения WebView2 и рассматриваются некоторые основные функции WebView2. Это конкретное руководство не начинается с создания нового проекта Win32 с помощью шаблона проекта. Вместо этого он начинается с готового проекта в репозитории WebView2Samples и содержит сведения о добавленном коде WebView2.

Дополнительные сведения о событиях и обработчиках API в WebView2 см. в статье Справочник по API WebView2.

Шаг 1. Установка Visual Studio

Требуется Microsoft Visual Studio (минимальная версия: Visual Studio 2019). Microsoft Visual Studio Code не поддерживается в этом примере. Этот пример репозитория является проектом Visual Studio 2019. Пример также можно открыть с помощью Visual Studio 2022.

  1. Если Visual Studio еще не установлена с поддержкой C++, в отдельном окне или на вкладке см. статью Установка Visual Studioстатьи Настройка среды разработки для WebView2. Выполните действия, описанные в этом разделе, чтобы установить Visual Studio с поддержкой C++, а затем вернитесь на эту страницу и выполните следующие действия.

Если вы хотите использовать Visual Studio 2017, после открытия решения в Visual Studio 2017 измените набор инструментов платформы проекта в разделе Свойства >>> проекта Свойства проекта.

Чтобы использовать Visual Studio 2017, также может потребоваться установить на компьютере последнюю Windows SDK.

Шаг 2. Клонирование репозитория WebView2Samples

  1. Если это еще не сделано, клонируйте репозиторий на WebView2Samples локальный диск. В отдельном окне или на вкладке см . раздел Скачивание репозитория WebView2Samplesстатьи Настройка среды разработки для WebView2. Выполните действия, описанные в этом разделе, а затем вернитесь на эту страницу и продолжите работу ниже.

  2. Если вы ранее клонировали репозиторий, извлеките последние фиксации в локальную копию репозитория.

Шаг 3. Открытие решения в Visual Studio

  1. На локальном .sln диске откройте файл в Visual Studio:

    • <your-repos-directory>/WebView2Samples/SampleApps/WebView2Samples.sln

    или

    • <your-repos-directory>/WebView2Samples-main/SampleApps/WebView2Samples.sln

Пример и проект WebView2APISample — это пример main Win32.

В отличие от некоторых других примеров, в каталоге репозитория примера нет выделенного .sln файла, содержащего файл readme этого примера. Вместо этого .sln файл для этого примера (включая другие примеры проектов) находится в родительском каталоге.

Все проекты в решении в Обозреватель решений

Шаг 4. Установка рабочих нагрузок при появлении запроса

  1. Рабочие нагрузки Visual Studio . При появлении запроса установите все запрошенные рабочие нагрузки Visual Studio. В отдельном окне или вкладке см . статью Установка рабочих нагрузок Visual Studioстатьи Настройка среды разработки для WebView2. Выполните действия, описанные в этом разделе, а затем вернитесь на эту страницу и продолжите работу ниже.

Выполните указанные ниже действия.

Шаг 5. Просмотр открытого проекта

  1. На локальном диске снова откройте решение WebView2Samples в той же версии Visual Studio, которую вы настроили:

    • <your-repos-directory>/WebView2Samples/SampleApps/WebView2Samples.sln

    или

    • <your-repos-directory>/WebView2Samples-main/SampleApps/WebView2Samples.sln
  2. Нажмите кнопку ОК . Может открыться диалоговое окно "Перенацелить проекты ":

    Диалоговое окно

    Пример установленных версий:

    Retarget — установленные пакеты SDK

  3. Нажмите кнопку ОК .

Обозреватель решений отображает несколько проектов, включая проект WebView2APISample:

Проект WebView2APISample в Обозреватель решений

Шаг 6. Сборка проекта с помощью установленной версии пакета SDK

В верхней части Visual Studio задайте целевой объект сборки следующим образом:

  1. В раскрывающемся списке Конфигурации решений выберите Отладка или Выпуск.

  2. В раскрывающемся списке Платформы решений выберите x86, x64 или ARM64.

  3. В Обозреватель решений щелкните правой кнопкой мыши проект WebView2APISample и выберите Сборка.

    Проект WebView2APISample, выбранный в Обозреватель решений

    При этом создается файл SampleApps/WebView2APISample/WebView2APISample.vcxprojпроекта .

Шаг 7. Запуск (отладка) проекта

  1. Выберите Отладка>Начать отладку (F5).

    Устранение неполадок: если пропустить шаг сборки и сразу же выбрать Отладка>Начать отладку (F5), может появиться диалоговое окно "Не удается запустить программу: не удается найти указанный путь":

    диалоговое окно: не удается запустить программу: не удается найти указанный путь

    Чтобы устранить эту проблему: в Обозреватель решений щелкните правой кнопкой мыши проект WebView2APISample и выберите Сборка.

    Откроется окно приложения WebView2APISample :

    Окно приложения WebView2APISample

  2. В Visual Studio выберите Отладка>Остановить отладку. Visual Studio закрывает приложение.

Шаг 8. Обновление предварительной версии пакета SDK для WebView2

Затем вы обновите пакет SDK для WebView2, а затем повторно создадите проект.

Если вы хотите быстро узнать, какая версия пакета SDK для WebView2 установлена в копии репозитория приложения WebView2APISample на сайте GitHub, см. packages.config.

В репозитории этого примера установлена предварительная версия пакета SDK для WebView2. Ниже вы обновите его до последней предварительной версии пакета SDK Для WebView2 или подтвердите, что установлен последний пакет SDK. С помощью предварительного пакета SDK вы получаете доступ к последним функциональным возможностям.

Изучите и, возможно, обновите установленные пакеты NuGet следующим образом:

  1. В Обозреватель решений щелкните правой кнопкой мыши проект WebView2APISample (не узел решения над ним), а затем выберите Управление пакетами NuGet.

    В Visual Studio откроется панель Диспетчер пакетов NuGet .

  2. Справа от текстового поля поиска выберите поле Включить предварительную версию проверка.

  3. В диспетчере пакетов NuGet перейдите на вкладку Установленные. В правой части каждого пакета проверка, есть ли в списке новый номер версии, а также существующий номер версии.

  4. Перейдите на вкладку Обновление . Если доступны обновления для пакетов WebView2 или WIL, при необходимости можно обновить пакет здесь.

  5. Справа в раскрывающемся списке Версия убедитесь, что выбрана последняя предварительная версия, если вы хотите попробовать последние API:

    Диспетчер пакетов NuGet с выбранным предварительным выпуском пакета SDK для WebView2

  6. Нажмите кнопку Обновить .

    Откроется диалоговое окно Предварительный просмотр изменений :

    Диалоговое окно Предварительный просмотр изменений для пакета NugGet WebView2

    Приведенное выше изображение из другого проекта, но похожее.

  7. Нажмите кнопку ОК .

Для этого проекта теперь установлена последняя версия пакета SDK для WebView2.

Шаг 9. Сборка и запуск проекта с обновленным пакетом SDK

  1. В Обозреватель решений щелкните правой кнопкой мыши проект WebView2APISample и выберите Сборка.

    Проект WebView2APISample, выбранный в Обозреватель решений

  2. Выберите Отладка>Начать отладку (F5).

    Откроется окно приложения WebView2APISample :

    Окно приложения WebView2APISample

  3. Используйте приложение WebView2APISample .

  4. В Visual Studio выберите Отладка>Остановить отладку. Visual Studio закрывает приложение.

На этом будут выполнены нумерованные действия по созданию и запуску примера приложения Win32. Затем в редакторе кода Visual Studio проверьте код в следующих разделах.

Архитектура гибридного приложения

Приложение WebView2APISample является примером гибридного приложения с собственной частью Win32 и частью WebView.

  • Часть Win32 может напрямую обращаться к собственным API Windows.
  • WebView — это контейнер для стандартных веб-технологий (HTML, CSS и JavaScript).

Гибридное приложение

  • Раздел 1. Верхняя часть приложения WebView2APISample — это компонент Win32, написанный на C++. Эта часть приложения принимает входные данные пользовательского интерфейса от пользователя и использует их для управления WebView.

  • Раздел 2. Main частью приложения WebView2APISample является WebView, который можно использовать с помощью стандартных веб-технологий (HTML/CSS/JavaScript). Его можно переходить на веб-сайты или локальное содержимое.

Этот гибридный подход позволяет создавать и выполнять итерации быстрее с помощью веб-технологий, при этом при этом можно использовать преимущества собственных функций. Приложение WebView2APISample демонстрирует, как компонент Win32 и компонент WebView могут взаимодействовать друг с другом.

Этот расширенный пример приложения вырос до более чем 150 элементов menuitem, демонстрируя множество API WebView2 в платформе Win32/C++. В следующих разделах основное внимание уделяется основам реализации гибридного приложения.

Файлы проекта

В этом разделе кратко описаны некоторые ключевые файлы в репозитории. Приложение WebView2APISample делится по вертикали на компоненты, а не по горизонтали на слои. Каждый компонент реализует весь рабочий процесс категории примеров функций, от прослушивания команд меню до вызова методов API WebView для их реализации.

App.cpp

Это файл верхнего уровня, в котором выполняется приложение WebView2APISample . Он считывает параметры командной строки, настраивает среду процесса и обрабатывает модель потоков приложения.

AppWindow.cpp (меню "Окно")

Этот файл реализует окно приложения, выполнив следующие действия:

  1. Настройте все элементы управления Win32.

  2. Инициализируйте среду WebView и WebView.

  3. Добавьте обработчики событий в WebView и создайте все компоненты, обрабатывающие различные функции приложения.

Класс AppWindow обрабатывает команды из меню окна примера приложения.

Этот файл более подробно описан в разделе Основные функции в AppWindow.cpp ниже.

FileComponent.cpp (меню "Файл")

Этот компонент обрабатывает команды из меню Файл (за исключением выхода), а также DocumentTitleChanged событие.

ScriptComponent.cpp (меню "Скрипт")

Этот компонент обрабатывает команды из меню скрипта , которые включают взаимодействие с WebView путем внедрения JavaScript, публикации WebMessages, добавления собственных объектов на веб-страницу или использования протокола DevTools для взаимодействия с веб-страницей.

ProcessComponent.cpp (меню "Процесс")

Этот компонент обрабатывает команды из меню Процесс , которые включают взаимодействие с процессом браузера. Он также обрабатывает ProcessFailed событие, если процесс браузера или один из его процессов отрисовки завершается сбоем или не отвечает.

SettingsComponent.cpp (меню "Параметры")

Этот компонент обрабатывает команды из меню Параметры . Этот компонент также отвечает за копирование параметров из старого WebView при создании нового. Большая часть кода, взаимодействующего с интерфейсом ICoreWebView2Settings , находится здесь.

ViewComponent.cpp (меню "Вид")

Этот компонент обрабатывает команды из меню Вид и все функциональные возможности, связанные с изменением размера и видимостью WebView. Когда размер окна приложения изменится, свернуто или восстановлено, ViewComponent будет изменяться размер, скрываться или отображаться WebView в ответ. Он также реагирует на ZoomFactorChanged событие.

ScenarioWebMessage.cpp и ScenarioWebMessage.html (меню "Сценарий")

Компонент ScenarioWebMessage создается при выборе пункта меню Сценарий>веб-сообщений . Этот компонент реализует пример приложения с частью C++ и частью HTML+JavaScript, которые взаимодействуют друг с другом, асинхронно публикуя и получая сообщения.

Этот компонент более подробно описан в разделе ScenarioWebMessage (.html, .cpp и .h) ниже.

ScenarioAddHostObject.cpp и ScenarioAddHostObject.html (меню "Сценарий")

Этот компонент создается при выборе пункта меню Объекты узла сценариев>. Он демонстрирует взаимодействие между собственным приложением и веб-страницей HTML с помощью внедрения объекта узла. Интерфейс ведущего объекта объявляется в HostObjectSample.idl, а сам объект реализуется в HostObjectSampleImpl.cpp.

См. также:

Ключевые функции в AppWindow.cpp

AppWindow.cpp реализует окно приложения, выполнив следующие действия:

  1. Настройте все элементы управления Win32.

  2. Инициализируйте среду WebView и WebView.

  3. Добавьте обработчики событий в WebView и создайте все компоненты, обрабатывающие различные функции приложения.

Класс AppWindow обрабатывает команды из меню окна примера приложения. Ниже приведены некоторые ключевые функции в AppWindow.cpp.

InitializeWebView()

InitializeWebView() В AppWindow.cppфункция создает среду WebView2 с помощью CreateCoreWebView2EnvironmentWithOptions.

Чтобы увидеть эти вызовы API в действии, проверьте следующий код из InitializeWebView():

HRESULT hr = CreateCoreWebView2EnvironmentWithOptions(
    subFolder, nullptr, options.Get(),
    Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
        this, &AppWindow::OnCreateEnvironmentCompleted)
        .Get());
if (!SUCCEEDED(hr))
{
    if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
    {
        MessageBox(
            m_mainWindow,
            L"Couldn't find Edge installation. "
            "Do you have a version installed that's compatible with this "
            "WebView2 SDK version?",
            nullptr, MB_OK);
    }
    else
    {
        ShowFailure(hr, L"Failed to create webview environment");
    }
}

OnCreateEnvironmentCompleted()

После создания среды мы создаем WebView с помощью CreateCoreWebView2Controller.

Функция обратного OnCreateEnvironmentCompleted вызова передается CreateCoreWebView2EnvironmentWithOptions в .InitializeWebView() Обратный вызов сохраняет указатель среды, а затем использует его для создания нового WebView:

HRESULT AppWindow::OnCreateEnvironmentCompleted(
    HRESULT result, ICoreWebView2Environment* environment)
{
    CHECK_FAILURE(result);

    m_webViewEnvironment = environment;

    CHECK_FAILURE(m_webViewEnvironment->CreateCoreWebView2Controller(
        m_mainWindow, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
                            this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)
                            .Get()));
    return S_OK;
}

OnCreateCoreWebView2ControllerCompleted()

Функция обратного OnCreateCoreWebView2ControllerCompleted вызова передается CreateCoreWebView2Controller в .InitializeWebView() Этот обратный вызов:

  • Инициализирует состояние, связанное с WebView.
  • Регистрирует некоторые обработчики событий.
  • Создает компоненты приложения.

RegisterEventHandlers()

Функция RegisterEventHandlers вызывается в .CreateCoreWebView2Controller Он настраивает некоторые обработчики событий, используемые приложением, и добавляет их в WebView.

Дополнительные сведения об обработчиках событий в WebView2 см. в разделе ICoreWebView2.

Ниже приведен фрагмент кода из RegisterEventHandlers(), где мы настроили обработчик событий для NewWindowRequested события. Это событие возникает, когда JavaScript на веб-странице вызывает .window.open() ICoreWebView2NewWindowRequestedEventHandler создает объект и AppWindow передает webView нового окна обратно в браузер, чтобы он смог вернуть его из window.open() вызова. В отличие от наших вызовов к и CreateCoreWebView2Controllerвместо того, чтобы CreateCoreWebView2EnvironmentWithOptions предоставить метод для обратного вызова, мы просто предоставляем лямбда-лямбда C++ прямо тогда и там:

CHECK_FAILURE(m_webView->add_NewWindowRequested(
    Callback<ICoreWebView2NewWindowRequestedEventHandler>(
        [this](
            ICoreWebView2* sender,
            ICoreWebView2NewWindowRequestedEventArgs* args) {
            wil::com_ptr<ICoreWebView2Deferral> deferral;
            CHECK_FAILURE(args->GetDeferral(&deferral));

            auto newAppWindow = new AppWindow(L"");
            newAppWindow->m_isPopupWindow = true;
            newAppWindow->m_onWebViewFirstInitialized = [args, deferral, newAppWindow]() {
                CHECK_FAILURE(args->put_NewWindow(newAppWindow->m_webView.get()));
                CHECK_FAILURE(args->put_Handled(TRUE));
                CHECK_FAILURE(deferral->Complete());
            };

            return S_OK;
        })
        .Get(),
    nullptr));

ScenarioWebMessage (.html, .cpp и .h)

В ScenarioWebMessage файлах показано, как узел Win32 может изменять WebView, как WebView может изменять узел Win32 и как WebView может изменять себя, используя доступ к информации из узла Win32. Это выполняется асинхронно.

Компонент ScenarioWebMessage создается при выборе пункта меню Сценарий>веб-сообщений . Компонент ScenarioWebMessage реализует пример приложения с частью C++ и частью HTML+JavaScript, которые взаимодействуют друг с другом, асинхронно публикуя и получая сообщения:

Веб-сообщения: публикация и получение сообщений

В следующих разделах показано, как работает каждая дискретная функция с помощью приложения WebView2APISample , а затем объясняется, как реализовать эту функцию.

Сначала перейдите к веб-приложению ScenarioWebMessage в примере приложения:

  1. Откройте (запустите) приложение WebView2APISample .

  2. В меню Сценарий выберите Веб-обмен сообщениями.

    WebView отображает веб-страницу с именем Пример страницы WebMessage (ScenarioWebMessage.html):

    Веб-обмен сообщениями для публикации и получения сообщений

Чтобы изучить эту функцию ScenarioWebMessage , следуйте инструкциям на странице или выполните указанные ниже действия.

Публикация сообщений с узла Win32 в WebView

Ниже показано, как узел Win32 может изменять WebView. В этом примере вы повернете текст синим цветом:

  1. Откройте страницу примера WebMessage (ScenarioWebMessage.html), как описано выше.

  2. В меню Скрипт выберите Post Web Message JSON.

    Откроется диалоговое окно с предварительно написанным кодом {"SetColor":"blue"} .

  3. Нажмите кнопку OK.

    Текст в разделе Публикация сообщений на странице изменится с черного на синий.

Принципы действия
  1. В ScriptComponent.cppвызов PostWebMessageAsJson отправляет входные данные пользователя в ScenarioMessage.html веб-приложение:

    // Prompt the user for some JSON and then post it as a web message.
    void ScriptComponent::SendJsonWebMessage()
    {
       TextInputDialog dialog(
          m_appWindow->GetMainWindow(),
          L"Post Web Message JSON",
          L"Web message JSON:",
          L"Enter the web message as JSON.",
          L"{\"SetColor\":\"blue\"}");
       if (dialog.confirmed)
       {
          m_webView->PostWebMessageAsJson(dialog.input.c_str());
       }
    }
    
  2. В веб-приложении прослушиватели событий используются для получения веб-сообщения и реагирования на него. Приведенный ниже фрагмент кода находится из ScenarioWebMessage.html. Прослушиватель событий изменяет цвет текста, если аргумент имеет значение SetColor:

    window.chrome.webview.addEventListener('message', arg => {
       if ("SetColor" in arg.data) {
          document.getElementById("colorable").style.color = arg.data.SetColor;
       }
    });
    

Получение сообщений (из WebView на узел Win32)

Ниже показано, как WebView может изменить ведущее приложение Win32, изменив название приложения Win32.

  1. Откройте страницу примера WebMessage (ScenarioWebMessage.html), как описано выше.

  2. Обратите внимание на название приложения WebView2APISample , которое отображается в левом верхнем углу окна рядом со значком. Изначально это WebView2APISample — Microsoft Edge WebView2.

  3. В разделе Получение сообщений на странице введите новое название и нажмите кнопку Отправить .

  4. Обратите внимание на новый заголовок, отображаемый в строке заголовка приложения WebView2APISample .

Принципы действия
  1. В ScenarioWebMessage.htmlwindow.chrome.webview.postMessage() отправляет входные данные пользователя в ведущее приложение:

    function SetTitleText() {
       let titleText = document.getElementById("title-text");
       window.chrome.webview.postMessage(`SetTitleText ${titleText.value}`);
    }
    
  2. В ScenarioWebMessage.cppиспользуется add_WebMessageReceived для регистрации обработчика событий. При получении события после проверки входных данных мы изменяем заголовок окна приложения (m_appWindow):

    // Setup the web message received event handler before navigating to
    // ensure we don't miss any messages.
    CHECK_FAILURE(m_webview->add_WebMessageReceived(
       Microsoft::WRL::Callback<ICoreWebView2WebMessageReceivedEventHandler>(
          [this](ICoreWebView2* sender, ICoreWebView2WebMessageReceivedEventArgs* args)
    {
       wil::unique_cotaskmem_string uri;
       CHECK_FAILURE(args->get_Source(&uri));
    
       // Always validate that the origin of the message is what you expect.
       if (uri.get() != m_sampleUri)
       {
          return S_OK;
       }
       wil::unique_cotaskmem_string messageRaw;
       CHECK_FAILURE(args->TryGetWebMessageAsString(&messageRaw));
       std::wstring message = messageRaw.get();
    
       if (message.compare(0, 13, L"SetTitleText ") == 0)
       {
          m_appWindow->SetTitleText(message.substr(13).c_str());
       }
       return S_OK;
    }).Get(), &m_webMessageReceivedToken));
    

Сообщения кругового пути (от WebView к узлу обратно в WebView)

Ниже показано, как WebView может получать сведения из узла Win32 и изменять себя, отображая размер приложения Win32.

  1. Откройте страницу примера WebMessage (ScenarioWebMessage.html), как описано выше.

  2. В разделе Круговой путь страницы нажмите кнопку GetWindowBounds .

    В текстовом поле под кнопкой отображаются границы для приложения WebView2APISample .

Принципы действия
  1. При нажатии GetWindowBoundsкнопки Получить границы окна вызывается функция в ScenarioWebMessage.html . GetWindowBounds вызывает window.chrome.webview.postMessage() для отправки сообщения в ведущему приложению:

    function GetWindowBounds() {
        window.chrome.webview.postMessage("GetWindowBounds");
    }
    
  2. В ScenarioWebMessage.cppмы используем add_WebMessageReceived для регистрации полученного обработчика событий. После проверки входных данных обработчик событий получает границы окна из окна приложения. PostWebMessageAsJson отправляет границы в веб-приложение:

    if (message.compare(L"GetWindowBounds") == 0)
    {
       RECT bounds = m_appWindow->GetWindowBounds();
       std::wstring reply =
          L"{\"WindowBounds\":\"Left:" + std::to_wstring(bounds.left)
          + L"\\nTop:" + std::to_wstring(bounds.top)
          + L"\\nRight:" + std::to_wstring(bounds.right)
          + L"\\nBottom:" + std::to_wstring(bounds.bottom)
          + L"\"}";
       CHECK_FAILURE(sender->PostWebMessageAsJson(reply.c_str()));
    }
    
  3. В ScenarioWebMessage.htmlпрослушиватель событий отвечает на WindowBounds сообщение и отображает границы окна:

    window.chrome.webview.addEventListener('message', arg => {
       if ("WindowBounds" in arg.data) {
          document.getElementById("window-bounds").value = arg.data.WindowBounds;
       }
    });
    

См. также