Internet explorer IWebBrowser2 Ctrl+;C和其他快捷方式支持
看来我没有一个小问题 我把自己的窗户挂在主窗户上。我的窗口来自WTL的CWindowImpl和主机IWebBrowers2控件,该控件显示一些内容 IWebBrowser2使用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
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箭头键现在可以工作了
但并非全部。捷径也有问题
解决方案? 您可以提到,在有关此问题的所有解决方案中,有:
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,它没有。所以,不,我不能用其他方法。不太可能。在注册表中注册的不是这样的“合法”工具栏。这只是一个小问题