WM_MOUSELEAVE这个消息很有意思,它是鼠标指针离开窗口时发送的,但是它每一次发送都必须用TrackMouseEvent注册一次。
如果想自绘制窗口控件(比如按钮),使用WM_MOUSELEAVE消息判断鼠标移出重画,可以很简单地实现按钮的鼠标在上面变色移出时恢复。(据说这种方法有一些问题,就是如果鼠标按住窗口再离开的话WM_MOUSELEAVE就会在鼠标放开的时候再响应,另外SetCapture貌似也能实现类似功能,但没有试过,我会在我以后会发的GdiplusFlat博文中进一步介绍)
先来看看TrackMouseEvent的函数原型:
BOOL WINAPI TrackMouseEvent( _Inout_ LPTRACKMOUSEEVENT lpEventTrack );
MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms646265(v=vs.85).aspx
参数: lpEventTrack
A pointer to a TRACKMOUSEEVENT structure that contains tracking information
一个TRACKMOUSEEVENT结构体的指针
返回值:成功非0,失败0
再看看TRACKMOUSEEVENT:
typedef struct tagTRACKMOUSEEVENT { DWORD cbSize; DWORD dwFlags; HWND hwndTrack; DWORD dwHoverTime; } TRACKMOUSEEVENT, *LPTRACKMOUSEEVENT;
MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms645604(v=vs.85).aspx
cbSize
Type: DWORD
The size of the TRACKMOUSEEVENT structure, in bytes.
结构体的大小
dwFlags 标志
这个标志有很多,这里只说两个(需要用的到)
TME_CANCEL: 调用者想要取消事先跟踪请求。调用方还应指定它想要取消的跟踪的类型。例如,若要取消离开通知,调用方必须通过 TME_CANCEL 和 TME_LEAVE 的标志。
TME_LEAVE: 调用方要离开通知。作为 WM_MOUSELEAVE消息传递通知。如果鼠标不在指定的窗口,立即生成离开通知。
hwndTrack
Type: HWND
A handle to the window to track.
窗口句柄
dwHoverTime 本文这里为0即可
特别提示:TrackMouseEvent注册一次只生效一次。就是说调用一次TrackMouseEvent,系统只发送一次WM_MOUSELEAVE消息,所以应该在没次鼠标进入窗口就调用,即在WM_MOUSEMOVE里调用。
继续使用上次的代码(http://blog.csdn.net/zuishikonghuan/article/details/46378475),在回调函数里加入:
<pre class="cpp" name="code">case WM_MOUSEMOVE://鼠标移动 TRACKMOUSEEVENT a; a.cbSize = sizeof(TRACKMOUSEEVENT); a.dwFlags = TME_LEAVE; a.hwndTrack = hwnd; TrackMouseEvent(&a); break;
case WM_MOUSELEAVE: MessageBox(hwnd, TEXT("鼠标离开了窗口"), TEXT(""), 0); break;