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);
}