[REACTOS] Fix MSVC printf format warnings
[reactos.git] / modules / rostests / apitests / user32 / SendMessageTimeout.c
1 /*
2 * PROJECT: ReactOS API tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for SendMessageTimeout
5 * PROGRAMMERS: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include "precomp.h"
9
10 static DWORD dwThread1;
11 static DWORD dwThread2;
12 static HANDLE hThread1;
13 static HANDLE hThread2;
14 static HWND hWndThread1;
15 static HWND hWndThread2;
16
17 static
18 void
19 TestSendMessageTimeout(
20 _In_ HWND hWnd,
21 _In_ UINT Msg)
22 {
23 LRESULT ret;
24 DWORD_PTR result;
25
26 ret = SendMessageTimeoutW(hWnd, Msg, 0, 0, SMTO_NORMAL, 0, NULL);
27 ok(ret == 0, "ret = %Id\n", ret);
28
29 result = 0x55555555;
30 ret = SendMessageTimeoutW(hWnd, Msg, 0, 0, SMTO_NORMAL, 0, &result);
31 ok(ret == 0, "ret = %Id\n", ret);
32 ok(result == 0, "result = %Iu\n", result);
33
34 ret = SendMessageTimeoutA(hWnd, Msg, 0, 0, SMTO_NORMAL, 0, NULL);
35 ok(ret == 0, "ret = %Id\n", ret);
36
37 result = 0x55555555;
38 ret = SendMessageTimeoutA(hWnd, Msg, 0, 0, SMTO_NORMAL, 0, &result);
39 ok(ret == 0, "ret = %Id\n", ret);
40 ok(result == 0, "result = %Iu\n", result);
41 }
42
43 #define WM_SENDTOOTHERTHREAD (WM_USER + 14)
44
45 #define KILL_THREAD1_FLAG 0x40000000
46 #define KILL_THREAD2_FLAG 0x20000000
47 #define KILL_THREAD_FLAGS (KILL_THREAD1_FLAG | KILL_THREAD2_FLAG)
48
49 static
50 LRESULT
51 CALLBACK
52 WndProc(
53 _In_ HWND hWnd,
54 _In_ UINT message,
55 _In_ WPARAM wParam,
56 _In_ LPARAM lParam)
57 {
58 if (IsDWmMsg(message) || IseKeyMsg(message))
59 return DefWindowProcW(hWnd, message, wParam, lParam);
60
61 if (hWnd == hWndThread1)
62 {
63 RECORD_MESSAGE(1, message, SENT, wParam, lParam);
64 }
65 else if (hWnd == hWndThread2)
66 {
67 RECORD_MESSAGE(2, message, SENT, wParam, lParam);
68 }
69 else
70 {
71 RECORD_MESSAGE(3, message, SENT, wParam, lParam);
72 }
73
74 switch (message)
75 {
76 case WM_SENDTOOTHERTHREAD:
77 if (GetCurrentThreadId() == dwThread1)
78 {
79 if ((wParam & KILL_THREAD2_FLAG) &&
80 (wParam & ~KILL_THREAD_FLAGS) > 10)
81 {
82 TerminateThread(hThread2, 123);
83 }
84 if ((wParam & KILL_THREAD1_FLAG) &&
85 (wParam & ~KILL_THREAD_FLAGS) > 10)
86 {
87 TerminateThread(hThread1, 456);
88 }
89 ok(lParam == dwThread2, "lParam = %Iu, expected %lu\n", lParam, dwThread2);
90 return SendMessage(hWndThread2, WM_SENDTOOTHERTHREAD, wParam + 1, GetCurrentThreadId());
91 }
92 else
93 {
94 ok(lParam == dwThread1, "lParam = %Iu, expected %lu\n", lParam, dwThread1);
95 return SendMessage(hWndThread1, WM_SENDTOOTHERTHREAD, wParam + 1, GetCurrentThreadId());
96 }
97 }
98
99 return DefWindowProcW(hWnd, message, wParam, lParam);
100 }
101
102 static
103 DWORD
104 WINAPI
105 Thread1(
106 _Inout_opt_ PVOID Parameter)
107 {
108 MSG msg;
109
110 hWndThread1 = CreateWindowExW(0, L"SendTest", NULL, 0, 10, 10, 20, 20, NULL, NULL, 0, NULL);
111 ok(hWndThread1 != NULL, "CreateWindow failed\n");
112
113 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
114 {
115 if (!(msg.message > WM_USER || IsDWmMsg(msg.message) || IseKeyMsg(msg.message)))
116 RECORD_MESSAGE(1, msg.message, POST, 0, 0);
117 DispatchMessageA(&msg);
118 }
119
120 ResumeThread(hThread2);
121
122 while (MsgWaitForMultipleObjectsEx(1, &hThread2, FALSE, QS_ALLEVENTS, MWMO_ALERTABLE) != WAIT_OBJECT_0)
123 {
124 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
125 {
126 if (!(msg.message > WM_USER || IsDWmMsg(msg.message) || IseKeyMsg(msg.message)))
127 RECORD_MESSAGE(1, msg.message, POST, 0, 0);
128 DispatchMessageA(&msg);
129 }
130 }
131
132 DestroyWindow(hWndThread1);
133 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
134 {
135 if (!(msg.message > WM_USER || IsDWmMsg(msg.message) || IseKeyMsg(msg.message)))
136 RECORD_MESSAGE(1, msg.message, POST, 0, 0);
137 DispatchMessageA(&msg);
138 }
139
140 return 6;
141 }
142
143 static
144 DWORD
145 WINAPI
146 Thread2(
147 _Inout_opt_ PVOID Parameter)
148 {
149 MSG msg;
150 LRESULT ret;
151 WPARAM wParam;
152
153 hWndThread2 = CreateWindowExW(0, L"SendTest", NULL, 0, 10, 10, 20, 20, NULL, NULL, 0, NULL);
154 ok(hWndThread2 != NULL, "CreateWindow failed\n");
155
156 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
157 {
158 if (!(msg.message > WM_USER || IsDWmMsg(msg.message) || IseKeyMsg(msg.message)))
159 RECORD_MESSAGE(2, msg.message, POST, 0, 0);
160 DispatchMessageA(&msg);
161 }
162
163 wParam = (WPARAM)Parameter;
164 ret = SendMessage(hWndThread1, WM_SENDTOOTHERTHREAD, wParam, dwThread2);
165 ok(ret == 0, "ret = %lu\n", ret);
166
167 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
168 {
169 if (!(msg.message > WM_USER || IsDWmMsg(msg.message) || IseKeyMsg(msg.message)))
170 RECORD_MESSAGE(2, msg.message, POST, 0, 0);
171 DispatchMessageA(&msg);
172 }
173
174 DestroyWindow(hWndThread2);
175 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
176 {
177 if (!(msg.message > WM_USER || IsDWmMsg(msg.message) || IseKeyMsg(msg.message)))
178 RECORD_MESSAGE(2, msg.message, POST, 0, 0);
179 DispatchMessageA(&msg);
180 }
181
182 return 7;
183 }
184
185 static
186 void
187 TestRecursiveInterThreadMessages(
188 _In_ BOOL KillThread1,
189 _In_ BOOL KillThread2)
190 {
191 PVOID Parameter;
192 HANDLE Handles[2];
193 BOOL Ret;
194 DWORD ExitCode;
195
196 Parameter = UlongToPtr((KillThread1 ? KILL_THREAD1_FLAG : 0) |
197 (KillThread2 ? KILL_THREAD2_FLAG : 0));
198 hThread1 = CreateThread(NULL, 0, Thread1, Parameter, CREATE_SUSPENDED, &dwThread1);
199 hThread2 = CreateThread(NULL, 0, Thread2, Parameter, CREATE_SUSPENDED, &dwThread2);
200
201 ResumeThread(hThread1);
202
203 Handles[0] = hThread1;
204 Handles[1] = hThread2;
205 WaitForMultipleObjects(2, Handles, TRUE, INFINITE);
206
207 Ret = GetExitCodeThread(hThread1, &ExitCode);
208 ok(Ret == TRUE, "GetExitCodeThread failed with %lu\n", GetLastError());
209 if (KillThread1)
210 ok(ExitCode == 456, "Thread1 exit code is %lu\n", ExitCode);
211 else
212 ok(ExitCode == 6, "Thread1 exit code is %lu\n", ExitCode);
213
214 Ret = GetExitCodeThread(hThread2, &ExitCode);
215 ok(Ret == TRUE, "GetExitCodeThread failed with %lu\n", GetLastError());
216 if (KillThread2)
217 ok(ExitCode == 123, "Thread2 exit code is %lu\n", ExitCode);
218 else
219 ok(ExitCode == 7, "Thread2 exit code is %lu\n", ExitCode);
220
221 CloseHandle(hThread2);
222 CloseHandle(hThread1);
223
224 //TRACE_CACHE();
225 }
226
227 START_TEST(SendMessageTimeout)
228 {
229 TestSendMessageTimeout(NULL, WM_USER);
230 TestSendMessageTimeout(NULL, WM_PAINT);
231 TestSendMessageTimeout(NULL, WM_GETICON);
232
233 RegisterSimpleClass(WndProc, L"SendTest");
234
235 TestRecursiveInterThreadMessages(FALSE, FALSE);
236 TestRecursiveInterThreadMessages(FALSE, TRUE);
237 TestRecursiveInterThreadMessages(TRUE, FALSE);
238 TestRecursiveInterThreadMessages(TRUE, TRUE);
239 }