#include #include #include #pragma comment(lib, "comctl32.lib") class TrackMouseEventWindow : public CWindowImpl { protected: BEGIN_MSG_MAP(TrackMouseEventWindow) MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) MESSAGE_HANDLER(WM_MOUSEHOVER, OnMouseHover) MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave) MESSAGE_HANDLER(WM_DESTROY, OnDestroy) END_MSG_MAP() public: TrackMouseEventWindow() : _bMouseTracking(false) , _bMouseWithin(false) { } protected: LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { // 如果鼠标不在客户区内,就产生一个鼠标进入事件 if(!_bMouseWithin) { OnMouseEnter(uMsg /* WM_MOUSEMOVE */, wParam, lParam, bHandled); } // 开始跟踪鼠标停留/离开事件 if(!_bMouseTracking) { StartTrack(); _bMouseTracking = true; return 0; } printf("鼠标移动: %d,%d\n", GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); return 0; } LRESULT OnMouseHover(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { _bMouseTracking = false; printf("鼠标停留: %d,%d\n", GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); return 0; } LRESULT OnMouseLeave(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { _bMouseTracking = false; _bMouseWithin = false; printf("鼠标离开: %d,%d\n", GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); return 0; } LRESULT OnMouseEnter(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { _bMouseWithin = true; printf("鼠标进入: %d,%d\n", GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); return 0; } LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { ::PostQuitMessage(0); return 0; } protected: void StartTrack() { TRACKMOUSEEVENT tme = {0}; tme.cbSize = sizeof(tme); tme.hwndTrack = m_hWnd; tme.dwFlags = TME_HOVER | TME_LEAVE; tme.dwHoverTime = HOVER_DEFAULT; _TrackMouseEvent(&tme); } protected: bool _bMouseTracking; // 是否正在跟踪鼠标 bool _bMouseWithin; // 鼠标是否在窗口内 }; int main() { TrackMouseEventWindow wnd; wnd.Create(nullptr, nullptr, nullptr, WS_OVERLAPPEDWINDOW); wnd.ShowWindow(SW_SHOWNORMAL); MSG msg; while(::GetMessage(&msg, nullptr, 0, 0)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } return (int)msg.wParam; }