Я реализовал настраиваемые всплывающие подсказки для пары элементов управления в моем приложении (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. Так чего мне не хватает? Просто невозможно перехватить это сообщение в глобальном хуке? Есть ли другой способ сделать это без необходимости помещать один и тот же код в каждый элемент управления?
Спасибо.
Хавьер