ネイティブ側と Web 側のコードの相互運用
Microsoft Edge WebView2 コントロールを使用すると、Web コンテンツをネイティブ アプリケーションに埋め込むことができます。 WebView2 は、実行する必要がある内容に応じて、さまざまな方法で使用できます。 この記事では、単純なメッセージ、JavaScript コード、ネイティブ オブジェクトを使用して通信する方法について説明します。
一般的なユース ケースには、次のようなものがあります。
- 別の Web サイトに移動した後、ネイティブ ホスト ウィンドウのタイトルを更新します。
- ネイティブ カメラ オブジェクトを送信し、Web アプリからそのメソッドを使用します。
- アプリケーションの Web 側で専用の JavaScript ファイルを実行します。
開始する前に
このチュートリアルでは、サンプル アプリ コードを実行して、WebView2 の通信機能の一部を示します。
WebView2Samples リポジトリを複製し、Visual Studio で.sln
ファイルを開き、プロジェクトをビルドし、実行 (デバッグ) して、この記事の手順に従います。
リポジトリの複製の詳細な手順については、「 WebView2 サンプル」を参照してください。
シナリオ: 単純なメッセージング
WebView2 コントロールを使用すると、アプリケーションの Web 側とネイティブ側の間で単純なメッセージを交換できます。
JSON
やString
などのデータ型を使用して、ホスト アプリケーションと WebView2 の間でメッセージを送信できます。
ホスト アプリから WebView2 にメッセージを送信する
この例では、ホスト アプリからのメッセージに基づいて、サンプル アプリがフロントエンドのテキストの色を変更する方法を示します。
メッセージングの動作を確認するには:
サンプル アプリを実行し、[ シナリオ ] タブを選択し、[ Web メッセージング ] オプションを選択します。
次の画面が表示されます。
「
Posting Messages
」というタイトルの最初のセクションに注目してください。 指示に従い、[ スクリプト>Post Message JSON] を選択します。 次に、[ OK] をクリックします。 メッセージが青に変わります。テキストの色を変更するにはどうすればよいですか? サンプルは、ネイティブ側でボタンを作成することから始めます。 次に、このサンプルでは、ボタンがクリックされたときに Web メッセージを投稿する次のコードを追加します。 このコードは、Web テキストの色を青に変更します。
この例には、クリックされたときに
SendJsonWebMessage()
を呼び出す Windows ボタンを作成する C++ コードが含まれています。C++ でボタンを作成する方法の詳細については、「 ボタンを作成する方法」を参照してください。
ボタンをクリックすると、 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()); } }
注:
このチュートリアルの残りの部分では、WebView2 サンプルから
ScenarioWebMessage.html
ファイルを使用します。 作業中に独自の HTML ファイルを比較するか、 ScenarioWebMessage.htmlからコンテンツ をコピーして貼り付けます。この例では、Web 上で JavaScript イベント リスナーを使用します。
ScenarioWebMessage.html
ヘッダーには次の JavaScript が含まれています。window.chrome.webview.addEventListener('message', arg => { if ("SetColor" in arg.data) { document.getElementById("colorable").style.color = arg.data.SetColor; } });
イベント リスナーは メッセージ イベントをリッスン し、メッセージ テキストを色付けできるようにします。
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>
Post Message JSON
メニュー項目は、Microsoft Visual C++生成されたリソース スクリプト ファイル WebView2APISample.rc にあります。MENUITEM "Post Message JSON", IDM_POST_WEB_MESSAGE_JSON
スクリプト ファイルは、ScriptComponent.cppでケース
IDM_POST_WEB_MESSAGE_JSON
を呼び出します。case IDM_POST_WEB_MESSAGE_JSON: SendJsonWebMessage(); return true;
これにより、WebView2 が単純なメッセージを介して通信する方法を示す例が完成します。
postMessage を使用してメッセージ文字列を受信する
次の使用例は、Web ページの Receiving Messages
セクションに従って、タイトル バーのテキストを変更します。 ホスト アプリは、WebView2 から新しいタイトル バー テキストを含むメッセージを受信します。
C++ ファイルはタイトル テキストを処理し、それを文字列としてホスト アプリに伝えます。
ボタンがクリックされると、WebView2 は、 の
window.chrome.webview.postMessage
を使用して Web ページからネイティブ アプリケーションにメッセージ ScenarioWebMessage.html送信します。function SetTitleText() { let titleText = document.getElementById("title-text"); window.chrome.webview.postMessage(`SetTitleText ${titleText.value}`); }
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>
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));
ラウンドトリップ メッセージ
この例は、WebMessage サンプル ページの <h2>Round trip</h2>
セクションに従 ScenarioWebMessage.html。 この例では、WebView2 からホスト アプリに戻るラウンドトリップ メッセージを示します。 ホスト アプリは WebView2 から要求を受け取り、アクティブ ウィンドウの境界を返します。
ホスト アプリによって要求されると、C++ ファイルはウィンドウの境界を取得し、JSON Web メッセージとして WebView2 にデータを送信します。
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>
ユーザーがボタンをクリックすると、WebView2 は、
window.chrome.webview.postMessage
を使用して Web ページからネイティブ アプリケーションにメッセージを送信します。function GetWindowBounds() { window.chrome.webview.postMessage("GetWindowBounds"); }
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));
ウィンドウの境界が Web ページに表示されます。
シナリオ: JavaScript コードを送信する
このシナリオでは、Web 側で JavaScript を実行する方法を示します。 この方法では、ホスト アプリは実行する JavaScript コードを指定し、 ExecuteScriptAsync
を介してコードを Web に渡します。
ExecuteScriptAsync
関数は、JavaScript の結果をExecuteScript
呼び出し元に返します。
詳細については、「 WebView2 で JavaScript を使用する (ネイティブ コードから JavaScript を実行する)」を参照してください。
シナリオ: ネイティブ オブジェクトを送信する
ネイティブ オブジェクトを Web に渡します。 次に、Web から オブジェクトのメソッドを呼び出します。
メソッド呼び出しを表すメッセージを使用するには、 AddHostObjectToScript
API を使用します。 大まかに言うと、この API を使用すると、ネイティブ (ホスト) オブジェクトを Web 側に公開し、プロキシとして機能できます。
window.chrome.webview.hostObjects.{name}
を使用してこれらのオブジェクトにアクセスします。
アプリケーションの Web 側にネイティブ オブジェクトを渡す方法については、インターフェイス ICoreWebView2 の AddHostObjectToScript セクションを参照してください。
おめでとうございます! Web コンテンツがネイティブ アプリケーションに正常に埋め込まれています。
関連項目
- WebView2 の機能と API の概要に関するページの Web/ネイティブ相互運用。