WM_MOUSEHOVER在全局钩子中

时间:2009-06-25 07:23:34

标签: winapi events mfc mouse

我已经为我的应用程序(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);
}

确定。那么我错过了什么?在全局钩子中捕获此消息是不可能的?有没有其他方法来实现这一点,而无需在每个控件中放入相同的代码?

感谢。

哈维尔

1 个答案:

答案 0 :(得分:1)

WM_MOUSEHOVER被发布到线程的消息队列中,所以你不会看到WH_CALLWNDPROC(那是发送消息)。 WH_MOUSE会发布消息,所以我觉得有点奇怪,你没有看到它......也许钩子只能得到低级别的鼠标输入消息?试试WH_GETMESSAGE钩子。