Welcome

首页 / 软件开发 / C++ / VC编程中的WM_MOUSEENTER 和 WM_MOUSELEAVE消息

VC编程中的WM_MOUSEENTER 和 WM_MOUSELEAVE消息2015-02-20这两个消息比较古怪,虽然你能找到他们的定义,看起来也似乎挺有用,但是却接收不到。

如果要处理这两个消息需要手动在WM_MOUSEMOVE消息处理函数中添加:

添加变量:

BOOL m_bTracking;

m_bTracking = FALSE;

添加消息处理函数:

afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);

afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);

用ON_MESSAGE宏进行消息映射:

ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)

ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)

在WM_MOUSEMOVE消息处理函数中进行处理:

void CDemo::OnMouseMove(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultif (!m_bTracking){TRACKMOUSEEVENT tme;tme.cbSize = sizeof(tme);tme.hwndTrack = m_hWnd;tme.dwFlags = TME_LEAVE | TME_HOVER;tme.dwHoverTime = 1;m_bTracking = _TrackMouseEvent(&tme);} }LRESULT CDemo::OnMouseLeave(WPARAM wParam, LPARAM lParam){return 0;}LRESULT CDemo::OnMouseHover(WPARAM wParam, LPARAM lParam){ return 0;}

WM_MOUSELEAVE ,WM_MOUSEENTER 应该算是个自定义的消息,因为Windows通常都不会发送这个消息。只有你调用TrackMouseEvent 才会收到这个消息。

实际上这个消息 是 TrackMouseEvent 而不是windows 发出的。很奇怪微软会定义出这样子的API。而且TrackMouseEvent 个人感觉也不大好用(主要是感觉别扭,不是说功能不行)。其实TrackMouseEvent 的原理也蛮简单的,自己三两句语句就搞定了,不必理会微软搞的这个古里古怪的API,还得去查找消息定义。

原理如下:

鼠标在窗口区域时会收到MouseMove消息,第一次收到这个消息时 就是 WM_MOUSEENTER。

On_MouseMove(...){BOOL bFirst = TRUE;if (bFirst){// PostMessage(WM_MOUSEENTER...) or call some function.bFirst = FALSE;SetTimer(...);}}
在 Mouse Enter 自后启动了一个计时器, 通常100ms 就足够了。计时器里检测鼠标是否离开。

On_Timer(...){...GetCursorPos(pt);GetWindowRect(rect);if (PtInRect(&rect,pt)){KillTimer(...); // kill self.PostMessage(WM_MOUSELEAVE...); // or call some function.}}