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 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 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 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 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 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 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 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 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