簡體   English   中英

如何在 C++ COM STA 中的 WebView2 接口上等待對 ExecuteScript 的調用完成

[英]How to wait for completion of a call to ExecuteScript on a WebView2 interface in a C++ COM STA

我有一個 COM STA,它承載一個 ICoreWebView2。

我嘗試獲取完整的 HTML 塊,並找到了一個文檔來使用腳本實現這一點。 這是我的代碼:

    hr = m_spWebView->ExecuteScript(L"document.body.outerHTML",
        Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
            [&val](HRESULT hr, LPCWSTR result) -> HRESULT 
            {
                if (SUCCEEDED(hr))
                    val = result;
                return S_OK;
            }
        ).Get()
    );

此代碼有效,但它是異步執行的。 所以需要一些時間才能得到結果。 事實上,我可以看到結果在下次執行消息泵時到達(正如我對 STA 的期望)。

在 C# 中,我會使用 await 來等待完成。 但是使用 C++ 就沒有這樣的事情了。 使用事件是行不通的,因為我有一個 STA,我會阻塞線程並且答案永遠不會到達。

有沒有辦法在 C++ 中調用等待完成的函數? 或者另一個幫助是使用ExecuteScript同步。

你必須實現一個 IDispatch 接口(COM stuf),並添加它:

m_spWebView->AddHostObjectToScript(L"host", &disp);

然后在加載文檔時讓 JavaScript 調用它。

struct CDispatch : IDispatch
{
...
} cdisp;

您將獲得 HTML 作為 Invoke 調用中的參數。 其他方法不用管,只需要在QueryInterface中確認IID_IDispatch並注意Invoke。

 window.chrome.webview.hostObjects.host(document.body.outerHTML);

我在這里嘗試並設法做你願意做的事情。

如果您有一個 STA,那么您可以啟動您的消息循環或返回並允許您的消息循環繼續處理消息,而不是顯式等待完成。

如果您需要在不返回消息循環的情況下阻止執行和處理消息,您可以嘗試使用CoWaitForMultipleHandlesCOWAIT_DISPATCH_WINDOW_MESSAGES來確保您處理 WebView2 回調執行所必需的窗口消息。 但是,這可能會使您的應用程序面臨重入或其他同步問題,並且取決於您的應用程序的其余部分如何處理此問題,這可能是一個問題。

通常更好的解決方案是返回到您的消息循環。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM