1c2c66affSColin Finck /*
2c2c66affSColin Finck  * PROJECT:         ReactOS api tests
3c2c66affSColin Finck  * LICENSE:         GPL - See COPYING in the top level directory
4c2c66affSColin Finck  * PURPOSE:         Test for TrackMouseEvent
5c2c66affSColin Finck  * PROGRAMMERS:     Giannis Adamopoulos
6c2c66affSColin Finck  */
7c2c66affSColin Finck 
8c39b0fc6SAmine Khaldi #include "precomp.h"
9c2c66affSColin Finck 
10*97f075a2SVictor Perevertkin static HWND hWnd1, hWnd2, hWnd3;
11*97f075a2SVictor Perevertkin static HHOOK hMouseHookLL, hMouseHook;
12*97f075a2SVictor Perevertkin static int ignore_timer = 0, ignore_mouse = 0, ignore_mousell = 0;
13c2c66affSColin Finck 
get_iwnd(HWND hWnd)14c2c66affSColin Finck static int get_iwnd(HWND hWnd)
15c2c66affSColin Finck {
16c2c66affSColin Finck     if(hWnd == hWnd1) return 1;
17c2c66affSColin Finck     else if(hWnd == hWnd2) return 2;
18c2c66affSColin Finck     else if(hWnd == hWnd3) return 3;
19c2c66affSColin Finck     else return 0;
20c2c66affSColin Finck }
21c2c66affSColin Finck 
TmeTestProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)22c2c66affSColin Finck LRESULT CALLBACK TmeTestProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
23c2c66affSColin Finck {
24c2c66affSColin Finck     int iwnd = get_iwnd(hWnd);
25c2c66affSColin Finck 
26c2c66affSColin Finck     if(message == WM_PAINT)
27c2c66affSColin Finck     {
28c2c66affSColin Finck         PAINTSTRUCT ps;
29c2c66affSColin Finck         BeginPaint(hWnd, &ps);
30c2c66affSColin Finck         Rectangle(ps.hdc,  ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom);
31c2c66affSColin Finck         EndPaint(hWnd, &ps);
32c2c66affSColin Finck     }
33c2c66affSColin Finck 
34c2c66affSColin Finck     if(message > WM_USER || !iwnd || IsDWmMsg(message) || IseKeyMsg(message))
35c2c66affSColin Finck         return DefWindowProc(hWnd, message, wParam, lParam);
36c2c66affSColin Finck 
37c2c66affSColin Finck     switch(message)
38c2c66affSColin Finck     {
39c2c66affSColin Finck     case WM_IME_SETCONTEXT:
40c2c66affSColin Finck     case WM_IME_NOTIFY :
41c2c66affSColin Finck     case WM_GETICON :
42c2c66affSColin Finck     case WM_GETTEXT:
43c2c66affSColin Finck         break;
44c2c66affSColin Finck     case WM_SYSTIMER:
45c2c66affSColin Finck         ok(0, "Got unexpected WM_SYSTIMER in the winproc. wParam=%d\n", wParam);
46c2c66affSColin Finck         break;
47c2c66affSColin Finck     default:
48c2c66affSColin Finck         RECORD_MESSAGE(iwnd, message, SENT, 0,0);
49c2c66affSColin Finck     }
50c2c66affSColin Finck     return DefWindowProc(hWnd, message, wParam, lParam);
51c2c66affSColin Finck }
52c2c66affSColin Finck 
MouseLLHookProc(int nCode,WPARAM wParam,LPARAM lParam)53c2c66affSColin Finck static LRESULT CALLBACK MouseLLHookProc(int nCode, WPARAM wParam, LPARAM lParam)
54c2c66affSColin Finck {
55c2c66affSColin Finck     LRESULT ret;
56c2c66affSColin Finck     RECORD_MESSAGE(0, WH_MOUSE_LL, HOOK, wParam, 0);
57c2c66affSColin Finck     ret = CallNextHookEx(hMouseHookLL, nCode, wParam, lParam);
58c2c66affSColin Finck     if(ignore_mousell)
59c2c66affSColin Finck         return TRUE;
60c2c66affSColin Finck     return ret;
61c2c66affSColin Finck }
62c2c66affSColin Finck 
MouseHookProc(int nCode,WPARAM wParam,LPARAM lParam)63c2c66affSColin Finck static LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
64c2c66affSColin Finck {
65c2c66affSColin Finck     MOUSEHOOKSTRUCT *hs = (MOUSEHOOKSTRUCT*) lParam;
66c2c66affSColin Finck     LRESULT ret;
67c2c66affSColin Finck     RECORD_MESSAGE(get_iwnd(hs->hwnd), WH_MOUSE, HOOK, wParam, hs->wHitTestCode);
68c2c66affSColin Finck     ret = CallNextHookEx(hMouseHook, nCode, wParam, lParam);
69c2c66affSColin Finck     if(ignore_mouse)
70c2c66affSColin Finck         return TRUE;
71c2c66affSColin Finck     return ret;
72c2c66affSColin Finck }
73c2c66affSColin Finck 
FlushMessages()74c2c66affSColin Finck static void FlushMessages()
75c2c66affSColin Finck {
76c2c66affSColin Finck     MSG msg;
77c2c66affSColin Finck 
78c2c66affSColin Finck     while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
79c2c66affSColin Finck     {
80c2c66affSColin Finck         int iwnd = get_iwnd(msg.hwnd);
81c2c66affSColin Finck         if(iwnd)
82c2c66affSColin Finck         {
83c2c66affSColin Finck             if(msg.message == WM_SYSTIMER)
84c2c66affSColin Finck             {
85c2c66affSColin Finck                 RECORD_MESSAGE(iwnd, msg.message, POST,msg.wParam,0);
86c2c66affSColin Finck                 if(ignore_timer)
87c2c66affSColin Finck                     continue;
88c2c66affSColin Finck             }
89c2c66affSColin Finck             else if(!(msg.message > WM_USER || !iwnd || IsDWmMsg(msg.message) || IseKeyMsg(msg.message)))
90c2c66affSColin Finck                 RECORD_MESSAGE(iwnd, msg.message, POST,0,0);
91c2c66affSColin Finck         }
92c2c66affSColin Finck         DispatchMessageA( &msg );
93c2c66affSColin Finck     }
94c2c66affSColin Finck }
95c2c66affSColin Finck 
96c2c66affSColin Finck #define FLUSH_MESSAGES(expected, notexpected) \
97c2c66affSColin Finck     { EXPECT_QUEUE_STATUS(expected, notexpected);\
98c2c66affSColin Finck       FlushMessages();\
99c2c66affSColin Finck     }
100c2c66affSColin Finck 
create_test_windows()101c2c66affSColin Finck static void create_test_windows()
102c2c66affSColin Finck {
103c2c66affSColin Finck     hMouseHookLL = SetWindowsHookExW(WH_MOUSE_LL, MouseLLHookProc, GetModuleHandleW( NULL ), 0);
104c2c66affSColin Finck     hMouseHook = SetWindowsHookExW(WH_MOUSE, MouseHookProc, GetModuleHandleW( NULL ), GetCurrentThreadId());
105c2c66affSColin Finck     ok(hMouseHook!=NULL,"failed to set hook\n");
106c2c66affSColin Finck     ok(hMouseHookLL!=NULL,"failed to set hook\n");
107c2c66affSColin Finck 
108c2c66affSColin Finck     RegisterSimpleClass(TmeTestProc, L"testClass");
109c2c66affSColin Finck 
110c2c66affSColin Finck     hWnd1 = CreateWindowW(L"testClass", L"test", WS_OVERLAPPEDWINDOW,
111c2c66affSColin Finck                          100, 100, 500, 500, NULL, NULL, 0, NULL);
112c2c66affSColin Finck     hWnd2 = CreateWindowW(L"testClass", L"test", WS_CHILD,
113c2c66affSColin Finck                          50, 50, 200, 200, hWnd1, NULL, 0, NULL);
114c2c66affSColin Finck     hWnd3 = CreateWindowW(L"testClass", L"test", WS_CHILD,
115c2c66affSColin Finck                          150, 150, 200, 200, hWnd1, NULL, 0, NULL);
116c2c66affSColin Finck 
117c2c66affSColin Finck     ShowWindow(hWnd1, SW_SHOW);
118c2c66affSColin Finck     UpdateWindow(hWnd1);
119c2c66affSColin Finck     ShowWindow(hWnd2, SW_SHOW);
120c2c66affSColin Finck     UpdateWindow(hWnd2);
121c2c66affSColin Finck     ShowWindow(hWnd3, SW_SHOWNORMAL);
122c2c66affSColin Finck     UpdateWindow(hWnd3);
123c2c66affSColin Finck     //SetWindowPos (hWnd3, HWND_TOP, 0,0,0,0, SWP_NOMOVE|SWP_NOREDRAW);
124c2c66affSColin Finck }
125c2c66affSColin Finck 
destroy_test_window()126c2c66affSColin Finck static void destroy_test_window()
127c2c66affSColin Finck {
128c2c66affSColin Finck     DestroyWindow(hWnd1);
129c2c66affSColin Finck     UnregisterClassW(L"testClass", 0);
130c2c66affSColin Finck     UnhookWindowsHookEx(hMouseHookLL);
131c2c66affSColin Finck     UnhookWindowsHookEx(hMouseHook);
132c2c66affSColin Finck }
133c2c66affSColin Finck 
TmeStartTracking(HWND hwnd,DWORD Flags)134c2c66affSColin Finck static void TmeStartTracking(HWND hwnd, DWORD Flags)
135c2c66affSColin Finck {
136c2c66affSColin Finck     TRACKMOUSEEVENT tme;
137c2c66affSColin Finck     tme.cbSize = sizeof(tme);
138c2c66affSColin Finck     tme.dwFlags = Flags;
139c2c66affSColin Finck     tme.hwndTrack  = hwnd;
140c2c66affSColin Finck     tme.dwHoverTime = 1;
141c2c66affSColin Finck     if(!TrackMouseEvent(&tme))
142c2c66affSColin Finck     {
143c2c66affSColin Finck         trace("failed!\n");
144c2c66affSColin Finck     }
145c2c66affSColin Finck }
146c2c66affSColin Finck 
TmeQuery(HWND hwnd)147c2c66affSColin Finck DWORD TmeQuery(HWND hwnd)
148c2c66affSColin Finck {
149c2c66affSColin Finck     TRACKMOUSEEVENT tme;
150c2c66affSColin Finck     tme.cbSize = sizeof(tme);
151c2c66affSColin Finck     tme.dwFlags = TME_QUERY|TME_HOVER|TME_LEAVE;
152c2c66affSColin Finck     tme.hwndTrack  = hwnd;
153c2c66affSColin Finck     TrackMouseEvent(&tme);
154c2c66affSColin Finck     return tme.dwFlags;
155c2c66affSColin Finck }
156c2c66affSColin Finck 
157c2c66affSColin Finck #define EXPECT_TME_FLAGS(hWnd, expected)                                                                 \
158c2c66affSColin Finck     { DWORD flags = TmeQuery(hWnd);                                                                      \
159c2c66affSColin Finck       ok(flags == (expected),"wrong tme flags. expected %li, and got %li\n", (DWORD)(expected), flags);  \
160c2c66affSColin Finck     }
161c2c66affSColin Finck 
162c2c66affSColin Finck #define MOVE_CURSOR(x,y) mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE ,                           \
163c2c66affSColin Finck                                      x*(65535/GetSystemMetrics(SM_CXVIRTUALSCREEN)),                     \
164c2c66affSColin Finck                                      y*(65535/GetSystemMetrics(SM_CYVIRTUALSCREEN)) , 0,0);
165c2c66affSColin Finck 
166c2c66affSColin Finck /* the mouse moves over hwnd2 */
167*97f075a2SVictor Perevertkin static MSG_ENTRY mousemove2_chain[]={
168*97f075a2SVictor Perevertkin     {0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE},
169c2c66affSColin Finck     {2, WM_NCHITTEST},
170c2c66affSColin Finck     {2, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT},
171c2c66affSColin Finck     {2, WM_SETCURSOR},
172c2c66affSColin Finck     {1, WM_SETCURSOR},
173c2c66affSColin Finck     {2, WM_MOUSEMOVE, POST},
174c2c66affSColin Finck     {0,0}};
175c2c66affSColin Finck 
176c2c66affSColin Finck /* the mouse hovers hwnd2 */
177*97f075a2SVictor Perevertkin static MSG_ENTRY mousehover2_chain[]={
178*97f075a2SVictor Perevertkin     {0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE},
179c2c66affSColin Finck     {2, WM_NCHITTEST},
180c2c66affSColin Finck     {2, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT},
181c2c66affSColin Finck     {2, WM_SETCURSOR},
182c2c66affSColin Finck     {1, WM_SETCURSOR},
183c2c66affSColin Finck     {2, WM_MOUSEMOVE, POST},
184c2c66affSColin Finck     {2, WM_SYSTIMER, POST, ID_TME_TIMER},
185c2c66affSColin Finck     {2, WM_MOUSEHOVER, POST},
186c2c66affSColin Finck     {0,0}};
187c2c66affSColin Finck 
188c2c66affSColin Finck /* the mouse leaves hwnd2 and moves to hwnd1 */
189*97f075a2SVictor Perevertkin static MSG_ENTRY mouseleave2to1_chain[]={
190*97f075a2SVictor Perevertkin     {0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE},
191c2c66affSColin Finck     {1, WM_NCHITTEST},
192c2c66affSColin Finck     {1, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT},
193c2c66affSColin Finck     {1, WM_SETCURSOR},
194c2c66affSColin Finck     {1, WM_MOUSEMOVE, POST},
195c2c66affSColin Finck     {2, WM_MOUSELEAVE, POST},
196c2c66affSColin Finck     {0,0}};
197c2c66affSColin Finck 
198c2c66affSColin Finck /* the mouse leaves hwnd2 and moves to hwnd3 */
199*97f075a2SVictor Perevertkin static MSG_ENTRY mouseleave2to3_chain[]={
200*97f075a2SVictor Perevertkin     {0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE},
201c2c66affSColin Finck     {3, WM_NCHITTEST},
202c2c66affSColin Finck     {3, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT},
203c2c66affSColin Finck     {3, WM_SETCURSOR},
204c2c66affSColin Finck     {1, WM_SETCURSOR},
205c2c66affSColin Finck     {3, WM_MOUSEMOVE, POST},
206c2c66affSColin Finck     {2, WM_MOUSELEAVE, POST},
207c2c66affSColin Finck     {0,0}};
208c2c66affSColin Finck 
209c2c66affSColin Finck /* the mouse hovers hwnd3 */
210*97f075a2SVictor Perevertkin static MSG_ENTRY mousehover3_chain[]={
211*97f075a2SVictor Perevertkin     {0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE},
212c2c66affSColin Finck     {3, WM_NCHITTEST},
213c2c66affSColin Finck     {3, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT},
214c2c66affSColin Finck     {3, WM_SETCURSOR},
215c2c66affSColin Finck     {1, WM_SETCURSOR},
216c2c66affSColin Finck     {3, WM_MOUSEMOVE, POST},
217c2c66affSColin Finck     {3, WM_SYSTIMER, POST, ID_TME_TIMER},
218c2c66affSColin Finck     {3, WM_MOUSEHOVER, POST},
219c2c66affSColin Finck     {0,0}};
220c2c66affSColin Finck 
221c2c66affSColin Finck /* the mouse hovers hwnd3 without moving */
222*97f075a2SVictor Perevertkin static MSG_ENTRY mousehover3_nomove_chain[]={
223*97f075a2SVictor Perevertkin     {3, WM_SYSTIMER, POST, ID_TME_TIMER},
224c2c66affSColin Finck     {3, WM_MOUSEHOVER, POST},
225c2c66affSColin Finck     {0,0}};
226c2c66affSColin Finck 
227c2c66affSColin Finck /* the mouse hovers hwnd3 and the timer is not dispatched */
228*97f075a2SVictor Perevertkin static MSG_ENTRY mousehover3_droptimer_chain[]={
229*97f075a2SVictor Perevertkin     {0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE},
230c2c66affSColin Finck     {3, WM_NCHITTEST},
231c2c66affSColin Finck     {3, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT},
232c2c66affSColin Finck     {3, WM_SETCURSOR},
233c2c66affSColin Finck     {1, WM_SETCURSOR},
234c2c66affSColin Finck     {3, WM_MOUSEMOVE, POST},
235c2c66affSColin Finck     {3, WM_SYSTIMER, POST, ID_TME_TIMER},
236c2c66affSColin Finck     {0,0}};
237c2c66affSColin Finck 
238c2c66affSColin Finck /* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE */
239*97f075a2SVictor Perevertkin static MSG_ENTRY mousehover3_dropmouse_chain[]={
240*97f075a2SVictor Perevertkin     {0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE},
241c2c66affSColin Finck     {3, WM_NCHITTEST},
242c2c66affSColin Finck     {3, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT},
243c2c66affSColin Finck     {3, WM_SYSTIMER, POST, ID_TME_TIMER},
244c2c66affSColin Finck     {3, WM_MOUSEHOVER, POST},
245c2c66affSColin Finck     {0,0}};
246c2c66affSColin Finck 
247c2c66affSColin Finck /* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE_LL */
248*97f075a2SVictor Perevertkin static MSG_ENTRY mousehover3_dropmousell_chain[]={
249*97f075a2SVictor Perevertkin     {0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE},
250c2c66affSColin Finck     {3, WM_SYSTIMER, POST, ID_TME_TIMER},
251c2c66affSColin Finck     {3, WM_MOUSEHOVER, POST},
252c2c66affSColin Finck     {0,0}};
253c2c66affSColin Finck 
254c2c66affSColin Finck /* the mouse leaves hwnd3 and moves to hwnd2 and mouse message is dropped by WH_MOUSE */
255*97f075a2SVictor Perevertkin static MSG_ENTRY mouseleave3to2_dropmouse_chain[]={
256*97f075a2SVictor Perevertkin     {0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE},
257c2c66affSColin Finck     {2, WM_NCHITTEST},
258c2c66affSColin Finck     {2, WH_MOUSE,HOOK, WM_MOUSEMOVE, HTCLIENT},
259c2c66affSColin Finck     {0,0}};
260c2c66affSColin Finck 
261c2c66affSColin Finck /* the mouse leaves hwnd3 and moves to hwnd2 and mouse message is dropped by WH_MOUSE_LL */
262*97f075a2SVictor Perevertkin static MSG_ENTRY mouseleave3to2_dropmousell_chain[]={
263*97f075a2SVictor Perevertkin     {0, WH_MOUSE_LL, HOOK, WM_MOUSEMOVE},
264c2c66affSColin Finck     {0,0}};
265c2c66affSColin Finck 
266c2c66affSColin Finck /* after WH_MOUSE drops WM_MOUSEMOVE, WM_MOUSELEAVE is still in the queue */
267*97f075a2SVictor Perevertkin static MSG_ENTRY mouseleave3_remainging_chain[]={
268*97f075a2SVictor Perevertkin     {3, WM_MOUSELEAVE, POST},
269c2c66affSColin Finck     {0,0}};
270c2c66affSColin Finck 
Test_TrackMouseEvent()271c2c66affSColin Finck void Test_TrackMouseEvent()
272c2c66affSColin Finck {
273c2c66affSColin Finck     MOVE_CURSOR(0,0);
274c2c66affSColin Finck     create_test_windows();
275c2c66affSColin Finck     FlushMessages();
276c2c66affSColin Finck     EMPTY_CACHE();
277c2c66affSColin Finck 
278c2c66affSColin Finck     /* the mouse moves over hwnd2 */
279c2c66affSColin Finck     MOVE_CURSOR(220,220);
280c2c66affSColin Finck     FlushMessages();
281c2c66affSColin Finck     COMPARE_CACHE(mousemove2_chain);
282c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd2, 0);
283c2c66affSColin Finck 
284c2c66affSColin Finck     /* Begin tracking mouse events for hWnd2 */
285c2c66affSColin Finck     TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE);
286c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE);
287c2c66affSColin Finck     FlushMessages();
288c2c66affSColin Finck     COMPARE_CACHE(empty_chain);
289c2c66affSColin Finck 
290c2c66affSColin Finck     /* the mouse hovers hwnd2 */
291c2c66affSColin Finck     MOVE_CURSOR(221, 221);
292c2c66affSColin Finck     Sleep(100);
293c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE);
294c2c66affSColin Finck     FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0);
295c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd2, TME_LEAVE);
296c2c66affSColin Finck     COMPARE_CACHE(mousehover2_chain);
297c2c66affSColin Finck 
298c2c66affSColin Finck     /* the mouse leaves hwnd2 and moves to hwnd1 */
299c2c66affSColin Finck     MOVE_CURSOR(150, 150);
300c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd2, TME_LEAVE);
301c2c66affSColin Finck     FLUSH_MESSAGES(QS_MOUSEMOVE,QS_TIMER );
302c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd2, 0);
303c2c66affSColin Finck     COMPARE_CACHE(mouseleave2to1_chain);
304c2c66affSColin Finck 
305c2c66affSColin Finck     FlushMessages();
306c2c66affSColin Finck     COMPARE_CACHE(empty_chain);
307c2c66affSColin Finck 
308c2c66affSColin Finck     /* the mouse moves over hwnd2 */
309c2c66affSColin Finck     MOVE_CURSOR(220,220);
310c2c66affSColin Finck     FLUSH_MESSAGES(QS_MOUSEMOVE, QS_TIMER);
311c2c66affSColin Finck     COMPARE_CACHE(mousemove2_chain);
312c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd2, 0);
313c2c66affSColin Finck 
314c2c66affSColin Finck     FlushMessages();
315c2c66affSColin Finck     COMPARE_CACHE(empty_chain);
316c2c66affSColin Finck 
317c2c66affSColin Finck     /* Begin tracking mouse events for hWnd2 */
318c2c66affSColin Finck     TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE);
319c2c66affSColin Finck     TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE);
320c2c66affSColin Finck     TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE);
321c2c66affSColin Finck     TmeStartTracking(hWnd2, TME_HOVER|TME_LEAVE);
322c2c66affSColin Finck     FLUSH_MESSAGES(0, QS_TIMER|QS_MOUSEMOVE);
323c2c66affSColin Finck     COMPARE_CACHE(empty_chain);
324c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE);
325c2c66affSColin Finck 
326c2c66affSColin Finck     /* the mouse moves from hwnd2 to the intersection of hwnd2 and hwnd3 */
327c2c66affSColin Finck     MOVE_CURSOR(300,300);
328c2c66affSColin Finck     FLUSH_MESSAGES(QS_MOUSEMOVE, QS_TIMER);
329c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE);
330c2c66affSColin Finck     COMPARE_CACHE(mousemove2_chain);
331c2c66affSColin Finck 
332c2c66affSColin Finck     FlushMessages();
333c2c66affSColin Finck     COMPARE_CACHE(empty_chain);
334c2c66affSColin Finck 
335c2c66affSColin Finck     /* the mouse moves from hwnd2 to hwnd3 */
336c2c66affSColin Finck     MOVE_CURSOR(400,400);
337c2c66affSColin Finck     FLUSH_MESSAGES(QS_MOUSEMOVE, QS_TIMER);
338c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd2, 0);
339c2c66affSColin Finck     COMPARE_CACHE(mouseleave2to3_chain);
340c2c66affSColin Finck 
341c2c66affSColin Finck     FlushMessages();
342c2c66affSColin Finck     COMPARE_CACHE(empty_chain);
343c2c66affSColin Finck 
344c2c66affSColin Finck     /* Begin tracking mouse events for hWnd3 */
345c2c66affSColin Finck     TmeStartTracking(hWnd3, TME_HOVER|TME_LEAVE);
346c2c66affSColin Finck     FLUSH_MESSAGES(0, QS_TIMER|QS_MOUSEMOVE);
347c2c66affSColin Finck     COMPARE_CACHE(empty_chain);
348c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd2, TME_HOVER|TME_LEAVE);
349c2c66affSColin Finck 
350c2c66affSColin Finck     /* the mouse hovers hwnd3 */
351c2c66affSColin Finck     MOVE_CURSOR(401,401);
352c2c66affSColin Finck     Sleep(100);
353c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE);
354c2c66affSColin Finck     FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0);
355c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd3, TME_LEAVE);
356c2c66affSColin Finck     COMPARE_CACHE(mousehover3_chain);
357c2c66affSColin Finck 
358c2c66affSColin Finck     FlushMessages();
359c2c66affSColin Finck     COMPARE_CACHE(empty_chain);
360c2c66affSColin Finck 
361c2c66affSColin Finck     /* Begin tracking mouse events for hWnd3 */
362c2c66affSColin Finck     TmeStartTracking(hWnd3, TME_HOVER );
363c2c66affSColin Finck     FLUSH_MESSAGES(0, QS_TIMER|QS_MOUSEMOVE);
364c2c66affSColin Finck     COMPARE_CACHE(empty_chain);
365c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE);
366c2c66affSColin Finck 
367c2c66affSColin Finck     /* make sure that the timer will fire before the mouse moves */
368c2c66affSColin Finck     Sleep(100);
369c2c66affSColin Finck     FlushMessages();
370c2c66affSColin Finck     COMPARE_CACHE(mousehover3_nomove_chain);
371c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd3, TME_LEAVE);
372c2c66affSColin Finck 
373c2c66affSColin Finck     Sleep(100);
374c2c66affSColin Finck     FlushMessages();
375c2c66affSColin Finck     COMPARE_CACHE(empty_chain);
376c2c66affSColin Finck 
377c2c66affSColin Finck     /* the mouse hovers hwnd3 and the timer is not dispatched*/
378c2c66affSColin Finck     TmeStartTracking(hWnd3, TME_HOVER );
379c2c66affSColin Finck     ignore_timer = TRUE;
380c2c66affSColin Finck     MOVE_CURSOR(400,400);
381c2c66affSColin Finck     Sleep(100);
382c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE);
383c2c66affSColin Finck     FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0);     /* the loop drops WM_SYSTIMER */
384c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE); /* TME_HOVER is still active  */
385c2c66affSColin Finck     COMPARE_CACHE(mousehover3_droptimer_chain);   /* we get no WM_MOUSEHOVER    */
386c2c66affSColin Finck     ignore_timer = FALSE;
387c2c66affSColin Finck 
388c2c66affSColin Finck     /* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE_LL */
389c2c66affSColin Finck     ignore_mousell = TRUE;
390c2c66affSColin Finck     MOVE_CURSOR(402,402);
391c2c66affSColin Finck     Sleep(100);
392c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE);
393c2c66affSColin Finck     FLUSH_MESSAGES(QS_TIMER, QS_MOUSEMOVE);         /* WH_MOUSE_LL drops WM_MOUSEMOVE */
394c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd3, TME_LEAVE);
395c2c66affSColin Finck     COMPARE_CACHE(mousehover3_dropmousell_chain);   /* we get WM_MOUSEHOVER normaly */
396c2c66affSColin Finck     ignore_mousell = FALSE;
397c2c66affSColin Finck 
398c2c66affSColin Finck     FlushMessages();
399c2c66affSColin Finck     COMPARE_CACHE(empty_chain);
400c2c66affSColin Finck 
401c2c66affSColin Finck     /* the mouse hovers hwnd3 and mouse message is dropped by WH_MOUSE */
402c2c66affSColin Finck     ignore_mouse = TRUE;
403c2c66affSColin Finck     TmeStartTracking(hWnd3, TME_HOVER );
404c2c66affSColin Finck     MOVE_CURSOR(401,401);
405c2c66affSColin Finck     Sleep(100);
406c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd3, TME_HOVER|TME_LEAVE);
407c2c66affSColin Finck     FLUSH_MESSAGES(QS_TIMER|QS_MOUSEMOVE, 0);     /* WH_MOUSE drops WM_MOUSEMOVE */
408c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd3, TME_LEAVE);
409c2c66affSColin Finck     COMPARE_CACHE(mousehover3_dropmouse_chain);   /* we get WM_MOUSEHOVER normaly */
410c2c66affSColin Finck     ignore_mouse = FALSE;
411c2c66affSColin Finck 
412c2c66affSColin Finck     FlushMessages();
413c2c66affSColin Finck     COMPARE_CACHE(empty_chain);
414c2c66affSColin Finck 
415c2c66affSColin Finck     /* the mouse leaves hwnd3 and moves to hwnd2 and mouse message is dropped by WH_MOUSE_LL */
416c2c66affSColin Finck     ignore_mousell = TRUE;
417c2c66affSColin Finck     TmeStartTracking(hWnd3, TME_LEAVE );
418c2c66affSColin Finck     MOVE_CURSOR(220,220);
419c2c66affSColin Finck     FLUSH_MESSAGES(0, QS_MOUSEMOVE|QS_TIMER);         /* WH_MOUSE drops WM_MOUSEMOVE */
420c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd3, TME_LEAVE);               /* all flags are removed */
421c2c66affSColin Finck     COMPARE_CACHE(mouseleave3to2_dropmousell_chain);  /* we get no WM_MOUSELEAVE */
422c2c66affSColin Finck     ignore_mousell = FALSE;
423c2c66affSColin Finck 
424c2c66affSColin Finck     FlushMessages();
425c2c66affSColin Finck     COMPARE_CACHE(empty_chain);
426c2c66affSColin Finck 
427c2c66affSColin Finck     /* the mouse leaves hwnd3 and moves to hwnd2 and mouse message is dropped by WH_MOUSE */
428c2c66affSColin Finck     ignore_mouse = TRUE;
429c2c66affSColin Finck     MOVE_CURSOR(220,220);
430c2c66affSColin Finck     FLUSH_MESSAGES(QS_MOUSEMOVE, QS_TIMER);         /* WH_MOUSE drops WM_MOUSEMOVE */
431c2c66affSColin Finck     EXPECT_TME_FLAGS(hWnd3, 0);                     /* all flags are removed */
432c2c66affSColin Finck     COMPARE_CACHE(mouseleave3to2_dropmouse_chain);  /* we get no WM_MOUSELEAVE */
433c2c66affSColin Finck     ignore_mouse = FALSE;
434c2c66affSColin Finck 
435c2c66affSColin Finck     /* after WH_MOUSE drops WM_MOUSEMOVE, WM_MOUSELEAVE is still in the queue */
436c2c66affSColin Finck     FLUSH_MESSAGES(QS_POSTMESSAGE, QS_TIMER|QS_MOUSEMOVE);
437c2c66affSColin Finck     COMPARE_CACHE(mouseleave3_remainging_chain);
438c2c66affSColin Finck 
439c2c66affSColin Finck     FlushMessages();
440c2c66affSColin Finck     COMPARE_CACHE(empty_chain);
441c2c66affSColin Finck 
442c2c66affSColin Finck     destroy_test_window();
443c2c66affSColin Finck }
444c2c66affSColin Finck 
START_TEST(TrackMouseEvent)445c2c66affSColin Finck START_TEST(TrackMouseEvent)
446c2c66affSColin Finck {
447c2c66affSColin Finck     Test_TrackMouseEvent();
448c2c66affSColin Finck }
449