ReactOS  0.4.13-dev-551-gf37fb1f
TrackMouseEvent.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS api tests
3  * LICENSE: GPL - See COPYING in the top level directory
4  * PURPOSE: Test for TrackMouseEvent
5  * PROGRAMMERS: Giannis Adamopoulos
6  */
7 
8 #include "precomp.h"
9 
13 
14 static int get_iwnd(HWND hWnd)
15 {
16  if(hWnd == hWnd1) return 1;
17  else if(hWnd == hWnd2) return 2;
18  else if(hWnd == hWnd3) return 3;
19  else return 0;
20 }
21 
23 {
24  int iwnd = get_iwnd(hWnd);
25 
26  if(message == WM_PAINT)
27  {
28  PAINTSTRUCT ps;
29  BeginPaint(hWnd, &ps);
31  EndPaint(hWnd, &ps);
32  }
33 
34  if(message > WM_USER || !iwnd || IsDWmMsg(message) || IseKeyMsg(message))
36 
37  switch(message)
38  {
39  case WM_IME_SETCONTEXT:
40  case WM_IME_NOTIFY :
41  case WM_GETICON :
42  case WM_GETTEXT:
43  break;
44  case WM_SYSTIMER:
45  ok(0, "Got unexpected WM_SYSTIMER in the winproc. wParam=%d\n", wParam);
46  break;
47  default:
48  RECORD_MESSAGE(iwnd, message, SENT, 0,0);
49  }
51 }
52 
54 {
55  LRESULT ret;
58  if(ignore_mousell)
59  return TRUE;
60  return ret;
61 }
62 
64 {
66  LRESULT ret;
69  if(ignore_mouse)
70  return TRUE;
71  return ret;
72 }
73 
74 static void FlushMessages()
75 {
76  MSG msg;
77 
78  while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
79  {
80  int iwnd = get_iwnd(msg.hwnd);
81  if(iwnd)
82  {
83  if(msg.message == WM_SYSTIMER)
84  {
85  RECORD_MESSAGE(iwnd, msg.message, POST,msg.wParam,0);
86  if(ignore_timer)
87  continue;
88  }
89  else if(!(msg.message > WM_USER || !iwnd || IsDWmMsg(msg.message) || IseKeyMsg(msg.message)))
90  RECORD_MESSAGE(iwnd, msg.message, POST,0,0);
91  }
93  }
94 }
95 
96 #define FLUSH_MESSAGES(expected, notexpected) \
97  { EXPECT_QUEUE_STATUS(expected, notexpected);\
98  FlushMessages();\
99  }
100 
101 static void create_test_windows()
102 {
105  ok(hMouseHook!=NULL,"failed to set hook\n");
106  ok(hMouseHookLL!=NULL,"failed to set hook\n");
107 
108  RegisterSimpleClass(TmeTestProc, L"testClass");
109 
110  hWnd1 = CreateWindowW(L"testClass", L"test", WS_OVERLAPPEDWINDOW,
111  100, 100, 500, 500, NULL, NULL, 0, NULL);
112  hWnd2 = CreateWindowW(L"testClass", L"test", WS_CHILD,
113  50, 50, 200, 200, hWnd1, NULL, 0, NULL);
114  hWnd3 = CreateWindowW(L"testClass", L"test", WS_CHILD,
115  150, 150, 200, 200, hWnd1, NULL, 0, NULL);
116 
123  //SetWindowPos (hWnd3, HWND_TOP, 0,0,0,0, SWP_NOMOVE|SWP_NOREDRAW);
124 }
125 
126 static void destroy_test_window()
127 {
129  UnregisterClassW(L"testClass", 0);
132 }
133 
135 {
136  TRACKMOUSEEVENT tme;
137  tme.cbSize = sizeof(tme);
138  tme.dwFlags = Flags;
139  tme.hwndTrack = hwnd;
140  tme.dwHoverTime = 1;
141  if(!TrackMouseEvent(&tme))
142  {
143  trace("failed!\n");
144  }
145 }
146 
148 {
149  TRACKMOUSEEVENT tme;
150  tme.cbSize = sizeof(tme);
152  tme.hwndTrack = hwnd;
153  TrackMouseEvent(&tme);
154  return tme.dwFlags;
155 }
156 
157 #define EXPECT_TME_FLAGS(hWnd, expected) \
158  { DWORD flags = TmeQuery(hWnd); \
159  ok(flags == (expected),"wrong tme flags. expected %li, and got %li\n", (DWORD)(expected), flags); \
160  }
161 
162 #define MOVE_CURSOR(x,y) mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE , \
163  x*(65535/GetSystemMetrics(SM_CXVIRTUALSCREEN)), \
164  y*(65535/GetSystemMetrics(SM_CYVIRTUALSCREEN)) , 0,0);
165 
166 /* the mouse moves over hwnd2 */
168  {2, WM_NCHITTEST},
170  {2, WM_SETCURSOR},
171  {1, WM_SETCURSOR},
172  {2, WM_MOUSEMOVE, POST},
173  {0,0}};
174 
175 /* the mouse hovers hwnd2 */
177  {2, WM_NCHITTEST},
179  {2, WM_SETCURSOR},
180  {1, WM_SETCURSOR},
181  {2, WM_MOUSEMOVE, POST},
183  {2, WM_MOUSEHOVER, POST},
184  {0,0}};
185 
186 /* the mouse leaves hwnd2 and moves to hwnd1 */
188  {1, WM_NCHITTEST},
190  {1, WM_SETCURSOR},
191  {1, WM_MOUSEMOVE, POST},
192  {2, WM_MOUSELEAVE, POST},
193  {0,0}};
194 
195 /* the mouse leaves hwnd2 and moves to hwnd3 */
197  {3, WM_NCHITTEST},
199  {3, WM_SETCURSOR},
200  {1, WM_SETCURSOR},
201  {3, WM_MOUSEMOVE, POST},
202  {2, WM_MOUSELEAVE, POST},
203  {0,0}};
204 
205 /* the mouse hovers hwnd3 */
207  {3, WM_NCHITTEST},
209  {3, WM_SETCURSOR},
210  {1, WM_SETCURSOR},
211  {3, WM_MOUSEMOVE, POST},
213  {3, WM_MOUSEHOVER, POST},
214  {0,0}};
215 
216 /* the mouse hovers hwnd3 without moving */
218  {3, WM_MOUSEHOVER, POST},
219  {0,0}};
220 
221 /* the mouse hovers hwnd3 and the timer is not dispatched */
223  {3, WM_NCHITTEST},
225  {3, WM_SETCURSOR},
226  {1, WM_SETCURSOR},
227  {3, WM_MOUSEMOVE, POST},
229  {0,0}};
230 
231 /* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE */
233  {3, WM_NCHITTEST},
236  {3, WM_MOUSEHOVER, POST},
237  {0,0}};
238 
239 /* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE_LL */
242  {3, WM_MOUSEHOVER, POST},
243  {0,0}};
244 
245 /* the mouse leaves hwnd3 and moves to hwnd2 and mouse message is dropped by WH_MOUSE */
247  {2, WM_NCHITTEST},
249  {0,0}};
250 
251 /* the mouse leaves hwnd3 and moves to hwnd2 and mouse message is dropped by WH_MOUSE_LL */
253  {0,0}};
254 
255 /* after WH_MOUSE drops WM_MOUSEMOVE, WM_MOUSELEAVE is still in the queue */
257  {0,0}};
258 
260 {
261  MOVE_CURSOR(0,0);
263  FlushMessages();
264  EMPTY_CACHE();
265 
266  /* the mouse moves over hwnd2 */
267  MOVE_CURSOR(220,220);
268  FlushMessages();
271 
272  /* Begin tracking mouse events for hWnd2 */
275  FlushMessages();
277 
278  /* the mouse hovers hwnd2 */
279  MOVE_CURSOR(221, 221);
280  Sleep(100);
285 
286  /* the mouse leaves hwnd2 and moves to hwnd1 */
287  MOVE_CURSOR(150, 150);
292 
293  FlushMessages();
295 
296  /* the mouse moves over hwnd2 */
297  MOVE_CURSOR(220,220);
301 
302  FlushMessages();
304 
305  /* Begin tracking mouse events for hWnd2 */
313 
314  /* the mouse moves from hwnd2 to the intersection of hwnd2 and hwnd3 */
315  MOVE_CURSOR(300,300);
319 
320  FlushMessages();
322 
323  /* the mouse moves from hwnd2 to hwnd3 */
324  MOVE_CURSOR(400,400);
328 
329  FlushMessages();
331 
332  /* Begin tracking mouse events for hWnd3 */
337 
338  /* the mouse hovers hwnd3 */
339  MOVE_CURSOR(401,401);
340  Sleep(100);
345 
346  FlushMessages();
348 
349  /* Begin tracking mouse events for hWnd3 */
354 
355  /* make sure that the timer will fire before the mouse moves */
356  Sleep(100);
357  FlushMessages();
360 
361  Sleep(100);
362  FlushMessages();
364 
365  /* the mouse hovers hwnd3 and the timer is not dispatched*/
367  ignore_timer = TRUE;
368  MOVE_CURSOR(400,400);
369  Sleep(100);
371  FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0); /* the loop drops WM_SYSTIMER */
372  EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE); /* TME_HOVER is still active */
373  COMPARE_CACHE(mousehover3_droptimer_chain); /* we get no WM_MOUSEHOVER */
374  ignore_timer = FALSE;
375 
376  /* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE_LL */
378  MOVE_CURSOR(402,402);
379  Sleep(100);
381  FLUSH_MESSAGES(QS_TIMER, QS_MOUSEMOVE); /* WH_MOUSE_LL drops WM_MOUSEMOVE */
383  COMPARE_CACHE(mousehover3_dropmousell_chain); /* we get WM_MOUSEHOVER normaly */
385 
386  FlushMessages();
388 
389  /* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE */
390  ignore_mouse = TRUE;
392  MOVE_CURSOR(401,401);
393  Sleep(100);
395  FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0); /* WH_MOUSE drops WM_MOUSEMOVE */
397  COMPARE_CACHE(mousehover3_dropmouse_chain); /* we get WM_MOUSEHOVER normaly */
399 
400  FlushMessages();
402 
403  /* the mouse leaves hwnd3 and moves to hwnd2 and mouse message is dropped by WH_MOUSE_LL */
406  MOVE_CURSOR(220,220);
407  FLUSH_MESSAGES(0, QS_MOUSEMOVE|QS_TIMER); /* WH_MOUSE drops WM_MOUSEMOVE */
408  EXPECT_TME_FLAGS(hWnd3, TME_LEAVE); /* all flags are removed */
409  COMPARE_CACHE(mouseleave3to2_dropmousell_chain); /* we get no WM_MOUSELEAVE */
411 
412  FlushMessages();
414 
415  /* the mouse leaves hwnd3 and moves to hwnd2 and mouse message is dropped by WH_MOUSE */
416  ignore_mouse = TRUE;
417  MOVE_CURSOR(220,220);
418  FLUSH_MESSAGES(QS_MOUSEMOVE, QS_TIMER); /* WH_MOUSE drops WM_MOUSEMOVE */
419  EXPECT_TME_FLAGS(hWnd3, 0); /* all flags are removed */
420  COMPARE_CACHE(mouseleave3to2_dropmouse_chain); /* we get no WM_MOUSELEAVE */
422 
423  /* after WH_MOUSE drops WM_MOUSEMOVE, WM_MOUSELEAVE is still in the queue */
426 
427  FlushMessages();
429 
431 }
432 
434 {
436 }
#define WH_MOUSE
Definition: winuser.h:37
struct tagHOOK HOOK
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define trace(...)
Definition: kmt_test.h:217
#define WM_IME_NOTIFY
Definition: winuser.h:1806
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
Definition: tftpd.h:59
#define PeekMessage
Definition: winuser.h:5696
#define TRUE
Definition: types.h:120
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
#define FLUSH_MESSAGES(expected, notexpected)
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
#define WM_SYSTIMER
Definition: comctl32.h:111
HHOOK hMouseHookLL
Definition: msgtrace.h:14
BOOL WINAPI Rectangle(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
LRESULT CALLBACK TmeTestProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
#define WM_MOUSEHOVER
Definition: commctrl.h:4945
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
#define WM_GETTEXT
Definition: winuser.h:1600
DWORD TmeQuery(HWND hwnd)
#define CALLBACK
Definition: compat.h:27
BOOL WINAPI UpdateWindow(_In_ HWND)
HWND hWnd
Definition: settings.c:17
LONG top
Definition: windef.h:292
#define QS_TIMER
Definition: winuser.h:893
HHOOK hMouseHook
static LRESULT CALLBACK MouseLLHookProc(int nCode, WPARAM wParam, LPARAM lParam)
#define WM_NCHITTEST
Definition: winuser.h:1668
UINT_PTR WPARAM
Definition: windef.h:207
#define EXPECT_TME_FLAGS(hWnd, expected)
#define WS_CHILD
Definition: pedump.c:617
LONG left
Definition: windef.h:291
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
LONG right
Definition: windef.h:293
BOOL WINAPI DestroyWindow(_In_ HWND)
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4185
static LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
WPARAM wParam
Definition: combotst.c:138
#define ID_TME_TIMER
Definition: undocuser.h:79
BOOL WINAPI TrackMouseEvent(_Inout_ LPTRACKMOUSEEVENT)
#define WH_MOUSE_LL
Definition: winuser.h:44
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
static BOOL IseKeyMsg(UINT msg)
Definition: msgtrace.h:52
MSG_ENTRY mousemove2_chain[]
#define WM_SETCURSOR
Definition: winuser.h:1618
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
#define WM_MOUSELEAVE
Definition: commctrl.h:4946
#define ok(value,...)
smooth NULL
Definition: ftsmooth.c:416
LONG_PTR LPARAM
Definition: windef.h:208
MSG_ENTRY mousehover3_droptimer_chain[]
HWND hWnd2
MSG_ENTRY mouseleave2to3_chain[]
#define SW_SHOW
Definition: winuser.h:769
DWORD WINAPI GetCurrentThreadId(VOID)
Definition: thread.c:420
#define DefWindowProc
Definition: ros2win.h:31
static __inline ATOM RegisterSimpleClass(WNDPROC lpfnWndProc, LPCWSTR lpszClassName)
static int get_iwnd(HWND hWnd)
#define COMPARE_CACHE(msg_chain)
Definition: msgtrace.h:57
#define WM_IME_SETCONTEXT
Definition: winuser.h:1805
int ignore_timer
#define TME_QUERY
Definition: commctrl.h:4954
static void TmeStartTracking(HWND hwnd, DWORD Flags)
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WM_PAINT
Definition: winuser.h:1602
HWND hWnd1
int ret
Definition: msgtrace.h:7
void Test_TrackMouseEvent()
static const WCHAR L[]
Definition: oid.c:1250
#define QS_MOUSEMOVE
Definition: winuser.h:886
#define EMPTY_CACHE()
Definition: msgtrace.h:59
#define WM_USER
Definition: winuser.h:1856
BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK)
MSG_ENTRY mousehover3_nomove_chain[]
START_TEST(TrackMouseEvent)
static BOOL IsDWmMsg(UINT msg)
Definition: msgtrace.h:39
MSG_ENTRY mouseleave3to2_dropmouse_chain[]
LRESULT WINAPI CallNextHookEx(_In_opt_ HHOOK, _In_ int, _In_ WPARAM, _In_ LPARAM)
MSG_ENTRY mouseleave3to2_dropmousell_chain[]
#define SW_SHOWNORMAL
Definition: winuser.h:764
int ignore_mousell
MSG_ENTRY mouseleave3_remainging_chain[]
#define TME_HOVER
Definition: commctrl.h:4951
HWND hWnd3
#define TME_LEAVE
Definition: commctrl.h:4952
#define QS_POSTMESSAGE
Definition: winuser.h:888
static void FlushMessages()
unsigned int UINT
Definition: ndis.h:50
#define WM_MOUSEMOVE
Definition: winuser.h:1751
static void destroy_test_window()
Definition: msgtrace.h:6
static void create_test_windows()
#define msg(x)
Definition: auth_time.c:54
HHOOK WINAPI SetWindowsHookExW(_In_ int, _In_ HOOKPROC, _In_opt_ HINSTANCE, _In_ DWORD)
#define RECORD_MESSAGE(...)
Definition: msgtrace.h:60
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:845
LONG bottom
Definition: windef.h:294
#define MOVE_CURSOR(x, y)
#define PM_REMOVE
Definition: winuser.h:1182
#define HTCLIENT
Definition: winuser.h:2429
MSG_ENTRY mouseleave2to1_chain[]
LONG_PTR LRESULT
Definition: windef.h:209
MSG_ENTRY mousehover3_chain[]
MSG_ENTRY empty_chain[]
Definition: msgtrace.c:20
LPARAM lParam
Definition: combotst.c:139
MSG_ENTRY mousehover3_dropmouse_chain[]
MSG_ENTRY mousehover2_chain[]
int ignore_mouse
MSG_ENTRY mousehover3_dropmousell_chain[]