FAQ:WinAPI VCPP:определить выход курсора мыши за границу окна
Материал из Весельчак У
Как определить, что курсор мыши вышел за границу окна?
1) Использовать функцию _TrackMouseEvent. Например, есть класс MyST.
class MyST : public CStatic
{
bool m_bTrackingNow;
...
...
};
//в конструкторе
MyST:MyST()
{
m_bTrackingNow = false;
}
//в обработчике OnMouseMove запускаем отслеживание
void MyST::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_bTrackingNow)
{
m_bTrackingNow = true;
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_LEAVE; //отслеживаем выход курсора
tme.hwndTrack = m_hWnd; //из этого окна
::_TrackMouseEvent(&tme); //"запуск" отслеживания
//при выходе курсора за границу окна будет
//будет сгенерировано сообщение WM_MOUSELEAVE
}
...
...
CStatic::OnMouseMove(nFlags, point);
}
//ловим сообщение WM_MOUSELEAVE, для этого
//переопределяем виртуальную PreTranslateMessage()
BOOL MyST::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_MOUSELEAVE)
{
//тут обрабатываем
...
...
m_bTrackingNow = false;
}
...
...
return CStatic::PreTranslateMessage(pMsg);
}
2) Для случая, когда надо регулировать время "реакции" на выход за границу.
enum
{
def_TrackTimer_ID = 1000, //ID таймера
def_TrackTimer_value = 50, //миллисекунд
};
MyST::MyST()
{
m_bTrackingNow = false;
}
//в обработчике OnMouseMove запускаем таймер
void MyST::OnMouseMove(UINT nFlags, CPoint point)
{
//перезапуск таймера
SetTimer(def_TrackTimer_ID, def_TrackTimer_value, 0);
m_bTrackingNow = true;
...
...
CStatic::OnMouseMove(nFlags, point);
}
void MyST::OnTimer(UINT nIDEvent)
{
if (nIDEvent == def_TrackTimer_ID)
{
KillTimer(def_TrackTimer_ID); //таймер гасит сам себя
//смотрим, где курсор
POINT pnt;
if (GetCursorPos(&pnt))
{
if (WindowFromPoint(pnt) != this)
{
m_bTrackingNow = false; //вышли за окно
}
}
}
CStatic::OnTimer(nIDEvent);
}