WM_MOUSEHOVER в глобальном хуке - PullRequest
0 голосов
/ 25 июня 2009

Я реализовал настраиваемые всплывающие подсказки для пары элементов управления в моем приложении (MFC), но я хотел бы сделать их общими для всех элементов управления.

Прямо сейчас я вызываю TrackMouseEvent в WM_MOUSEMOVE и затем ловлю 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. Например, это функция WindowProc для пользовательского CListBox:

LRESULT CMyListBox::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
    if(message == WM_MOUSEHOVER)
    {
        AfxMessageBox(_T("WindowProc: WM_MOUSEHOVER"));
    }
    return CListBox::WindowProc(message, wParam, lParam);
}

Ok. Так чего мне не хватает? Просто невозможно перехватить это сообщение в глобальном хуке? Есть ли другой способ сделать это без необходимости помещать один и тот же код в каждый элемент управления?

Спасибо.

Хавьер

1 Ответ

1 голос
/ 25 июня 2009

WM_MOUSEHOVER публикуется в очереди сообщений потока, поэтому вы не увидите его с WH_CALLWNDPROC (это для отправленных сообщений). WH_MOUSE действительно публикует сообщения, поэтому я нахожу немного странным, что вы этого не видите ... Возможно, ловушка получает только низкоуровневые сообщения ввода мышью? Попробуйте хук WH_GETMESSAGE.

...