http://blog.youkuaiyun.com/colinchan/article/details/5516780
ActiveX控件开发人员如需正确处理在浏览器中的鼠标键盘事件,可首先参考一下潘爱民老师的《COM原理与应用》第12章:ActiveX控制,第392页。其中系统阐述了ActiveX控件与其容器程序的键盘交互原理。
1. 控件初次加载时,进行实地激活。如果基于ATL的简单控件CComControl,则可在OnCreate中添加。如果基于ATL的复合控件CComCompositeControl,则可在OnInitDialog中添加。
//Activate control in web browser immediately
InPlaceActivate(OLEIVERB_UIACTIVATE);
2. 当鼠标点击控件时,应进行实地激活。此处主要响应WM_MOUSEACTIVATE事件。
LRESULT OnMouseActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
//Activate control in web browser immediately
InPlaceActivate(OLEIVERB_UIACTIVATE);
return 0;
}
3. 然后就可在TranslateAccelerator中实现特点键盘事件处理了。
//IOleInPlaceActiveObject::TranslateAccelerator()
STDMETHOD(TranslateAccelerator)(MSG *pMsg)
{
if (
((pMsg->message >= WM_KEYFIRST) &&
(pMsg->message <= WM_KEYLAST))
&&
((pMsg->wParam == VK_TAB) ||
(pMsg->wParam == VK_RETURN))
)
{
CComQIPtr<IOleControlSite,&IID_IOleControlSite>
spCtrlSite(m_spClientSite);
if(spCtrlSite)
{
return spCtrlSite->TranslateAccelerator(pMsg, 0);
}
}
return S_FALSE;
}
上述的代码是在子窗口的编辑框中处理TAB与ENTER键,如果你需要处理UP ARROW, DOWN ARROW, PAGE UP, and PAGE DOWN,可如下示例:
if((pMsg->wParam == VK_UP) ||
(pMsg->wParam == VK_DOWN)||
(pMsg->wParam == VK_LEFT) ||
(pMsg->wParam == VK_RIGHT))
{
::IsDialogMessage(m_hWnd, pMsg);
return S_OK;
}
如果Active X控件有滚动条,你需要处理VK_UP与VK_DOWN,如下示例:
if (pMsg->wParam == VK_UP)
{
::SendMessage(m_hWnd,WM_VSCROLL,
SB_LINEUP,MAKELONG(0,m_hWnd));
return S_FALSE;
}
默认按钮的处理:当用户按下ENTER,你应该允许焦点转移到默认的按钮上(如果一个按钮设置为“默认”),那么你需要实现IOleControl::GetControlInfo()来接受ENTER与ESC键,ATL默认实现IOleControlImpl::GetControlInfo() 返回E_NOTIMPL,你需要覆盖它:
HRESULT STDMETHODCALLTYPE GetControlInfo(CONTROLINFO *pCI)
{
if(!pCI)
{
return E_POINTER;
}
pCI->hAccel = NULL; //load your accelerators here, if any
pCI->cAccel = 0;
pCI->dwFlags = 0;
return S_OK;
}