FAQ:WinAPI VCPP:определить выход курсора мыши за границу окна
Материал из Весельчак У
Версия от 20:48, 3 октября 2008; Алексей1153++ (обсуждение | вклад) (Новая: === Как определить , что курсор мыши вышел за границу окна? === 1) Использовать функцию _TrackMouseEvent. Например...)
Как определить , что курсор мыши вышел за границу окна?
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); }