diff --git a/rostests/apitests/user32/TrackMouseEvent.c b/rostests/apitests/user32/TrackMouseEvent.c index 68678433bad..975ae55f119 100644 --- a/rostests/apitests/user32/TrackMouseEvent.c +++ b/rostests/apitests/user32/TrackMouseEvent.c @@ -13,6 +13,7 @@ HWND hWnd1, hWnd2, hWnd3; HHOOK hMouseHookLL, hMouseHook; +int ignore_timer = 0, ignore_mouse = 0, ignore_mousell = 0; static int get_iwnd(HWND hWnd) { @@ -55,15 +56,23 @@ LRESULT CALLBACK TmeTestProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar static LRESULT CALLBACK MouseLLHookProc(int nCode, WPARAM wParam, LPARAM lParam) { + LRESULT ret; record_message(0, WH_MOUSE_LL, HOOK, wParam, 0); - return CallNextHookEx(hMouseHookLL, nCode, wParam, lParam); + ret = CallNextHookEx(hMouseHookLL, nCode, wParam, lParam); + if(ignore_mousell) + return TRUE; + return ret; } static LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) { MOUSEHOOKSTRUCT *hs = (MOUSEHOOKSTRUCT*) lParam; + LRESULT ret; record_message(get_iwnd(hs->hwnd), WH_MOUSE, HOOK, wParam, hs->wHitTestCode); - return CallNextHookEx(hMouseHook, nCode, wParam, lParam); + ret = CallNextHookEx(hMouseHook, nCode, wParam, lParam); + if(ignore_mouse) + return TRUE; + return ret; } static void FlushMessages() @@ -76,7 +85,11 @@ static void FlushMessages() if(iwnd) { if(msg.message == WM_SYSTIMER) + { record_message(iwnd, msg.message, POST,msg.wParam,0); + if(ignore_timer) + continue; + } else if(!(msg.message > WM_USER || !iwnd || IsDWmMsg(msg.message) || IseKeyMsg(msg.message))) record_message(iwnd, msg.message, POST,0,0); } @@ -84,6 +97,11 @@ static void FlushMessages() } } +#define FLUSH_MESSAGES(expected, notexpected) \ + { EXPECT_QUEUE_STATUS(expected, notexpected);\ + FlushMessages();\ + } + static void create_test_windows() { WNDCLASSEXW wcex; @@ -140,10 +158,15 @@ DWORD TmeQuery(HWND hwnd) ok(flags == (expected),"wrong tme flags. expected %li, and got %li\n", (DWORD)(expected), flags); \ } +#define MOVE_CURSOR(x,y) mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE , \ + x*(65535/GetSystemMetrics(SM_CXVIRTUALSCREEN)), \ + y*(65535/GetSystemMetrics(SM_CYVIRTUALSCREEN)) , 0,0); + MSG_ENTRY empty_chain[]= {{0,0}}; /* the mouse moves over hwnd2 */ -MSG_ENTRY mousemove2_chain[]={{2, WM_NCHITTEST}, +MSG_ENTRY mousemove2_chain[]={{0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE}, + {2, WM_NCHITTEST}, {2, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT}, {2, WM_SETCURSOR}, {1, WM_SETCURSOR}, @@ -151,7 +174,8 @@ MSG_ENTRY mousemove2_chain[]={{2, WM_NCHITTEST}, {0,0}}; /* the mouse hovers hwnd2 */ -MSG_ENTRY mousehover2_chain[]={{2, WM_NCHITTEST}, +MSG_ENTRY mousehover2_chain[]={{0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE}, + {2, WM_NCHITTEST}, {2, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT}, {2, WM_SETCURSOR}, {1, WM_SETCURSOR}, @@ -161,7 +185,8 @@ MSG_ENTRY mousehover2_chain[]={{2, WM_NCHITTEST}, {0,0}}; /* the mouse leaves hwnd2 and moves to hwnd1 */ -MSG_ENTRY mouseleave2to1_chain[]={{1, WM_NCHITTEST}, +MSG_ENTRY mouseleave2to1_chain[]={{0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE}, + {1, WM_NCHITTEST}, {1, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT}, {1, WM_SETCURSOR}, {1, WM_MOUSEMOVE, POST}, @@ -169,7 +194,8 @@ MSG_ENTRY mouseleave2to1_chain[]={{1, WM_NCHITTEST}, {0,0}}; /* the mouse leaves hwnd2 and moves to hwnd3 */ -MSG_ENTRY mouseleave2to3_chain[]={{3, WM_NCHITTEST}, +MSG_ENTRY mouseleave2to3_chain[]={{0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE}, + {3, WM_NCHITTEST}, {3, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT}, {3, WM_SETCURSOR}, {1, WM_SETCURSOR}, @@ -177,37 +203,78 @@ MSG_ENTRY mouseleave2to3_chain[]={{3, WM_NCHITTEST}, {2, WM_MOUSELEAVE, POST}, {0,0}}; +/* the mouse hovers hwnd3 */ +MSG_ENTRY mousehover3_chain[]={{0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE}, + {3, WM_NCHITTEST}, + {3, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT}, + {3, WM_SETCURSOR}, + {1, WM_SETCURSOR}, + {3, WM_MOUSEMOVE, POST}, + {3, WM_SYSTIMER, POST, ID_TME_TIMER}, + {3, WM_MOUSEHOVER, POST}, + {0,0}}; + +/* the mouse hovers hwnd3 and the timer is not dispatched */ +MSG_ENTRY mousehover3_droptimer_chain[]={{0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE}, + {3, WM_NCHITTEST}, + {3, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT}, + {3, WM_SETCURSOR}, + {1, WM_SETCURSOR}, + {3, WM_MOUSEMOVE, POST}, + {3, WM_SYSTIMER, POST, ID_TME_TIMER}, + {0,0}}; + +/* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE */ +MSG_ENTRY mousehover3_dropmouse_chain[]={{0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE}, + {3, WM_NCHITTEST}, + {3, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT}, + {3, WM_SYSTIMER, POST, ID_TME_TIMER}, + {3, WM_MOUSEHOVER, POST}, + {0,0}}; + +/* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE_LL */ +MSG_ENTRY mousehover3_dropmousell_chain[]={{0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE}, + {3, WM_SYSTIMER, POST, ID_TME_TIMER}, + {3, WM_MOUSEHOVER, POST}, + {0,0}}; + +/* the mouse leaves hwnd2 and moves to hwnd3 and mouse message is dropped by WH_MOUSE */ +MSG_ENTRY mouseleave3to2_dropmouse_chain[]={{0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE}, + {2, WM_NCHITTEST}, + {2, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT}, + {0,0}}; + void Test_TrackMouseEvent() { - SetCursorPos(0,0); + MOVE_CURSOR(0,0); create_test_windows(); - FlushMessages(); + FlushMessages(0,0); empty_message_cache(); /* the mouse moves over hwnd2 */ - SetCursorPos(220,220); + MOVE_CURSOR(220,220); FlushMessages(); COMPARE_CACHE(mousemove2_chain); EXPECT_TME_FLAGS(hWnd2, 0); + + /* Begin tracking mouse events for hWnd2 */ TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE); EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE); FlushMessages(); COMPARE_CACHE(empty_chain); /* the mouse hovers hwnd2 */ - SetCursorPos(221,221); + MOVE_CURSOR(221, 221); Sleep(100); - EXPECT_QUEUE_STATUS(QS_TIMER|QS_MOUSEMOVE, 0); EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE); - FlushMessages(); + FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0); EXPECT_TME_FLAGS(hWnd2, TME_LEAVE); COMPARE_CACHE(mousehover2_chain); /* the mouse leaves hwnd2 and moves to hwnd1 */ - SetCursorPos(150,150); - EXPECT_QUEUE_STATUS(QS_MOUSEMOVE,QS_TIMER ); + MOVE_CURSOR(150, 150); EXPECT_TME_FLAGS(hWnd2, TME_LEAVE); - FlushMessages(); + FLUSH_MESSAGES(QS_MOUSEMOVE,QS_TIMER ); EXPECT_TME_FLAGS(hWnd2, 0); COMPARE_CACHE(mouseleave2to1_chain); @@ -215,28 +282,26 @@ void Test_TrackMouseEvent() COMPARE_CACHE(empty_chain); /* the mouse moves over hwnd2 */ - SetCursorPos(220,220); - EXPECT_QUEUE_STATUS(QS_MOUSEMOVE, QS_TIMER); - FlushMessages(); + MOVE_CURSOR(220,220); + FLUSH_MESSAGES(QS_MOUSEMOVE, QS_TIMER); COMPARE_CACHE(mousemove2_chain); EXPECT_TME_FLAGS(hWnd2, 0); - COMPARE_CACHE(empty_chain); - TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE); - TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE); - TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE); - TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE); - EXPECT_QUEUE_STATUS(0, QS_TIMER|QS_MOUSEMOVE); + FlushMessages(); COMPARE_CACHE(empty_chain); + + /* Begin tracking mouse events for hWnd2 */ + TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE); + TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE); + TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE); + TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE); + FLUSH_MESSAGES(0, QS_TIMER|QS_MOUSEMOVE); + COMPARE_CACHE(empty_chain); EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE); - FlushMessages(); - COMPARE_CACHE(empty_chain); - /* the mouse moves from hwnd2 to the intersection of hwnd2 and hwnd3 */ - SetCursorPos(300,300); - EXPECT_QUEUE_STATUS(QS_MOUSEMOVE, QS_TIMER); - FlushMessages(); + MOVE_CURSOR(300,300); + FLUSH_MESSAGES(QS_MOUSEMOVE, QS_TIMER); EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE); COMPARE_CACHE(mousemove2_chain); @@ -244,14 +309,80 @@ void Test_TrackMouseEvent() COMPARE_CACHE(empty_chain); /* the mouse moves from hwnd2 to hwnd3 */ - SetCursorPos(400,400); - EXPECT_QUEUE_STATUS(QS_MOUSEMOVE, QS_TIMER); - FlushMessages(); + MOVE_CURSOR(400,400); + FLUSH_MESSAGES(QS_MOUSEMOVE, QS_TIMER); EXPECT_TME_FLAGS(hWnd2, 0); COMPARE_CACHE(mouseleave2to3_chain); FlushMessages(); COMPARE_CACHE(empty_chain); + + /* Begin tracking mouse events for hWnd3 */ + TmeStartTracking(hWnd3, TME_HOVER|TME_LEAVE); + FLUSH_MESSAGES(0, QS_TIMER|QS_MOUSEMOVE); + COMPARE_CACHE(empty_chain); + EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE); + + /* the mouse hovers hwnd3 */ + MOVE_CURSOR(401,401); + Sleep(100); + EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE); + FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0); + EXPECT_TME_FLAGS(hWnd3, TME_LEAVE); + COMPARE_CACHE(mousehover3_chain); + + /* Begin tracking mouse events for hWnd3 */ + TmeStartTracking(hWnd3, TME_HOVER ); + FLUSH_MESSAGES(0, QS_TIMER|QS_MOUSEMOVE); + COMPARE_CACHE(empty_chain); + EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE); + + /* make sure that the timer won't fire before the mouse moves */ + Sleep(100); + COMPARE_CACHE(empty_chain); + Sleep(100); + COMPARE_CACHE(empty_chain); + Sleep(100); + COMPARE_CACHE(empty_chain); + + /* the mouse hovers hwnd3 and the timer is not dispatched*/ + ignore_timer = TRUE; + MOVE_CURSOR(400,400); + Sleep(100); + EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE); + FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0); /* the loop drops WM_SYSTIMER */ + EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE); /* TME_HOVER is still active */ + COMPARE_CACHE(mousehover3_droptimer_chain); /* we get no WM_MOUSEHOVER */ + ignore_timer = FALSE; + + /* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE_LL */ + ignore_mousell = TRUE; + MOVE_CURSOR(402,402); + Sleep(100); + EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE); + FLUSH_MESSAGES(QS_TIMER, QS_MOUSEMOVE); /* WH_MOUSE_LL drops WM_MOUSEMOVE */ + EXPECT_TME_FLAGS(hWnd3, TME_LEAVE); + COMPARE_CACHE(mousehover3_dropmousell_chain); /* we get WM_MOUSEHOVER normaly */ + ignore_mousell = FALSE; + + /* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE */ + ignore_mouse = TRUE; + TmeStartTracking(hWnd3, TME_HOVER ); + MOVE_CURSOR(401,401); + Sleep(100); + EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE); + FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0); /* WH_MOUSE drops WM_MOUSEMOVE */ + EXPECT_TME_FLAGS(hWnd3, TME_LEAVE); + COMPARE_CACHE(mousehover3_dropmouse_chain); /* we get WM_MOUSEHOVER normaly */ + ignore_mouse = FALSE; + + /* the mouse leaves hwnd2 and moves to hwnd3 and mouse message is dropped by WH_MOUSE */ + ignore_mouse = TRUE; + MOVE_CURSOR(220,220); + FLUSH_MESSAGES(QS_MOUSEMOVE, QS_TIMER); /* WH_MOUSE drops WM_MOUSEMOVE */ + EXPECT_TME_FLAGS(hWnd3, 0); /* all flags are removed */ + COMPARE_CACHE(mouseleave3to2_dropmouse_chain); /* we get no WM_MOUSELEAVE */ + ignore_mouse = FALSE; } START_TEST(TrackMouseEvent) diff --git a/rostests/apitests/user32/helper.c b/rostests/apitests/user32/helper.c index d69e185f20e..bd37ecc7467 100644 --- a/rostests/apitests/user32/helper.c +++ b/rostests/apitests/user32/helper.c @@ -134,7 +134,7 @@ void compare_cache(const char* file, int line, MSG_ENTRY *msg_chain) if(!got_error && !same) got_error = TRUE; - if(msg_chain->msg !=0 && msg_chain->iwnd != 0) + if(msg_chain->msg !=0 || msg_chain->iwnd != 0) msg_chain++; else {