Internet explorer IWebBrowser2 Ctrl+;C和其他快捷方式支持

Internet explorer IWebBrowser2 Ctrl+;C和其他快捷方式支持,internet-explorer,winapi,hook,wtl,iwebbrowser2,Internet Explorer,Winapi,Hook,Wtl,Iwebbrowser2,看来我没有一个小问题 我把自己的窗户挂在主窗户上。我的窗口来自WTL的CWindowImpl和主机IWebBrowers2控件,该控件显示一些内容 IWebBrowser2使用editbox显示html,我需要支持编辑和操作文本所需的所有键(Ctrl+C、Ctrl+V、Ctrl+X等…+Esc、Delete、上下箭头) 我还需要禁止一些快捷键,比如Ctrl+p、Ctrl+S,因为它们调用特定于我不需要的网页的对话框 这似乎是一个常见问题,我需要为我的IWebBrowser2对象调用Transl

看来我没有一个小问题

我把自己的窗户挂在主窗户上。我的窗口来自WTL的CWindowImpl和主机IWebBrowers2控件,该控件显示一些内容

IWebBrowser2使用
editbox显示html,我需要支持编辑和操作文本所需的所有键(Ctrl+C、Ctrl+V、Ctrl+X等…+Esc、Delete、上下箭头)

我还需要禁止一些快捷键,比如Ctrl+p、Ctrl+S,因为它们调用特定于我不需要的网页的对话框


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

网上也有一些类似的问题——

解决方案-

这是一条非常有趣的线索,我需要的是-


因此,首先我需要为我的IWebBrowser2对象调用TranslateAccelerator。但我必须先从键盘上得到信息

那么,让我们看看它看起来如何

我的钩形窗口不接收任何键盘输入消息。一个类为“InternetExplorer\uServer”的窗口接收所有这些内容(实际上,它是IWebBrowser2中的一个IE硬件)

所以我需要钩住这个hwnd的窗口进程

m_ieOldProc = (PROC)::SetWindowLongPtr ( hIEWnd, GWLP_WNDPROC, (LONG_PTR)_IEWndProc );
在挂钩wnd过程中,我执行以下操作:

// ...
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();
            }           
        }
        // ...
    }
}
// ...
/。。。
开关(uMsg)
{
案例WM_KEYUP:
案例WM_键控:
{
// ...
IOleInPlaceActiveObject*打包机;
CComPtrpWebBrowser=CWebWindow::GetWebBrowser(hwnd);
如果(pWebBrowser)
{               
hr=pWebBrowser->QueryInterface(IID_IOleInPlaceActiveObject,(void**)和pAccelerator);
如果(成功(hr))
{
pAccelerator->TranslateAccelerator(&msg);
pAccelerator->Release();
}           
}
// ...
}
}
// ...
对!!有些事情成功了!Esc、Delete、Up和Down箭头键现在可以工作了

但并非全部。捷径也有问题

  • Ctrl+C,Ctrl+A不起作用 Ctrl+X,Ctrl+V-完成工作

    下面是Spy++for hwnd中带有“Internet Explorer_Server”类的消息日志

    在Ctrl+C上,我没有收到WM_命令

    在Ctrl+X上:

    我不知道为什么

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


    解决方案?

    您可以提到,在有关此问题的所有解决方案中,有:

  • 预译信息
  • 实际平移加速度计
  • 到目前为止,钩住消息过程中只有TranslateAccelerator

    翻译前必须这样做:

    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);
    }
    
    BOOL预翻译消息(MSG*pMsg)
    {
    如果((pMsg->messagemessage>WM|u KEYLAST)&&
    (pMsg->messagemessage>WM|u MOUSELAST))
    返回FALSE;
    //让HTML页面有机会翻译此消息
    返回(BOOL)发送消息(WM_FORWARDMSG,0,(LPARAM)pMsg);
    }
    
    另外,在PreTranslateMessage中,我可以过滤“坏”的快捷方式,而不将它们发送到窗口

    另一个人建议也使用预翻译消息(上面线程中的对话框):

    –从CMessageFilter派生您的窗口,使用 CMessageLoop::AddMessageFilter,实现预翻译消息,如图所示 在这个例子中

    –我想我已经按照样本的建议做了。但问题是,我的“父”窗口没有得到击键,它们都会转到 IEAX控制

    –这就是为什么您需要CMessageFilter。它被信息吸引住了 在消息被分派到其目标窗口之前

    好的,但是我的根窗口(托管IWebBrowser2)没有收到任何键盘消息。 另外,我的窗口中没有PreTranslateMessage,只有windowproc调用(由父级调用,CWindowImpl)

    如上所述,我可以从CMessageFilter派生,实现预翻译消息,但我不能使用CMessageLoop::AddMessageFilter订阅事件,因为我不创建主窗口,也无权访问它的CMessageLoop


    那么我现在该怎么做才能让这一切顺利进行呢?
    我应该使用预翻译信息吗?如何使用?

    听起来您已经实现了一个工具栏。在这种情况下,您应该执行,浏览器框架将在适当的时间向您转发调用,以便您可以适当地转换加速器(和否决加速器)。

    最近,我还遇到了复制/剪切命令不起作用的问题。事实证明,TranslateAccelerator或类似产品中没有键盘问题。问题是COM库是使用CoInitialize/coInitializeX初始化的。但是需要调用OleInitialize才能使剪贴板工作。MSDN“WebBrowser定制”页面上有说明:

    应用程序应该使用OleInitialize而不是CoInitialize来 启动COM。OleInitialize启用对剪贴板的支持, 拖放操作、OLE和就地激活。使用 OleUninitialize可在应用程序关闭时关闭COM库 放下

    如果它仍然不工作,请查看我在PHP桌面项目中对IWebBrowser2控件的实现(C API):


    您要解决的问题是什么,需要将windows插入Internet Explorer?托管您自己的IWebBrowser2实例,您可以控制消息循环,这不是更简单吗?@EricBrown这是一种与IE的集成。类似于IE版本的searchbox,它没有。所以,不,我不能用其他方法。不太可能。在注册表中注册的不是这样的“合法”工具栏。这只是一个小问题