我们可以在JS中,通过postMessage方法向C++发送消息,代码如下
window.chrome.webview.postMessage(window.document.URL)
C++中要想接收消息,必须注册一个WebMessageReceived事件,
在WebView2控件成功添加到窗口上时,我们就可以注册事件了,代码如下:
EventRegistrationToken token;
auto messageReceivedCB = Callback<ICoreWebView2WebMessageReceivedEventHandler>(this, &Win::messageReceived);
webview->add_WebMessageReceived(messageReceivedCB.Get(), &token);
这个事件的回调方法如下:
HRESULT Win::messageReceived(ICoreWebView2* webview, ICoreWebView2WebMessageReceivedEventArgs* args)
{
wil::unique_cotaskmem_string messageRaw;
args->TryGetWebMessageAsString(&messageRaw);
std::wstring message = messageRaw.get();
return S_OK;
}
现在你可以在HTML页面中写下本文最开始时提到的那句JS代码,运行程序,就会发现回调方法得到了当前页面的URL,如下图所示:
我们也可以在WebView2控件成功添加到窗口上时,给页面注入一段JS代码,如下所示:
std::wstring script = L"window.chrome.webview.postMessage(window.document.URL);console.log(456);";
hr = webview->AddScriptToExecuteOnDocumentCreated(script.c_str(), nullptr);
这段JS脚本并不会马上执行,而是要等到页面成功加载之后才会执行。
当然,我们也可以在C++这边向JavaScript那边发送消息
C++代码如下:
webview->PostWebMessageAsString(L"allen");
JavaScript接收消息的代码如下:
window.chrome.webview.addEventListener("message", (e) => {
console.log(e);
})
打印出来的内容是:
在上面的代码中,我们都是用字符串传递数据的,也可以用JSON传递数据:
webview->PostWebMessageAsJson(L"{\"name\":123 }");
注意:传递的JSON必须是符合格式要求的,不然JavaScript接不到这个消息。
前面JavaScript发送消息给C++也可以传递JSON数据。C++只要使用get_WebMessageAsJson方法即可。
wil::unique_cotaskmem_string messageRaw;
args->get_WebMessageAsJson(&messageRaw);
std::wstring message = messageRaw.get();
下面是发送消息的JS代码:
window.chrome.webview.postMessage({ name :1234 })
结果如下图所示:
这里得到的JSON也是字符串,要想序列化,就用咱们前面文章提到过的RappidJSON序列化即可。