让WebBrowser控件响应键盘快捷键或者鼠标信息
通过SDK方式或者Atl方式添加的IE控件(WebBrowser控件)无法响应键盘的tab消息,这在输入表单的时候非常不方便,每次都需要鼠标点击输入框,我在网上看过一些文章,据说可以通过IE控件的IDocHostShowUI接口和IDocHostUIHandler2接口获取响应的消息,不过我试过这些方法,没成功~_~.于是采用了一种比较偏门的方法:挂钩键盘消息。
首先,设置键盘消息处理函数,该函数的功能是获取键盘的输入键信息,如果该键是tab键,并且是按下状态,则将该消息发送给IE控件的快捷键处理函数进行快捷键处理,同样的,为了能通过回车键提交html表单,判断输入键是回车键,并且是按键释放时,将该消息发送给IE控件的快捷键处理函数进行快捷键处理。
先声明一个全局的HHOOK句柄
HHOOK h_Keyboard;
消息处理函数如下:
LRESULT CALLBACK KeyboardProc( int code, // hook code WPARAM wParam, // virtual-key code LPARAM lParam // keystroke-message information ) { if(wParam==VK_TAB && GetKeyState(wParam)< 0) { //按下tab键 //::MessageBox(NULL, _T("TAB"), _T(""), 0); //以下是获取浏览器对象并像对象发送快捷键的代码,我这里的m_wndIE是AxWindow类型,如果直接用SDK创建IE控件的话,前面的代码有所不同,但后面的获取接口的方式是一致的 CWebWindow* pWebWindow = g_webWindow; MSG msg; msg.hwnd = pWebWindow->m_wndIE.m_hWnd; msg.message = WM_KEYDOWN; msg.lParam = lParam; msg.wParam = wParam; HRESULT hr = S_OK; IWebBrowser2Ptr browser; hr = pWebWindow->m_wndIE.QueryControl(__uuidof(IWebBrowser2), (void**)&browser); ATLASSERT(SUCCEEDED(hr)); CComPtr<IDispatch> disp; hr = browser->get_Document(&disp); ATLASSERT(SUCCEEDED(hr)); //CComPtr<IHTMLDocument2> doc; CComQIPtr<IOleInPlaceActiveObject> spInPlace; hr = disp->QueryInterface(__uuidof(IOleInPlaceActiveObject), (void**)&spInPlace); ATLASSERT(SUCCEEDED(hr)); if (spInPlace) bool bRet = (spInPlace->TranslateAccelerator(&msg) == S_OK) ? TRUE : FALSE; } else if (wParam == VK_RETURN && GetKeyState(wParam)> 0) { ///释放回车键 //::MessageBox(NULL, _T("ENTER"), _T(""), 0); ////以下是获取浏览器对象并像对象发送快捷键的代码,我这里的m_wndIE是AxWindow类型,如果直接用SDK创建IE控件的话,前面的代码有所不同,但后面的获取接口的方式是一致的 CWebWindow* pWebWindow = g_webWindow; MSG msg; msg.hwnd = pWebWindow->m_wndIE.m_hWnd; msg.message = WM_KEYUP; msg.lParam = lParam; msg.wParam = wParam; HRESULT hr = S_OK; IWebBrowser2Ptr browser; hr = pWebWindow->m_wndIE.QueryControl(__uuidof(IWebBrowser2), (void**)&browser); ATLASSERT(SUCCEEDED(hr)); CComPtr<IDispatch> disp; hr = browser->get_Document(&disp); ATLASSERT(SUCCEEDED(hr)); //CComPtr<IHTMLDocument2> doc; CComQIPtr<IOleInPlaceActiveObject> spInPlace; hr = disp->QueryInterface(__uuidof(IOleInPlaceActiveObject), (void**)&spInPlace); ATLASSERT(SUCCEEDED(hr)); if (spInPlace) bool bRet = (spInPlace->TranslateAccelerator(&msg) == S_OK) ? TRUE : FALSE; } //返回非0值,表示我们已处理此键盘消息了 return CallNextHookEx(h_Keyboard,code,wParam,lParam); }
然后,就是设置挂钩函数,这个放在主函数的初始化部分:
h_Keyboard=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,hInstance,0);
最后,释放挂钩,这个放在主函数的退出之前:
UnhookWindowsHookEx(h_Keyboard);
原文地址:http://www.cnblogs.com/moodlxs/archive/2012/11/01/2750142.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)