1 /*
2 * PROJECT: ReactOS API tests
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Tests for NtUserSetTimer
5 * COPYRIGHT: Copyright 2008 Timo Kreuzer <timo.kreuzer@reactos.org>
6 * Copyright 2024 Tomáš Veselý <turican0@gmail.com>
7 */
8
9 #include "../win32nt.h"
10
11 #define SLEEP_TIME 500
12 #define MIN_MESSAGES_TIME 1
13 #define MAX_MESSAGES_TIME 1000
14
15 #define TEST1_COUNT 20
16 #define TEST1_INTERVAL 10
17
18 #define TEST2_COUNT 40000
19 #define TEST2_INTERVAL 10
20
21 #define TESTW1_COUNT 20
22 #define TESTW1_INTERVAL 10
23
24 #define TESTW2_COUNT 40000
25 #define TESTW2_INTERVAL 10
26
27 typedef struct TIMER_MESSAGE_STATE1
28 {
29 UINT_PTR index;
30 UINT counter;
31 } TIMER_MESSAGE_STATE1;
32
33 TIMER_MESSAGE_STATE1 timerId1[TEST1_COUNT];
34
35 typedef struct TIMER_MESSAGE_STATEW1
36 {
37 UINT counter;
38 } TIMER_MESSAGE_STATEW1;
39
40 TIMER_MESSAGE_STATEW1 timerIdW1[TESTW1_COUNT];
41
42 /* TIMERPROC for the test1,2,3() with messages without window */
43 static void CALLBACK
TimerProc(HWND hWnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime)44 TimerProc(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
45 {
46 UINT i;
47 for (i = 0; i < TEST1_COUNT; i++)
48 {
49 if (timerId1[i].index == idEvent)
50 timerId1[i].counter++;
51 }
52 }
53
54 /* TIMERPROC for the testW1,2() with messages with window */
55 static LRESULT CALLBACK
WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)56 WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
57 {
58 switch (uMsg)
59 {
60 case WM_TIMER:
61 timerIdW1[wParam].counter++;
62 return 0;
63 }
64
65 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
66 }
67
68 // TEST WITH MESSAGES WITHOUT WINDOW - test count of sent messages
test1(void)69 static BOOL test1(void)
70 {
71 UINT i, countErrors = 0;
72 ULONGLONG startTime;
73 MSG msg = { NULL };
74
75 ZeroMemory(timerId1, sizeof(timerId1));
76
77 for (i = 0; i < TEST1_COUNT; i++)
78 {
79 timerId1[i].index = SetTimer(NULL, 0, TEST1_INTERVAL, TimerProc);
80 if (timerId1[i].index == 0)
81 countErrors++;
82 }
83
84 startTime = GetTickCount();
85
86 while (GetMessageW(&msg, NULL, 0, 0))
87 {
88 TranslateMessage(&msg);
89 DispatchMessageW(&msg);
90
91 if (GetTickCount() - startTime >= SLEEP_TIME)
92 PostQuitMessage(0);
93 }
94
95 for (i = 0; i < TEST1_COUNT; i++)
96 {
97 if ((timerId1[i].counter < MIN_MESSAGES_TIME) || (timerId1[i].counter > MAX_MESSAGES_TIME))
98 countErrors++;
99 }
100
101 for (i = 0; i < TEST1_COUNT; i++)
102 {
103 if (KillTimer(NULL, timerId1[i].index) == 0)
104 countErrors++;
105 }
106
107 return (countErrors == 0);
108 }
109
110 // TEST WITH MESSAGES WITHOUT WINDOW - create many timers
test2(void)111 static BOOL test2(void)
112 {
113 UINT i, countErrors = 0;
114 UINT_PTR locIndex;
115
116 for (i = 0; i < TEST2_COUNT; i++)
117 {
118 locIndex = SetTimer(NULL, 0, TEST2_INTERVAL, TimerProc);
119
120 if (locIndex == 0)
121 countErrors++;
122 if (KillTimer(NULL, locIndex) == 0)
123 countErrors++;
124 }
125
126 return (countErrors == 0);
127 }
128
129 // TEST WITH MESSAGES WITHOUT WINDOW - test different ids
test3(void)130 static BOOL test3(void)
131 {
132 UINT countErrors = 0;
133 UINT_PTR locIndex1;
134 UINT_PTR locIndex2;
135
136 locIndex1 = SetTimer(NULL, 0, TEST1_INTERVAL, TimerProc);
137 if (locIndex1 == 0)
138 countErrors++;
139 if (KillTimer(NULL, locIndex1) == 0)
140 countErrors++;
141 locIndex2 = SetTimer(NULL, 0, TEST1_INTERVAL, TimerProc);
142 if (locIndex2 == 0)
143 countErrors++;
144 if (KillTimer(NULL, locIndex2) == 0)
145 countErrors++;
146 if (locIndex1 == locIndex2)
147 countErrors++;
148
149 return (countErrors == 0);
150 }
151
152 // TEST WITH MESSAGES WITH WINDOW - test count of sent messages
testW1(HWND hwnd)153 static BOOL testW1(HWND hwnd)
154 {
155 UINT i, countErrors = 0;
156 UINT_PTR locIndex;
157 ULONGLONG startTime;
158 MSG msg = { NULL };
159
160 if (hwnd == NULL)
161 return FALSE;
162
163 ZeroMemory(timerIdW1, sizeof(timerIdW1));
164
165 for (i = 0; i < TESTW1_COUNT; i++)
166 {
167 locIndex = SetTimer(hwnd, i, TESTW1_INTERVAL, NULL);
168 if (locIndex == 0)
169 countErrors++;
170 }
171
172 startTime = GetTickCount();
173
174 while (GetMessageW(&msg, NULL, 0, 0))
175 {
176 TranslateMessage(&msg);
177 DispatchMessageW(&msg);
178
179 if (GetTickCount() - startTime >= SLEEP_TIME)
180 PostQuitMessage(0);
181 }
182
183 for (i = 0; i < TESTW1_COUNT; i++)
184 {
185 if ((timerIdW1[i].counter < MIN_MESSAGES_TIME) || (timerIdW1[i].counter > MAX_MESSAGES_TIME))
186 countErrors++;
187 }
188
189 for (i = 0; i < TESTW1_COUNT; i++)
190 {
191 if (KillTimer(hwnd, i) == 0)
192 countErrors++;
193 }
194
195 return (countErrors == 0);
196 }
197
198 // TEST WITH MESSAGES WITH WINDOW - create many timers
testW2(HWND hwnd)199 static BOOL testW2(HWND hwnd)
200 {
201 UINT i, countErrors = 0;
202 UINT_PTR result;
203
204 if (hwnd == NULL)
205 return FALSE;
206
207 for (i = 0; i < TESTW2_COUNT; i++)
208 {
209 result = SetTimer(hwnd, 1, TESTW2_INTERVAL, NULL);
210 if (result == 0)
211 countErrors++;
212 if (KillTimer(hwnd, 1) == 0)
213 countErrors++;
214 }
215
216 return (countErrors == 0);
217 }
218
START_TEST(NtUserSetTimer)219 START_TEST(NtUserSetTimer)
220 {
221 WNDCLASSW wc = { 0 };
222 HWND hwnd;
223
224 // TEST WITH MESSAGES WITHOUT WINDOW - test count of sent messages
225 TEST(test1());
226
227 // TEST WITH MESSAGES WITHOUT WINDOW - create many timers
228 TEST(test2());
229
230 // TEST WITH MESSAGES WITHOUT WINDOW - test different ids
231 TEST(test3());
232
233 wc.lpfnWndProc = WindowProc;
234 wc.hInstance = GetModuleHandleW(NULL);
235 wc.lpszClassName = L"TimerWindowClass";
236 RegisterClassW(&wc);
237
238 hwnd = CreateWindowExW(0, L"TimerWindowClass", L"Timer Window", 0,
239 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
240 HWND_MESSAGE, NULL, GetModuleHandleW(NULL), NULL);
241
242 // TEST WITH MESSAGES WITH WINDOW - test count of sent messages
243 TEST(testW1(hwnd));
244
245 // TEST WITH MESSAGES WITH WINDOW - create many timers
246 TEST(testW2(hwnd));
247
248 if (hwnd != NULL)
249 DestroyWindow(hwnd);
250 UnregisterClassW(L"TimerWindowClass", NULL);
251 }
252