FAQ:WinAPI VCPP:определить выход курсора мыши за границу окна
Материал из Весельчак У
Версия от 18:19, 5 октября 2008; RXL (обсуждение | вклад) (Множественные правки пунктуации, форматирование исходного кода, добавлена категория.)
Как определить, что курсор мыши вышел за границу окна?
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); }