当鼠标停留在程序窗口一定时间后,会产生一个WM_MOUSEHOVER消息;当鼠标离开程序窗口后,会产生一个WM_MOUSELEAVE消息。那如何才能使窗口响应这两个消息呢?按下面的步骤,即可让指定的窗口能捕获并响应WM_MOUSEHOVER和WM_MOUSELEAVE消息了。
一:方法1:
1、在窗口类的头文件中添加:
afx_msg void OnMouseHover();
afx_msg void OnMouseLeave();
BOOL m_bTrackLeave; // 捕获设置标记
```
2、在窗口类的cpp文件中添加:
void CXXXWnd::OnMouseHover()
{
MessageBox( "鼠标已进入 ");
m_bTrackLeave = FALSE;
}
void CXXXWnd::OnMouseLeave()
{
MessageBox( "鼠标已离开 ");
m_bTrackLeave = FALSE;
}
3、用ON_MESSAGE添加消息映射:
ON_MESSAGE( WM_MOUSEHOVER, OnMouseHover )
ON_MESSAGE( WM_MOUSELEAVE, OnMouseLeave )
4、在OnMouseMove响应函数中,调用_TrackMouseEven(),设置捕获WM_MOUSEHOVER和WM_MOUSELEAVE消息
void CXXXWnd::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_bTracking)
{
// 鼠标移入窗时,请求WM\_MOUSEHOVER和WM\_MOUSELEAVE 消息
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE|TME_HOVER;
tme.dwHoverTime = 1;
m_bTracking = _TrackMouseEvent(&tme);
}
CWnd::OnMouseMove(nFlags, point);
}
5、相关说明
(1)调用一次_TrackMouseEvent只能请求一次WM_MOUSEHOVER和WM_MOUSELEAVE消息,所以要放到OnMouseMove中多次请求
(2)让一个相对独立的窗口捕获WM_MOUSEHOVER和WM_WM_MOUSELEAVE消息,直接上述方法就可以了,如果让子窗口CButton、CStatic等来捕获,则需要在基类的基础上派生出一个子类,在子类中按上述方法来实现就行了
二:方法二:
使用MFC自带函数SetCapture(),GetCapture()和ReleaseCapture()来使窗口捕获WM_MOUSEHOVER和WM_MOUSELEAVE消息
在OnMouseMover消息相应函数中添加如下代码
void CXXXWnd::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//设置鼠标捕获,即使光标离开按钮区域,仍然能接收鼠标消息
CRect rect;
GetClientRect(rect);
if(rect.PtInRect(point))//鼠标在自定义按钮窗口的范围内
{
//GetCapture()返回捕获了鼠标的窗口指针,
//因为自绘按钮设置了SetCapture(),
//所以会调用了SetCapture()函数的自绘按钮的指针,
//所以这句的作用是避免多次调用SetCapture()
if(GetCapture()!=this)
SetCapture();
//如果==this,说明此事鼠标在自定义按钮上
m_bTrack=TRUE;
}
else//如果鼠标不在自定义按钮窗口范围内
{
if(!m_bPress)//如果鼠标没按下,则解除捕获鼠标(拖着鼠标离开窗口)
ReleaseCapture();
m_bTrack=FALSE;
}
Invalidate(FALSE);
CWnd::OnMouseMove(nFlags, point);
}
然后就可在其他函数中根据变量m_bTrack的值来判断鼠标是否在某个窗口内(包括自定义窗口)来实现相关代码
注意:当 CWnd 不再需要任何鼠标输入时,应用程序应调用 ReleaseCapture 功能,以便其他窗口可以接收鼠标输入。
当鼠标输入捕获时,WM_NCHITTEST 或 WM_SETCURSOR 信息不会发送到活动窗口。
参考
http://blog.csdn.net/s_52588/article/details/8230053