我已经为我的应用程序(MFC)中的几个控件实现了自定义工具提示,但我想使其适用于所有控件。
现在我在WM_MOUSEMOVE
中调用TrackMouseEvent,然后捕获WM_MOUSEHOVER
(两者都在控件的覆盖函数WindowProc中)。但是这样我必须为每个控件复制代码。所以我的目的是为鼠标事件设置一个全局钩子,并要求控件在工具提示中显示消息。
问题是我无法在全局钩子中捕获WM_MOUSEHOVER
。这是代码:
hMouseHook = SetWindowsHookEx( WH_MOUSE,
CallWndMouseProc,
NULL,
AfxGetThread()->m_nThreadID);
hMainHook = SetWindowsHookEx( WH_CALLWNDPROC,
CallWndProc,
NULL,
AfxGetThread()->m_nThreadID);
LRESULT CALLBACK CallWndMouseProc( int nCode,
WPARAM wParam,
LPARAM lParam )
{
if(nCode == HC_ACTION)
{
MOUSEHOOKSTRUCT* pwp = (MOUSEHOOKSTRUCT*)lParam;
TRACE( _T("message: %x hwnd: %x x: %d y: %d\n"),
wParam,
pwp->hwnd,
pwp->pt.x,
pwp->pt.y);
TRACKMOUSEEVENT eventTrack;
eventTrack.cbSize = sizeof(TRACKMOUSEEVENT);
eventTrack.dwFlags = TME_HOVER;
eventTrack.dwHoverTime = HOVER_DEFAULT;
eventTrack.hwndTrack = pwp->hwnd;
_TrackMouseEvent(&eventTrack);
if(wParam == WM_MOUSEHOVER)
{
AfxMessageBox(_T("CallWndMouseProc: WM_MOUSEHOVER"));
}
}
// let the messages through to the next hook
return CallNextHookEx( hMouseHook,
nCode,
wParam,
lParam);
}
LRESULT CALLBACK CallWndProc( int nCode,
WPARAM wParam,
LPARAM lParam )
{
if(nCode == HC_ACTION)
{
CWPSTRUCT *pData = (CWPSTRUCT*)lParam;
if(pData->message == WM_MOUSEHOVER)
{
AfxMessageBox(_T("CallWndProc: WM_MOUSEHOVER"));
}
}
// let the messages through to the next hook
return CallNextHookEx( hMainHook,
nCode,
wParam,
lParam);
}
两个钩子都在调用其余的消息,我确信WM_MOUSEHOVER
正在被发送,因为它是在WindowProc函数中捕获的。例如,这是自定义CListBox的WindowProc函数:
LRESULT CMyListBox::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_MOUSEHOVER)
{
AfxMessageBox(_T("WindowProc: WM_MOUSEHOVER"));
}
return CListBox::WindowProc(message, wParam, lParam);
}
确定。那么我错过了什么?在全局钩子中捕获此消息是不可能的?有没有其他方法来实现这一点,而无需在每个控件中放入相同的代码?
感谢。
哈维尔
答案 0 :(得分:1)
WM_MOUSEHOVER被发布到线程的消息队列中,所以你不会看到WH_CALLWNDPROC(那是发送消息)。 WH_MOUSE会发布消息,所以我觉得有点奇怪,你没有看到它......也许钩子只能得到低级别的鼠标输入消息?试试WH_GETMESSAGE钩子。