Author: gadamopoulos Date: Sun Sep 25 16:05:09 2011 New Revision: 53855 URL: http://svn.reactos.org/svn/reactos?rev=53855&view=rev Log: [user32_apitest] - In TrackMouseEvent tests, use mouse_event function to move the mouse cause this causes low level hooks to be called and SetCursorPos doesn't - Test low level mouse hooks for TrackMouseEvent - Test ways to block WM_MOUSEHOVER and WM_MOUSELEAVE. This is useful to detect where each message is generated - clean up the code a bit by adding FLUSH_MESSAGES macro that checks for expected message queue status and flushes the message queue
Modified: trunk/rostests/apitests/user32/TrackMouseEvent.c trunk/rostests/apitests/user32/helper.c Modified: trunk/rostests/apitests/user32/TrackMouseEvent.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/TrackMouseEvent.c?rev=53855&r1=53854&r2=53855&view=diff ============================================================================== --- trunk/rostests/apitests/user32/TrackMouseEvent.c [iso-8859-1] (original) +++ trunk/rostests/apitests/user32/TrackMouseEvent.c [iso-8859-1] Sun Sep 25 16:05:09 2011 @@ -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 @@ 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,13 +85,22 @@ 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); } DispatchMessageA( &msg ); } } + +#define FLUSH_MESSAGES(expected, notexpected) \ + { EXPECT_QUEUE_STATUS(expected, notexpected);\ + FlushMessages();\ + } static void create_test_windows() { @@ -140,10 +158,15 @@ 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 @@ {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 @@ {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 @@ {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 @@ {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); - Sleep(100); - EXPECT_QUEUE_STATUS(QS_TIMER|QS_MOUSEMOVE, 0); - EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE); - FlushMessages(); + MOVE_CURSOR(221, 221); + Sleep(100); + EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE); + 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 @@ 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); - EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE); - - FlushMessages(); - COMPARE_CACHE(empty_chain); + + 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); /* 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 @@ 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) Modified: trunk/rostests/apitests/user32/helper.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/helper.c?rev=53855&r1=53854&r2=53855&view=diff ============================================================================== --- trunk/rostests/apitests/user32/helper.c [iso-8859-1] (original) +++ trunk/rostests/apitests/user32/helper.c [iso-8859-1] Sun Sep 25 16:05:09 2011 @@ -134,7 +134,7 @@ 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 {