internet-explorer - IWebBrowser2 Ctrl+C等快捷键支持

标签 internet-explorer winapi hook wtl iwebbrowser2

看来我遇到了一个不小的问题。

我将自己的窗口挂接到 IE 主窗口。我的窗口派生自 WTL 的 CWindowImpl 并承载 IWebBrowers2 控件,它显示一些内容。

IWebBrowser2 显示带有 <input type='text'/> 的 html我需要支持所有键的编辑框,这是编辑和操作文本所必需的(Ctrl + C、Ctrl + V、Ctrl + X 等...+ Esc、Delete、向上和向下箭头)。

我还需要禁用一些快捷方式,例如 Ctrl + P、Ctrl + S,因为它们会调用我不需要的特定于网页的对话框。


似乎是常见问题,我需要为我的 IWebBrowser2 对象调用 TranslateAccelerator。

网上有一些类似的问题- Tab key doesn't work in IWebbrowser2

解决方案 – hot key not work!!

Tab key support in an IWebBrowser2 control

这是一个非常有趣的线程,我需要的都是 – Handling Control-C in a hosted web browser control


因此,首先我需要为我的 IWebBrowser2 对象调用 TranslateAccelerator。但我必须先从键盘获取消息。

那么,让我们看看它的外观。

enter image description here

我的钩子(Hook)窗口没有收到任何键盘输入消息。带有“Internet Explorer_Server”类的窗口接收所有这些(实际上,它是 IWebBrowser2 中的 IE 的一个 hwnd)。

所以我需要 Hook 这个 hwnd 的窗口过程。

m_ieOldProc = (PROC)::SetWindowLongPtr ( hIEWnd, GWLP_WNDPROC, (LONG_PTR)_IEWndProc );

在 hooked wnd proc 中,我执行以下操作:

// ...
switch ( uMsg )
{
    case WM_KEYUP: 
    case WM_KEYDOWN: 
    {
        // ...
        IOleInPlaceActiveObject* pAccelerator;
        CComPtr< IWebBrowser2 > pWebBrowser =  CWebWindow::GetWebBrowser( hwnd );
        if( pWebBrowser )
        {               
            hr = pWebBrowser->QueryInterface( IID_IOleInPlaceActiveObject,(void**)&pAccelerator );
            if ( SUCCEEDED(hr) )
            {
                pAccelerator->TranslateAccelerator(&msg);
                pAccelerator->Release();
            }           
        }
        // ...
    }
}
// ...

是的!有些事情得到了工作! Esc、Delete、向上和向下箭头键现在可以使用。

但不是全部。快捷方式有问题。

  1. Ctrl + C、Ctrl + A 不起作用。

Ctrl + X、Ctrl + V - 工作。

这里是 Spy++ 中的消息日志,用于类为“Internet Explorer_Server”的 hwnd。

在 Ctrl + C 上我没有收到 WM_COMMAND。

enter image description here

在 Ctrl + X 上:

enter image description here

我也不知道为什么。

2。 “坏”的捷径确实有效。 打印对话框调用 Ctrl + P,网页保存对话框调用 Ctrl + S,等等。 在这种情况下我无能为力。无论我在 hooked window proc 中返回什么,它们仍在显示。 所以我需要在发送到窗口之前处理它们。


解决方案?

你可以提到在这个问题的所有解决方案中有:

  1. 预翻译消息
  2. 实际上是 TranslateAccelerator

直到这一刻,我在 Hook 的消息过程中只有 TranslateAccelerator。

Pretranslate 必须做类似的事情:

BOOL PreTranslateMessage(MSG* pMsg)
{
    if((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) &&
        (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST))
        return FALSE;

    // give HTML page a chance to translate this message
    return (BOOL)SendMessage(WM_FORWARDMSG, 0, (LPARAM)pMsg);
}

此外,在 PreTranslateMessage 中,我可以过滤“不良”快捷方式并且不将它们发送到窗口。

另一个人建议也使用 PretranslateMessage(来自上面线程的对话):

– Derive your window from CMessageFilter, install it with CMessageLoop::AddMessageFilter, implement PreTranslateMessage as shown in the example.

– I think I've done now what the sample suggests. But the problem is that my 'parent' window doesn't get the keystrokes - they all go to the IE AX control.

– That's why you need CMessageFilter. It gets hooked into the message pump, before message are dispatched to their destination windows.

好的,但是承载 IWebBrowser2 的根窗口没有收到任何键盘消息。 此外,我的窗口中没有 PreTranslateMessage,只有窗口过程调用(由父 CWindowImpl 调用)。

如上所述,我可以从 CMessageFilter 派生,实现 PreTranslateMessage,但我无法使用 CMessageLoop::AddMessageFilter 订阅事件,因为我没有创建主窗口并且无权访问它的 CMessageLoop。


那么我现在应该怎么做才能使所有这些工作正常进行? 我应该使用 PreTranslateMessage 吗?如何使用?

最佳答案

最近我也遇到了复制/剪切命令不起作用的问题。结果证明这不是 TranslateAccelerator 或类似软件中的键盘问题。问题是 COM 库是使用 CoInitialize/CoInitializeEx 初始化的。但是需要调用 OleInitialize 而不是剪贴板才能工作。 MSDN“WebBrowser Customization”页面上有解释:

Your application should use OleInitialize rather than CoInitialize to start COM. OleInitialize enables support for the Clipboard, drag-and-drop operations, OLE, and in-place activation. Use OleUninitialize to close the COM library when your application shuts down.

http://msdn.microsoft.com/en-us/library/aa770041(v=vs.85).aspx

如果还是不行,请看一下我在 PHP 桌面项目中对 IWebBrowser2 控件的实现(C API):

https://code.google.com/p/phpdesktop/source/browse/phpdesktop-msie/msie/

关于internet-explorer - IWebBrowser2 Ctrl+C等快捷键支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20638950/

相关文章:

html - Bootstrap 3 按钮在 IE11 中不起作用

c - MD5 Crypto API 为某些明文返回不正确的散列

git - 编写拒绝无效子模块提交的 git update hook 的最佳方法是什么?

.net - 简单的 API Hook 来防止文件删除?

c - 在 Linux 中使用 LD_PRELOAD Hook strcmp?

javascript - VML 是否具有与 SVG 的标记元素等效的元素?

html - 在 mozilla 中为内容添加了额外的填充

c - Windows - 程序使用了多少内存没有意义

windows - 使用 NtQueryObject 获取注册表路径

internet-explorer - Font Awesome 图标在浏览器刷新后消失