FAQ:WinAPI VCPP:определить выход курсора мыши за границу окна

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