1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * PURPOSE:         Test for SetCursorPos
5  * PROGRAMMERS:     Giannis Adamopoulos
6  */
7 
8 #include "precomp.h"
9 
10 static HHOOK hMouseHookLL, hMouseHook;
11 
12 struct _test_info
13 {
14     int ll_hook_called;
15     int hook_called;
16     int mouse_move_called;
17 };
18 
19 static struct _test_info info[] =
20 {
21     {0,0,0}, /* SetCursorPos without a window */
22     {1,1,0}, /* mouse_event without a window */
23     {0,1,1}, /* SetCursorPos with a window */
24     {1,1,1}, /* mouse_event with a window */
25     {0,1,1}, /* multiple SetCursorPos with a window with coalescing */
26     {0,2,2}, /* multiple SetCursorPos with a window without coalescing */
27     {2,1,1}, /* multiple mouse_event with a window with coalescing */
28     {2,2,2}, /* multiple mouse_event with a window without coalescing */
29 };
30 
31 static struct _test_info results[8];
32 static int test_no = 0;
33 
34 
MouseLLHookProc(int nCode,WPARAM wParam,LPARAM lParam)35 LRESULT CALLBACK MouseLLHookProc(int nCode, WPARAM wParam, LPARAM lParam)
36 {
37     results[test_no].ll_hook_called++;
38     return CallNextHookEx(hMouseHookLL, nCode, wParam, lParam);
39 }
40 
MouseHookProc(int nCode,WPARAM wParam,LPARAM lParam)41 LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
42 {
43     results[test_no].hook_called++;
44     return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
45 }
46 
WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)47 static LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
48 {
49     if(msg == WM_MOUSEMOVE)
50         results[test_no].mouse_move_called++;
51 
52     return DefWindowProcA( hWnd, msg, wParam, lParam );
53 }
54 
CreateTestWindow()55 static HWND CreateTestWindow()
56 {
57     MSG msg;
58     WNDCLASSA  wclass;
59     HANDLE hInstance = GetModuleHandleA( NULL );
60     HWND hWndTest;
61 
62     wclass.lpszClassName = "MouseInputTestClass";
63     wclass.style         = CS_HREDRAW | CS_VREDRAW;
64     wclass.lpfnWndProc   = WndProc;
65     wclass.hInstance     = hInstance;
66     wclass.hIcon         = LoadIconA( 0, IDI_APPLICATION );
67     wclass.hCursor       = LoadCursorA( NULL, IDC_ARROW );
68     wclass.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
69     wclass.lpszMenuName = 0;
70     wclass.cbClsExtra    = 0;
71     wclass.cbWndExtra    = 0;
72     RegisterClassA( &wclass );
73     /* create the test window that will receive the keystrokes */
74     hWndTest = CreateWindowA( wclass.lpszClassName, "MouseInputTestTest",
75                               WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 100, 100,
76                               NULL, NULL, hInstance, NULL);
77     assert( hWndTest );
78     ShowWindow( hWndTest, SW_SHOWMAXIMIZED);
79     SetWindowPos( hWndTest, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE );
80     SetForegroundWindow( hWndTest );
81     UpdateWindow( hWndTest);
82     SetFocus(hWndTest);
83 
84     /* flush pending messages */
85     while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
86 
87     return hWndTest;
88 }
89 
Test_SetCursorPos()90 void Test_SetCursorPos()
91 {
92     HWND hwnd;
93     MSG msg;
94     int i;
95 
96     hMouseHookLL = SetWindowsHookEx(WH_MOUSE_LL, MouseLLHookProc, GetModuleHandleA( NULL ), 0);
97     hMouseHook = SetWindowsHookExW(WH_MOUSE, MouseHookProc, GetModuleHandleW( NULL ), GetCurrentThreadId());
98     ok(hMouseHook!=NULL,"failed to set hook\n");
99     ok(hMouseHookLL!=NULL,"failed to set hook\n");
100 
101     test_no = 0;
102     SetCursorPos(1,1);
103     while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
104 
105     test_no = 1;
106     mouse_event(MOUSEEVENTF_MOVE, 2,2, 0,0);
107     while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
108 
109     hwnd = CreateTestWindow();
110     SetCapture(hwnd);
111 
112     test_no = 2;
113     SetCursorPos(50,50);
114     while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
115 
116     test_no = 3;
117     mouse_event(MOUSEEVENTF_MOVE, 100,100, 0,0);
118     while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
119 
120     test_no = 4;
121     SetCursorPos(50,50);
122     SetCursorPos(60,60);
123     while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
124 
125     test_no = 5;
126     SetCursorPos(50,50);
127     while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
128     SetCursorPos(60,60);
129     while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
130 
131     test_no = 6;
132     mouse_event(MOUSEEVENTF_MOVE, 50,50, 0,0);
133     mouse_event(MOUSEEVENTF_MOVE, 60,60, 0,0);
134     while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
135 
136     test_no = 7;
137     mouse_event(MOUSEEVENTF_MOVE, 50,50, 0,0);
138     while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
139     mouse_event(MOUSEEVENTF_MOVE, 60,60, 0,0);
140     while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
141 
142     for(i = 0; i< 8; i++)
143     {
144 #define TEST(s,x,y) ok(y == x, "%d: %s called %d times instead of %d\n",i,s, y,x);
145         TEST("WH_MOUSE_LL", info[i].ll_hook_called, results[i].ll_hook_called);
146         /* WH_MOUSE results vary greatly among windows versions */
147         //TEST("WH_MOUSE", info[i].hook_called, results[i].hook_called);
148         //TEST("WM_MOUSEMOVE", info[i].mouse_move_called, results[i].mouse_move_called);
149     }
150 
151     SetCapture(NULL);
152     DestroyWindow(hwnd);
153 
154     UnhookWindowsHookEx (hMouseHook);
155     UnhookWindowsHookEx (hMouseHookLL);
156 
157 }
158 
Test_DesktopAccess()159 void Test_DesktopAccess()
160 {
161     HDESK hDesk, hDeskInitial;
162     POINT curPoint, initialPoint;
163     BOOL ret;
164 
165     hDeskInitial = GetThreadDesktop(GetCurrentThreadId());
166     ok(hDeskInitial != NULL, "Failed to retrieve the initial desktop\n");
167 
168     ret = GetCursorPos(&initialPoint);
169     ok(ret == TRUE, "GetCursorPos should succed\n");
170 
171     hDesk = CreateDesktopW(L"testDesktop", NULL, NULL, 0, 0x01ff, NULL);
172     ok(hDesk != 0, "Failed to create a new desktop\n");
173     SetThreadDesktop(hDesk);
174     ok(GetThreadDesktop(GetCurrentThreadId()) == hDesk, "SetThreadDesktop had no effect\n");
175 
176     SetLastError(0xdeadbeef);
177 
178     ret = GetCursorPos(&curPoint);
179     ok(ret == FALSE, "GetCursorPos should fail\n");
180 
181     ok(GetLastError() == ERROR_ACCESS_DENIED || GetLastError() == 0xdeadbeef,
182        "Expected ERROR_ACCESS_DENIED or 0xdeadbeef, got 0x%lx\n", GetLastError());
183     SetLastError(0xdeadbeef);
184 
185     ret = SetCursorPos(2,2);
186     //ok(ret == FALSE, "SetCursorPos should fail\n"); // FIXME: fails on WHS testbot
187 
188     ok(GetLastError() == 0xdeadbeef, "Wrong last error, got 0x%lx\n", GetLastError());
189 
190     ret = GetCursorPos(&curPoint);
191     ok(ret == FALSE, "GetCursorPos should fail\n");
192 
193     SetThreadDesktop(hDeskInitial);
194 
195     ret = GetCursorPos(&curPoint);
196     ok(ret == TRUE, "GetCursorPos should succed\n");
197     //ok(curPoint.x ==  initialPoint.x && curPoint.y ==  initialPoint.y, "Mouse position changed\n");
198 }
199 
START_TEST(SetCursorPos)200 START_TEST(SetCursorPos)
201 {
202     Test_DesktopAccess();
203     Test_SetCursorPos();
204 }
205