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/TrackMous…
==============================================================================
--- 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?…
==============================================================================
--- 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
{