FAQ:WinAPI VCPP:определить выход курсора мыши за границу окна — различия между версиями
Материал из Весельчак У
(Новая: === Как определить , что курсор мыши вышел за границу окна? === 1) Использовать функцию _TrackMouseEvent. Например...) |
RXL (обсуждение | вклад) м («FAQ: WinAPI VCPP: определить выход курсора мыши за границу окна» переименована в «FAQ:WinAPI VCPP:определить выход курсора мыши за границу окна») |
||
(не показаны 3 промежуточные версии этого же участника) | |||
Строка 1: | Строка 1: | ||
− | === Как определить , что курсор мыши вышел за границу окна? === | + | ===Как определить, что курсор мыши вышел за границу окна?=== |
− | 1) Использовать функцию _TrackMouseEvent. Например, есть класс MyST | + | 1) Использовать функцию _TrackMouseEvent. Например, есть класс MyST. |
− | < | + | |
+ | <syntaxhighlight lang="cpp"> | ||
+ | class MyST : public CStatic | ||
{ | { | ||
bool m_bTrackingNow; | bool m_bTrackingNow; | ||
Строка 12: | Строка 14: | ||
MyST:MyST() | MyST:MyST() | ||
{ | { | ||
− | m_bTrackingNow=false; | + | m_bTrackingNow = false; |
} | } | ||
Строка 18: | Строка 20: | ||
void MyST::OnMouseMove(UINT nFlags, CPoint point) | void MyST::OnMouseMove(UINT nFlags, CPoint point) | ||
{ | { | ||
− | if(!m_bTrackingNow) | + | if (!m_bTrackingNow) |
{ | { | ||
− | m_bTrackingNow=true; | + | m_bTrackingNow = true; |
TRACKMOUSEEVENT tme; | TRACKMOUSEEVENT tme; | ||
− | tme.cbSize=sizeof(tme); | + | tme.cbSize = sizeof(tme); |
− | tme.dwFlags=TME_LEAVE;//отслеживаем выход курсора | + | tme.dwFlags = TME_LEAVE; //отслеживаем выход курсора |
− | tme.hwndTrack = m_hWnd;//из этого окна | + | tme.hwndTrack = m_hWnd; //из этого окна |
− | ::_TrackMouseEvent(& | + | ::_TrackMouseEvent(&tme); //"запуск" отслеживания |
//при выходе курсора за границу окна будет | //при выходе курсора за границу окна будет | ||
//будет сгенерировано сообщение WM_MOUSELEAVE | //будет сгенерировано сообщение WM_MOUSELEAVE | ||
Строка 32: | Строка 34: | ||
... | ... | ||
... | ... | ||
− | CStatic::OnMouseMove(nFlags,point); | + | CStatic::OnMouseMove(nFlags, point); |
} | } | ||
Строка 39: | Строка 41: | ||
BOOL MyST::PreTranslateMessage(MSG* pMsg) | BOOL MyST::PreTranslateMessage(MSG* pMsg) | ||
{ | { | ||
− | if(pMsg- | + | if (pMsg->message == WM_MOUSELEAVE) |
{ | { | ||
//тут обрабатываем | //тут обрабатываем | ||
... | ... | ||
... | ... | ||
− | m_bTrackingNow=false; | + | m_bTrackingNow = false; |
} | } | ||
... | ... | ||
Строка 50: | Строка 52: | ||
return CStatic::PreTranslateMessage(pMsg); | return CStatic::PreTranslateMessage(pMsg); | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
− | 2) Для случая, когда надо регулировать время "реакции" на выход за границу | + | |
− | < | + | 2) Для случая, когда надо регулировать время "реакции" на выход за границу. |
+ | |||
+ | <syntaxhighlight lang="cpp"> | ||
+ | enum | ||
{ | { | ||
− | def_TrackTimer_ID | + | def_TrackTimer_ID = 1000, //ID таймера |
− | def_TrackTimer_value = 50, //миллисекунд | + | def_TrackTimer_value = 50, //миллисекунд |
}; | }; | ||
MyST::MyST() | MyST::MyST() | ||
{ | { | ||
− | m_bTrackingNow=false; | + | m_bTrackingNow = false; |
} | } | ||
Строка 67: | Строка 72: | ||
{ | { | ||
//перезапуск таймера | //перезапуск таймера | ||
− | SetTimer(def_TrackTimer_ID,def_TrackTimer_value,0); | + | SetTimer(def_TrackTimer_ID, def_TrackTimer_value, 0); |
− | m_bTrackingNow=true; | + | m_bTrackingNow = true; |
... | ... | ||
... | ... | ||
− | CStatic::OnMouseMove(nFlags,point); | + | CStatic::OnMouseMove(nFlags, point); |
} | } | ||
void MyST::OnTimer(UINT nIDEvent) | void MyST::OnTimer(UINT nIDEvent) | ||
{ | { | ||
− | if(nIDEvent==def_TrackTimer_ID) | + | if (nIDEvent == def_TrackTimer_ID) |
{ | { | ||
− | KillTimer(def_TrackTimer_ID);//таймер гасит сам себя | + | KillTimer(def_TrackTimer_ID); //таймер гасит сам себя |
+ | |||
//смотрим, где курсор | //смотрим, где курсор | ||
POINT pnt; | POINT pnt; | ||
− | if(GetCursorPos(& | + | |
+ | if (GetCursorPos(&pnt)) | ||
{ | { | ||
− | if(WindowFromPoint(pnt)!=this) | + | if (WindowFromPoint(pnt) != this) |
{ | { | ||
− | m_bTrackingNow=false;//вышли за окно | + | m_bTrackingNow = false; //вышли за окно |
} | } | ||
} | } | ||
Строка 91: | Строка 98: | ||
CStatic::OnTimer(nIDEvent); | CStatic::OnTimer(nIDEvent); | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
+ | |||
+ | [[Category:FAQ:WinAPI VCPP]] |
Текущая версия на 18:53, 5 октября 2008
Как определить, что курсор мыши вышел за границу окна?
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); }