Interoperabilidade de código nativo e da Web

O controle Microsoft Edge WebView2 permite inserir conteúdo da Web em aplicativos nativos. Você pode usar o WebView2 de maneiras diferentes, dependendo do que você precisa realizar. Este artigo descreve como se comunicar usando mensagens simples, código JavaScript e objetos nativos.

Alguns casos de uso comuns incluem:

  • Atualize o título da janela do host nativo após navegar para um site diferente.
  • Envie um objeto de câmera nativo e use seus métodos em um aplicativo Web.
  • Execute um arquivo JavaScript dedicado no lado Web de um aplicativo.

Antes de começar

Este tutorial percorre o código do aplicativo de exemplo para demonstrar alguns dos recursos de comunicação no WebView2. Clone o repositório WebView2Samples, abra um .sln arquivo no Visual Studio, compile o projeto e execute (depurar) para seguir as etapas deste artigo.

Para obter etapas detalhadas sobre como clonar o repositório, consulte Aplicativos de exemplo WebView2.

Cenário: Sistema de mensagens simples

Os controles WebView2 permitem a troca de mensagens simples entre os lados Web e nativo de um aplicativo. Você pode usar tipos de dados como JSON ou String para enviar mensagens entre o aplicativo host e o WebView2.

Enviar mensagens do aplicativo host para o WebView2

Este exemplo mostra como o aplicativo de exemplo altera a cor do texto no front-end, com base em uma mensagem do aplicativo host.

Para ver as mensagens em ação:

  1. Execute o aplicativo de exemplo, selecione a guia Cenário e selecione a opção Web Messaging .

    A tela a seguir é exibida:

    A página de exemplo de Web Messaging, que demonstra a interação básica entre o aplicativo host e a instância de WebView2 usando mensagens da Web

  2. Observe a primeira seção, intitulada Posting Messages. Siga as instruções e selecione Script>Post Message JSON. Clique em OK. A mensagem fica azul:

    A demonstração

    Como conseguimos alterar a cor do texto? O exemplo começa criando um botão, no lado nativo. Em seguida, o exemplo adiciona o seguinte código para postar a mensagem da Web quando o botão é clicado. Este código altera a cor do texto da Web para azul.

    O exemplo inclui código C++ para criar um botão do Windows que é chamado SendJsonWebMessage() quando clicado.

    Para obter mais informações sobre como criar um botão em C++, consulte Como criar um botão.

  3. Quando o botão é clicado, ele chama o seguinte código de 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());
        }
    }
    

    Observação

    O restante deste tutorial usa o arquivo ScenarioWebMessage.html do exemplo WebView2. Compare seu próprio arquivo HTML enquanto trabalha ou copie e cole o conteúdo do ScenarioWebMessage.html.

    O exemplo usa um ouvinte de eventos JavaScript na Web.

  4. ScenarioWebMessage.html Inclui o seguinte JavaScript no cabeçalho:

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

    O ouvinte de eventos escuta um evento de mensagem e torna o texto da mensagem colorível.

  5. O arquivo HTML descreve o exercício de mensagens:

    <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. O Post Message JSON item de menu está no arquivo de script de recurso gerado pelo Microsoft Visual C++, WebView2APISample.rc.

    MENUITEM "Post Message JSON",           IDM_POST_WEB_MESSAGE_JSON
    
  7. O arquivo de script, por sua vez, chama o caso IDM_POST_WEB_MESSAGE_JSON em ScriptComponent.cpp.

    case IDM_POST_WEB_MESSAGE_JSON:
       SendJsonWebMessage();
       return true;
    

Isso completa o exemplo que mostra como o WebView2 se comunica por meio de mensagens simples.

Receber cadeias de caracteres de mensagem por meio de postMessage

Este exemplo segue a Receiving Messages seção da página da Web para alterar o texto da barra de título. O aplicativo host recebe uma mensagem do WebView2 com o novo texto da barra de título.

O arquivo C++ lida com o texto do título e o comunica ao aplicativo host como uma cadeia de caracteres.

  1. Quando o botão é clicado, o WebView2 transmite uma mensagem da página da Web para o aplicativo nativo usando window.chrome.webview.postMessage o ScenarioWebMessage.html.

    function SetTitleText() {
       let titleText = document.getElementById("title-text");
       window.chrome.webview.postMessage(`SetTitleText ${titleText.value}`);
    }
    
  2. O arquivo HTML inclui uma caixa de texto e um botão para enviar uma mensagem ao aplicativo host:

    <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. O manipulador de eventos no ScenarioWebMessage.cpp processa a nova cadeia de caracteres de texto do título e a comunica ao aplicativo host como uma cadeia de caracteres.

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

Mensagens de ida e volta

Este exemplo segue a <h2>Round trip</h2> seção da página de exemplo WebMessage, ScenarioWebMessage.html. Este exemplo mostra uma mensagem de ida e volta do WebView2 para o aplicativo host e vice-versa. O aplicativo host recebe uma solicitação do WebView2 e retorna os limites da janela ativa.

Quando solicitado pelo aplicativo host, o arquivo C++ obtém os limites da janela e envia os dados para o WebView2 como uma mensagem da Web JSON.

  1. O arquivo HTML inclui um botão para obter limites de janela do aplicativo host:

    <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. Quando o usuário clica no botão, o WebView2 transmite uma mensagem da página da Web para o aplicativo nativo usando window.chrome.webview.postMessage.

    function GetWindowBounds() {
       window.chrome.webview.postMessage("GetWindowBounds");
    }
    
  3. O manipulador de eventos no ScenarioWebMessage.cpp obtém os limites da janela e envia os dados para o aplicativo host usando 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));
    

    Os limites da janela são exibidos na página da Web.

Cenário: Enviar código JavaScript

Este cenário mostra como executar o JavaScript no lado da Web. Nessa abordagem, o aplicativo host especifica o código JavaScript a ser executado e passa o código para a Web por meio do ExecuteScriptAsync. A ExecuteScriptAsync função retorna o resultado do JavaScript de volta para o ExecuteScript chamador.

Para obter mais informações, consulte Usar JavaScript no WebView2 (Executar JavaScript a partir de código nativo).

Cenário: Enviar objetos nativos

Passe o objeto nativo para a Web. Em seguida, chame os métodos do objeto na Web.

Para usar mensagens que representam chamadas de método, use a AddHostObjectToScript API. Em um alto nível, essa API permite expor objetos nativos (host) no lado da Web e atuar como um proxy. Acesse esses objetos usando o window.chrome.webview.hostObjects.{name}.

Passar um objeto nativo para o lado da Web de um aplicativo é descrito na seção AddHostObjectToScript da interface ICoreWebView2.

Parabéns! Você inseriu com sucesso conteúdo da Web em aplicativos nativos.

Confira também