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