【问题标题】:How to display Find dialog in a WebView2 control?如何在 WebView2 控件中显示查找对话框?
【发布时间】:2021-09-14 08:47:10
【问题描述】:

我已将旧的 C++ MFC 应用程序升级为使用基于 Edge 的 WebView2 Web 浏览器控件。否则我可以正常工作,剩下的问题之一是通过主 MFC 应用程序 Edit-Find 菜单项或通过 Ctrl+F(也被 MFC 框架拦截)在其中打开“查找”对话框。我现在拥有的是:

m_webView->ExecuteScript(L"window.find(\"\", 0, 0, 0, 0, 0, 1);");

其中m_webView 是指向ICoreWebView2 接口的指针。

问题在于,有时它确实会显示“查找”对话框,有时则不会。有时它会在页面刷新后执行,有时不会。当我从 cross 关闭“查找”对话框时,它通常会拒绝再次打开它。

我怎样才能让它正常运行?也许有一种方法不需要通过Javascript?

更新:它似乎只有在 Ctrl+F 击键以某种方式绕过 MFC 直接发送到 WebView2 控件时才有效。看起来上面的 Javascript 行从来没有工作过。那么或许有办法为WebView2控件模拟Ctrl+F?

【问题讨论】:

  • 听起来像是焦点控制问题 - MFC 中最后一次获得焦点的控件都是 Ctrl+F 序列。
  • 对,这主要是焦点问题,GotFocus 事件处理程序有时会将焦点从 webview2 控件上移开。似乎仍然没有办法让 Edit-Find 菜单项工作。是的,我知道菜单目前已经过时了……

标签: javascript c++ microsoft-edge webview2


【解决方案1】:

AFAIK,WebView2 目前不支持您调用或以其他方式控制在页面对话框中的查找。也可以参考this thread。 GitHub上有a similar thread,官方没有给出解决方案。

您可以在 WebView2 控件中直接使用 Ctrl+F 击键或在 WebView2 Feedback page 上提供有关此问题的反馈。感谢您的理解。

【讨论】:

    【解决方案2】:

    正如@yu-zhou 回答的那样,目前还没有官方方法可以做我想做的事。现在,我求助于以编程方式为 WebView2 控件模拟 Ctrl+F,但结果并不那么漂亮。为了记录,我仍然在这里展示它:

    首先,用户必须在 webview2 控件中至少单击一次,这样我就可以在 add_GotFocus() 注册的 GotFocus 事件处理程序中记录它的 HWND:

    void MyHtmlView::OnGotFocus() {
        if (!m_webview2_hwnd) {
            m_webview2_hwnd = ::GetFocus();
        }
    }
    

    现在,当我想以编程方式调出“查找”栏时,我需要确保正确的窗口聚焦并发送 Ctrl+F 键。唉,控件似乎以异步方式检查 Ctrl 键状态,所以它有点棘手,我需要更改线程的键盘状态并添加一个额外的事件处理程序以便之后恢复它。经过反复试验,我达到了这一点(为简洁起见,省略了错误检查):

    void MyHtmlView::Find() {
    
        if (::GetFocus()!=m_webview2_hwnd) {
            ::SetFocus(m_webview2_hwnd);
        }
    
        std::uint8_t state[256];
        ::GetKeyboardState(state);
        bool restoreCtrlState = false;
        if ((state[VK_CONTROL] & 0x80)==0) {
            // Ctrl key is currently not pressed.
            // Mark it pressed.
            state[VK_CONTROL] |= 0x80;
            ::SetKeyboardState(state);
            restoreCtrlState = true;
        }
    
        std::thread auxThread([this, restoreCtrlState]() {
            ::SendMessage(m_webview2_hwnd, WM_KEYDOWN, 'F', 1);
            ::SendMessage(m_webview2_hwnd, WM_KEYUP, 'F', 1);
            if (restoreCtrlState) {
                ::PostMessage(m_hWnd, WM_COMMAND, ID_RESTORE_CONTROL_STATE, 0);
            }
        });
        auxThread.detach();
    }
    
    // This needs to be registered to handle ID_RESTORE_CONTROL_STATE
    void HtmlView::OnRestoreCtrlState() {
        std::uint8_t state[256];
        ::GetKeyboardState(state);
        if ((state[VK_CONTROL] & 0x80)!=0) {
            state[VK_CONTROL] &= ~0x80;
            ::SetKeyboardState(state);
        }
    }
    

    不用说,如果他们更改 webview2 实现中的某些内容,这个 hack 可能很容易停止工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多