转载自http://www.cnblogs.com/jasonsun/archive/2010/08/10/1796564.html
TrackMouseEvent 函数用于当鼠标指针离开某个窗口或在某个窗口中悬停指定时间后向相应窗口发送(post)消息。
语法
BOOL TrackMouseEvent( LPTRACKMOUSEEVENT lpEventTrack );
此函数可以 post 以下四个消息:
1. WM_MOUSEHOVER
鼠标指针在上次调用 TrackMouseEvent 函数时所指定的窗口的客户区已停留了指定的时间段。此消息只会触发一次。
如果需要再次发送此消息,则必需重新调用 TrackMouseEvent 函数。
2. WM_MOUSELEAVE
鼠标指针离开了上次调用 TrackMouseEvent 函数时所指定的窗口的客户区。此消息产生以后,所有由 TrackMouseEvent
发起的鼠标跟踪请求都会被取消。
3. WM_NCMOUSEHOVER
与 WM_MOUSEHOVER 消息类似,只是其用于窗口的非客户区。
4. WM_NCMOUSELEAVE
与 WM_MOUSELEAVE 消息类似,只是其用于窗口的非客户区。
要产生 HOVER 消息并不是说鼠标必须一动不动超过一定时间,只要鼠标在指定大小的矩形中停留指定的时间就会被认为是
正在悬停。所需停留的时间由 TrackMouseEvent 函数的 lpEventTrack 参数指定,而此矩形的大小则由系统决定并可以
使用 SystemParametersInfo 函数来获得。例如,在我的电脑中执行以下代码:
UINT w,h; ::SystemParametersInfo(SPI_GETMOUSEHOVERWIDTH,0,&w,0); ::SystemParametersInfo(SPI_GETMOUSEHOVERHEIGHT,0,&h,0);
w 和 h 的值都为 4。也就是说只要鼠标在4像素 * 4像素大小的矩形中停留指定的时间就认为鼠标正在悬停。
如果在调用 TrackMouseEvent 函数请求悬停追踪时,悬停追踪已经激活了则悬停计时器将被重置(重新开如计时)。
如果在调用 TrackMouseEvent 函数请求悬停追踪时,鼠标指针不在窗口中则此次请求被忽略。
如果在调用 TrackMouseEvent 函数请求了离开追踪时(指定了 TME_LEAVE),鼠标指针不在窗口中则将立即产生
leave 消息,并且不会再产生其它的追踪消息(比如 hover 消息)。
示例
class CMainDlg : public CDialogImpl<CMainDlg> { public: CMainDlg() : m_track(true) {} LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // 只在首次进入窗口时才调用 TrackMouseEvent 函数 if (m_track) { TRACKMOUSEEVENT track; track.cbSize = sizeof(track); track.dwFlags = TME_LEAVE|TME_HOVER; track.dwHoverTime = 400; track.hwndTrack = m_hWnd; ::TrackMouseEvent(&track); m_track = false; return 0; } } LRESULT OnMouseHover(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // 执行 Hover 逻辑 return 0; } LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // 以备在下次重新进入窗口后可以调用 TrackMouseEvent 函数 m_track = true; // 执行 Leave 逻辑 return 0; } private: bool m_track; }