当鼠标停留在程序窗口一定时间后,会产生一个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 信息不会发送到活动窗口。
参考
 
                   
                   
                   
                   
                             本文介绍两种方法实现窗口捕获WM_MOUSEHOVER和WM_MOUSELEAVE消息。方法一通过_TrackMouseEvent函数结合消息映射实现;方法二利用SetCapture()函数实现鼠标捕获。适用于需要响应鼠标悬停与离开事件的应用程序。
本文介绍两种方法实现窗口捕获WM_MOUSEHOVER和WM_MOUSELEAVE消息。方法一通过_TrackMouseEvent函数结合消息映射实现;方法二利用SetCapture()函数实现鼠标捕获。适用于需要响应鼠标悬停与离开事件的应用程序。
           
       
           
                 
                 
                 
                 
                 
                
               
                 
                 
                 
                 
                
               
                 
                 扫一扫
扫一扫
                     
              
             
                   438
					438
					
 被折叠的  条评论
		 为什么被折叠?
被折叠的  条评论
		 为什么被折叠?
		 
		  到【灌水乐园】发言
到【灌水乐园】发言                                
		 
		 
    
   
    
   
             
            


 
            