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


Взаимодействие собственного и веб-кода

Элемент управления Microsoft Edge WebView2 позволяет внедрять веб-содержимое в собственные приложения. WebView2 можно использовать разными способами в зависимости от того, что вам нужно сделать. В этой статье описывается взаимодействие с использованием простых сообщений, кода JavaScript и собственных объектов.

Ниже приведены некоторые распространенные варианты использования:

  • Обновите заголовок окна собственного узла после перехода на другой веб-сайт.
  • Отправьте собственный объект камеры и используйте его методы из веб-приложения.
  • Запустите выделенный файл JavaScript на веб-стороне приложения.

Подготовка к работе

В этом руководстве описывается пример кода приложения, чтобы продемонстрировать некоторые возможности взаимодействия в WebView2. Клонируйте репозиторий WebView2Samples, откройте .sln файл в Visual Studio, выполните сборку проекта и запустите (отладка), чтобы выполнить действия, описанные в этой статье.

Подробные инструкции по клонировании репозитория см. в разделе Примеры WebView2.

Сценарий: простой обмен сообщениями

Элементы управления WebView2 позволяют обмениваться простыми сообщениями между веб-и собственными сторонами приложения. Для отправки сообщений между ведущим приложением и WebView2 можно использовать такие типы данных, как JSON или String .

Отправка сообщений из ведущего приложения в WebView2

В этом примере показано, как пример приложения изменяет цвет текста во интерфейсе на основе сообщения от ведущего приложения.

Чтобы увидеть обмен сообщениями в действии:

  1. Запустите пример приложения, затем перейдите на вкладку Сценарий и выберите параметр Веб-сообщения .

    Появится следующий экран:

    Пример страницы веб-сообщений, на которой демонстрируется базовое взаимодействие между ведущим приложением и экземпляром WebView2 с помощью веб-сообщений

  2. Обратите внимание на первый раздел под названием Posting Messages. Следуйте инструкциям и выберите Скрипт>post Message JSON. Нажмите кнопку ОК. Сообщение становится синим:

    Демонстрация

    Как нам удалось изменить цвет текста? Пример начинается с создания кнопки на собственной стороне. Затем пример добавляет следующий код для публикации веб-сообщения при нажатии кнопки. Этот код изменяет цвет веб-текста на синий.

    Пример включает код C++, который создает кнопку Windows, которая вызывает SendJsonWebMessage() при нажатии кнопки.

    Дополнительные сведения о создании кнопки в C++ см. в разделе Создание кнопки.

  3. При нажатии кнопки вызывается следующий код из ScriptComponent.cpp.

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

    Примечание.

    В остальной части этого руководства используется файл ScenarioWebMessage.html из примера WebView2. Сравните собственный HTML-файл по мере работы или скопируйте и вставьте содержимое изScenarioWebMessage.html.

    В примере используется прослушиватель событий JavaScript в Интернете.

  4. ScenarioWebMessage.html в заголовке содержится следующий Код JavaScript:

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

    Прослушиватель событий прослушивает событие сообщения и делает текст сообщения цветным.

  5. HTML-файл описывает упражнение по обмену сообщениями:

    <h1>WebMessage sample page</h1>
    <p>This page demonstrates basic interaction between the host app 
    and the webview by means of Web Messages.</p>
    
    <h2>Posting Messages</h2>
    <p id="colorable">Messages can be posted from the host app to the 
    webview using the functions
    <code>ICoreWebView2::PostWebMessageAsJson</code> and
    <code>ICoreWebView2::PostWebMessageAsString</code>. Try selecting 
    the menu item "Script > Post Message JSON" to send the message 
    <code>{"SetColor":"blue"}</code>.
    It should change the text color of this paragraph.</p>
    
  6. Элемент Post Message JSON меню находится в Microsoft Visual C++ созданном файле скрипта ресурса WebView2APISample.rc.

    MENUITEM "Post Message JSON",           IDM_POST_WEB_MESSAGE_JSON
    
  7. Файл скрипта, в свою очередь, вызывает дело IDM_POST_WEB_MESSAGE_JSON в ScriptComponent.cpp.

    case IDM_POST_WEB_MESSAGE_JSON:
       SendJsonWebMessage();
       return true;
    

Это завершает пример, показывающий, как WebView2 взаимодействует с помощью простых сообщений.

Получение строк сообщений через postMessage

Этот пример следует разделу Receiving Messages веб-страницы, чтобы изменить текст строки заголовка. Ведущее приложение получает сообщение от WebView2 с новым текстом заголовка.

Файл C++ обрабатывает текст заголовка и передает его ведущему приложению в виде строки.

  1. При нажатии кнопки WebView2 передает сообщение с веб-страницы в собственное приложение, используя window.chrome.webview.postMessage в ScenarioWebMessage.html.

    function SetTitleText() {
       let titleText = document.getElementById("title-text");
       window.chrome.webview.postMessage(`SetTitleText ${titleText.value}`);
    }
    
  2. HTML-файл содержит текстовое поле и кнопку для отправки сообщения в ведущему приложению:

    <h2>Receiving Messages</h2>
    <p>The host app can receive messages by registering an event handler 
    with <code>ICoreWebView2::add_WebMessageReceived</code>. If you 
    enter text and click "Send", this page will send a message to the 
    host app which will change the text of the title bar.</p>
    <input type="text" id="title-text"/>
    <button onclick="SetTitleText()">Send</button>
    
  3. Обработчик событий в ScenarioWebMessage.cpp обрабатывает новую текстовую строку заголовка и передает ее в ведущему приложению в виде строки.

    // 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());
       }
       else 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()));
       }
       return S_OK;
    }).Get(), &m_webMessageReceivedToken));
    

Сообщения кругового пути

Этот пример следует за разделом <h2>Round trip</h2> примера страницы WebMessage ,ScenarioWebMessage.html. В этом примере показано сообщение о круговом пути из WebView2 в ведущее приложение и обратно. Ведущее приложение получает запрос от WebView2 и возвращает границы активного окна.

По запросу ведущего приложения файл C++ получает границы окна и отправляет данные в WebView2 в виде веб-сообщения JSON.

  1. HTML-файл содержит кнопку для получения границ окон из ведущего приложения:

    <h2>Round trip</h2>
    <p>The host app can send messages back in response to received 
    messages. If you click the <b>Get window bounds</b> button, the 
    host app reports back the bounds of its window, which are 
    displayed in the text box.</p>
    <button onclick="GetWindowBounds()">Get window bounds</button><br>
    <textarea id="window-bounds" rows="4" readonly></textarea>
    
  2. Когда пользователь нажимает кнопку, WebView2 передает сообщение с веб-страницы в собственное приложение с помощью window.chrome.webview.postMessage.

    function GetWindowBounds() {
       window.chrome.webview.postMessage("GetWindowBounds");
    }
    
  3. Обработчик событий в ScenarioWebMessage.cpp получает границы окна и отправляет данные в ведущее приложение с помощью TryGetWebMessageAsString:

    // 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());
       }
       else 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()));
       }
       return S_OK;
    }).Get(), &m_webMessageReceivedToken));
    

    Границы окна отображаются на веб-странице.

Сценарий: отправка кода JavaScript

В этом сценарии показано, как запустить JavaScript на веб-стороне. В этом подходе ведущее приложение указывает код JavaScript для выполнения и передает его в Интернет через ExecuteScriptAsync. Функция ExecuteScriptAsync возвращает результат JavaScript обратно вызывающей стороне ExecuteScript .

Дополнительные сведения см. в статье Использование JavaScript в WebView2 (запуск JavaScript из машинного кода).

Сценарий. Отправка собственных объектов

Передайте собственный объект в Интернет. Затем вызовите методы объекта из Интернета.

Чтобы использовать сообщения, представляющие вызовы методов, используйте AddHostObjectToScript API. На высоком уровне этот API позволяет предоставлять собственные объекты (host) на веб-стороне и выступать в качестве прокси-сервера. Доступ к этим объектам с помощью window.chrome.webview.hostObjects.{name}.

Передача собственного объекта на веб-сторону приложения описана в разделе AddHostObjectToScriptинтерфейса ICoreWebView2.

Поздравляем! Вы успешно встроили веб-содержимое в собственные приложения.

См. также