ReactOS 0.4.15-dev-7961-gdcf9eb0
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
12static int ignore_timer = 0, ignore_mouse = 0, ignore_mousell = 0;
13
14static 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 {
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{
59 return TRUE;
60 return ret;
61}
62
64{
69 if(ignore_mouse)
70 return TRUE;
71 return ret;
72}
73
74static 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
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
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 */
169 {2, WM_NCHITTEST},
171 {2, WM_SETCURSOR},
172 {1, WM_SETCURSOR},
173 {2, WM_MOUSEMOVE, POST},
174 {0,0}};
175
176/* the mouse hovers hwnd2 */
179 {2, WM_NCHITTEST},
181 {2, WM_SETCURSOR},
182 {1, WM_SETCURSOR},
183 {2, WM_MOUSEMOVE, POST},
185 {2, WM_MOUSEHOVER, POST},
186 {0,0}};
187
188/* the mouse leaves hwnd2 and moves to hwnd1 */
191 {1, WM_NCHITTEST},
193 {1, WM_SETCURSOR},
194 {1, WM_MOUSEMOVE, POST},
195 {2, WM_MOUSELEAVE, POST},
196 {0,0}};
197
198/* the mouse leaves hwnd2 and moves to hwnd3 */
201 {3, WM_NCHITTEST},
203 {3, WM_SETCURSOR},
204 {1, WM_SETCURSOR},
205 {3, WM_MOUSEMOVE, POST},
206 {2, WM_MOUSELEAVE, POST},
207 {0,0}};
208
209/* the mouse hovers hwnd3 */
212 {3, WM_NCHITTEST},
214 {3, WM_SETCURSOR},
215 {1, WM_SETCURSOR},
216 {3, WM_MOUSEMOVE, POST},
218 {3, WM_MOUSEHOVER, POST},
219 {0,0}};
220
221/* the mouse hovers hwnd3 without moving */
224 {3, WM_MOUSEHOVER, POST},
225 {0,0}};
226
227/* the mouse hovers hwnd3 and the timer is not dispatched */
230 {3, WM_NCHITTEST},
232 {3, WM_SETCURSOR},
233 {1, WM_SETCURSOR},
234 {3, WM_MOUSEMOVE, POST},
236 {0,0}};
237
238/* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE */
241 {3, WM_NCHITTEST},
244 {3, WM_MOUSEHOVER, POST},
245 {0,0}};
246
247/* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE_LL */
251 {3, WM_MOUSEHOVER, POST},
252 {0,0}};
253
254/* the mouse leaves hwnd3 and moves to hwnd2 and mouse message is dropped by WH_MOUSE */
257 {2, WM_NCHITTEST},
259 {0,0}};
260
261/* the mouse leaves hwnd3 and moves to hwnd2 and mouse message is dropped by WH_MOUSE_LL */
264 {0,0}};
265
266/* after WH_MOUSE drops WM_MOUSEMOVE, WM_MOUSELEAVE is still in the queue */
268 {3, WM_MOUSELEAVE, POST},
269 {0,0}};
270
272{
273 MOVE_CURSOR(0,0);
276 EMPTY_CACHE();
277
278 /* the mouse moves over hwnd2 */
279 MOVE_CURSOR(220,220);
283
284 /* Begin tracking mouse events for hWnd2 */
289
290 /* the mouse hovers hwnd2 */
291 MOVE_CURSOR(221, 221);
292 Sleep(100);
297
298 /* the mouse leaves hwnd2 and moves to hwnd1 */
299 MOVE_CURSOR(150, 150);
304
307
308 /* the mouse moves over hwnd2 */
309 MOVE_CURSOR(220,220);
313
316
317 /* Begin tracking mouse events for hWnd2 */
325
326 /* the mouse moves from hwnd2 to the intersection of hwnd2 and hwnd3 */
327 MOVE_CURSOR(300,300);
331
334
335 /* the mouse moves from hwnd2 to hwnd3 */
336 MOVE_CURSOR(400,400);
340
343
344 /* Begin tracking mouse events for hWnd3 */
349
350 /* the mouse hovers hwnd3 */
351 MOVE_CURSOR(401,401);
352 Sleep(100);
357
360
361 /* Begin tracking mouse events for hWnd3 */
366
367 /* make sure that the timer will fire before the mouse moves */
368 Sleep(100);
372
373 Sleep(100);
376
377 /* the mouse hovers hwnd3 and the timer is not dispatched*/
380 MOVE_CURSOR(400,400);
381 Sleep(100);
383 FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0); /* the loop drops WM_SYSTIMER */
384 EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE); /* TME_HOVER is still active */
385 COMPARE_CACHE(mousehover3_droptimer_chain); /* we get no WM_MOUSEHOVER */
387
388 /* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE_LL */
390 MOVE_CURSOR(402,402);
391 Sleep(100);
393 FLUSH_MESSAGES(QS_TIMER, QS_MOUSEMOVE); /* WH_MOUSE_LL drops WM_MOUSEMOVE */
395 COMPARE_CACHE(mousehover3_dropmousell_chain); /* we get WM_MOUSEHOVER normaly */
397
400
401 /* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE */
404 MOVE_CURSOR(401,401);
405 Sleep(100);
407 FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0); /* WH_MOUSE drops WM_MOUSEMOVE */
409 COMPARE_CACHE(mousehover3_dropmouse_chain); /* we get WM_MOUSEHOVER normaly */
411
414
415 /* the mouse leaves hwnd3 and moves to hwnd2 and mouse message is dropped by WH_MOUSE_LL */
418 MOVE_CURSOR(220,220);
419 FLUSH_MESSAGES(0, QS_MOUSEMOVE|QS_TIMER); /* WH_MOUSE drops WM_MOUSEMOVE */
420 EXPECT_TME_FLAGS(hWnd3, TME_LEAVE); /* all flags are removed */
421 COMPARE_CACHE(mouseleave3to2_dropmousell_chain); /* we get no WM_MOUSELEAVE */
423
426
427 /* the mouse leaves hwnd3 and moves to hwnd2 and mouse message is dropped by WH_MOUSE */
429 MOVE_CURSOR(220,220);
430 FLUSH_MESSAGES(QS_MOUSEMOVE, QS_TIMER); /* WH_MOUSE drops WM_MOUSEMOVE */
431 EXPECT_TME_FLAGS(hWnd3, 0); /* all flags are removed */
432 COMPARE_CACHE(mouseleave3to2_dropmouse_chain); /* we get no WM_MOUSELEAVE */
434
435 /* after WH_MOUSE drops WM_MOUSEMOVE, WM_MOUSELEAVE is still in the queue */
438
441
443}
444
446{
448}
static MSG_ENTRY mousehover3_nomove_chain[]
static MSG_ENTRY mouseleave3to2_dropmouse_chain[]
static void FlushMessages()
void Test_TrackMouseEvent()
static HHOOK hMouseHook
static MSG_ENTRY mousehover3_droptimer_chain[]
DWORD TmeQuery(HWND hwnd)
static MSG_ENTRY mouseleave3to2_dropmousell_chain[]
#define MOVE_CURSOR(x, y)
static HHOOK hMouseHookLL
static HWND hWnd3
static int get_iwnd(HWND hWnd)
LRESULT CALLBACK TmeTestProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
static HWND hWnd1
static void TmeStartTracking(HWND hwnd, DWORD Flags)
static MSG_ENTRY mouseleave2to1_chain[]
static void destroy_test_window()
static MSG_ENTRY mousehover3_chain[]
#define EXPECT_TME_FLAGS(hWnd, expected)
static MSG_ENTRY mousehover3_dropmouse_chain[]
static MSG_ENTRY mousehover3_dropmousell_chain[]
static LRESULT CALLBACK MouseLLHookProc(int nCode, WPARAM wParam, LPARAM lParam)
static MSG_ENTRY mousemove2_chain[]
static int ignore_timer
static HWND hWnd2
static LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
#define FLUSH_MESSAGES(expected, notexpected)
static void create_test_windows()
static int ignore_mouse
static MSG_ENTRY mouseleave2to3_chain[]
static MSG_ENTRY mousehover2_chain[]
static int ignore_mousell
static MSG_ENTRY mouseleave3_remainging_chain[]
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define WM_SYSTIMER
Definition: comctl32.h:119
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CALLBACK
Definition: compat.h:35
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
unsigned long DWORD
Definition: ntddk_ex.h:95
struct tagHOOK HOOK
MSG_ENTRY empty_chain[]
Definition: msgtrace.c:20
#define EMPTY_CACHE()
Definition: msgtrace.h:59
static BOOL IsDWmMsg(UINT msg)
Definition: msgtrace.h:39
#define RECORD_MESSAGE(...)
Definition: msgtrace.h:60
#define COMPARE_CACHE(msg_chain)
Definition: msgtrace.h:57
@ POST
Definition: msgtrace.h:7
@ SENT
Definition: msgtrace.h:6
static BOOL IseKeyMsg(UINT msg)
Definition: msgtrace.h:52
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
#define WS_CHILD
Definition: pedump.c:617
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
#define TME_LEAVE
Definition: commctrl.h:4981
#define WM_MOUSELEAVE
Definition: commctrl.h:4975
#define WM_MOUSEHOVER
Definition: commctrl.h:4974
#define TME_QUERY
Definition: commctrl.h:4983
#define TME_HOVER
Definition: commctrl.h:4980
#define DefWindowProc
Definition: ros2win.h:31
Definition: msgtrace.h:15
Definition: tftpd.h:60
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
#define ID_TME_TIMER
Definition: undocuser.h:81
static __inline ATOM RegisterSimpleClass(WNDPROC lpfnWndProc, LPCWSTR lpszClassName)
int ret
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
BOOL WINAPI Rectangle(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
#define SW_SHOWNORMAL
Definition: winuser.h:770
#define WM_PAINT
Definition: winuser.h:1620
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
#define QS_MOUSEMOVE
Definition: winuser.h:875
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
#define WM_IME_NOTIFY
Definition: winuser.h:1830
#define QS_TIMER
Definition: winuser.h:878
HHOOK WINAPI SetWindowsHookExW(_In_ int, _In_ HOOKPROC, _In_opt_ HINSTANCE, _In_ DWORD)
#define WM_NCHITTEST
Definition: winuser.h:1686
#define WM_MOUSEMOVE
Definition: winuser.h:1775
#define WM_GETTEXT
Definition: winuser.h:1618
BOOL WINAPI TrackMouseEvent(_Inout_ LPTRACKMOUSEEVENT)
#define WM_IME_SETCONTEXT
Definition: winuser.h:1829
#define WH_MOUSE_LL
Definition: winuser.h:44
#define WH_MOUSE
Definition: winuser.h:37
BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK)
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
#define PM_REMOVE
Definition: winuser.h:1196
BOOL WINAPI UpdateWindow(_In_ HWND)
#define HTCLIENT
Definition: winuser.h:2475
#define PeekMessage
Definition: winuser.h:5830
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4316
#define QS_POSTMESSAGE
Definition: winuser.h:877
LRESULT WINAPI CallNextHookEx(_In_opt_ HHOOK, _In_ int, _In_ WPARAM, _In_ LPARAM)
#define WM_SETCURSOR
Definition: winuser.h:1636
#define WM_USER
Definition: winuser.h:1895
#define SW_SHOW
Definition: winuser.h:775
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
BOOL WINAPI DestroyWindow(_In_ HWND)
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170