Partilhar via


Interop of native-side and web-side code (Interop of native-side and web-side code)

O controlo WebView2 do Microsoft Edge permite-lhe incorporar conteúdo Web em aplicações nativas. Pode utilizar o WebView2 de formas diferentes, consoante o que precisa de realizar. Este artigo descreve como comunicar com mensagens simples, código JavaScript e objetos nativos.

Alguns casos de utilização comuns incluem:

  • Atualize o título da janela do anfitrião nativo depois de navegar para um site diferente.
  • Envie um objeto de câmara nativo e utilize os respetivos métodos a partir de uma aplicação Web.
  • Execute um ficheiro JavaScript dedicado no lado Web de uma aplicação.

Antes de começar

Este tutorial explica o código da Aplicação de Exemplo para demonstrar algumas das capacidades de comunicação no WebView2. Clone o repositório WebView2Samples, abra um .sln ficheiro no Visual Studio, crie o projeto e execute (depuração) para acompanhar os passos neste artigo.

Para obter os passos detalhados sobre a clonagem do repositório, veja Exemplos do WebView2.

Cenário: Mensagens simples

Os controlos WebView2 permitem-lhe trocar mensagens simples entre os lados Web e nativo de uma aplicação. Pode utilizar tipos de dados como JSON ou String para enviar mensagens entre a aplicação anfitriã e o WebView2.

Enviar mensagens da aplicação anfitriã para o WebView2

Este exemplo mostra como a aplicação de exemplo altera a cor do texto no front-end, com base numa mensagem da aplicação anfitriã.

Para ver mensagens em ação:

  1. Execute a aplicação de exemplo e, em seguida, selecione o separador Cenário e selecione a opção Mensagens Web .

    É apresentado o ecrã seguinte:

    A página de exemplo de Mensagens Web, que demonstra a interação básica entre a aplicação anfitriã e a instância webView2 através de Mensagens Web

  2. Repare na primeira secçã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 por criar um botão, no lado nativo. Em seguida, o exemplo adiciona o seguinte código para publicar a mensagem Web quando o botão é clicado. Este código altera a cor do texto web para azul.

    O exemplo inclui código C++ para criar um botão do Windows que chama 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, 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 resto deste tutorial utiliza o ficheiro do exemplo ScenarioWebMessage.html WebView2. Compare o seu próprio ficheiro HTML à medida que trabalha ou copie e cole o conteúdo de ScenarioWebMessage.html.

    O exemplo utiliza um serviço de escuta 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 serviço de escuta de eventos escuta um evento de mensagem e torna o texto da mensagem colorível.

  5. O ficheiro 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á na Microsoft Visual C++ ficheiro de script de recurso gerado WebView2APISample.rc.

    MENUITEM "Post Message JSON",           IDM_POST_WEB_MESSAGE_JSON
    
  7. O ficheiro 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;
    

Isto conclui o exemplo que mostra como o WebView2 comunica através de mensagens simples.

Receber cadeias de mensagens através de postMessage

Este exemplo segue a Receiving Messages secção da página Web para alterar o texto da barra de título. A aplicação anfitriã recebe uma mensagem do WebView2 com o novo texto da barra de título.

O ficheiro C++ processa o texto do título e comunica-o à aplicação anfitriã como uma cadeia.

  1. Quando o botão é clicado, o WebView2 transmite uma mensagem da página Web para a aplicação nativa que utiliza window.chrome.webview.postMessage no ScenarioWebMessage.html.

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

    <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 processador de eventos no ScenarioWebMessage.cpp processa a nova cadeia de texto de título e comunica-a à aplicação anfitriã como uma cadeia.

    // 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> secção da página de exemplo WebMessage ,ScenarioWebMessage.html. Este exemplo mostra uma mensagem de ida e volta de WebView2 para a aplicação anfitriã e para trás. A aplicação anfitriã recebe um pedido do WebView2 e devolve os limites da janela ativa.

Quando solicitado pela aplicação anfitriã, o ficheiro C++ obtém os limites da janela e envia os dados para o WebView2 como uma mensagem Web JSON.

  1. O ficheiro HTML inclui um botão para obter limites de janela da aplicação anfitriã:

    <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 utilizador clica no botão, o WebView2 transmite uma mensagem da página Web para a aplicação nativa com window.chrome.webview.postMessage.

    function GetWindowBounds() {
       window.chrome.webview.postMessage("GetWindowBounds");
    }
    
  3. O processador de eventos no ScenarioWebMessage.cpp obtém os limites da janela e envia os dados para a aplicação anfitriã com 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 apresentados na página Web.

Cenário: Enviar código JavaScript

Este cenário mostra como executar JavaScript no lado da Web. Nesta abordagem, a aplicação anfitriã especifica o código JavaScript a executar e transmite o código para a Web através de ExecuteScriptAsync. A ExecuteScriptAsync função devolve o resultado de JavaScript ao ExecuteScript chamador.

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

Cenário: Enviar objetos nativos

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

Para utilizar mensagens que representam chamadas de método, utilize a AddHostObjectToScript API. A um nível elevado, esta API permite-lhe expor objetos nativos (anfitriões) no lado da Web e atuar como um proxy. Aceda a estes objetos com window.chrome.webview.hostObjects.{name}.

A transmissão de um objeto nativo para o lado Web de uma aplicação é descrita na secção AddHostObjectToScript da interface ICoreWebView2.

Parabéns! Incorporou com êxito conteúdo Web em aplicações nativas.

Confira também