1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later) 4 * PURPOSE: Test for NtUserGetThreadState 5 * COPYRIGHT: Copyright 2021 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 6 */ 7 8 #include <win32nt.h> 9 #include <pseh/pseh2.h> 10 11 #define MAX_COUNT 8 12 #define IGNORED 0xDEADFACE 13 #define RAISED 0xBADBEEF 14 #define DO_CHECK(i, value) CheckThreadState(__LINE__, (i), (DWORD_PTR)(value)) 15 16 #undef DO_PRINT 17 18 #ifdef DO_PRINT 19 static VOID PrintThreadState(INT lineno, HWND hWnd) 20 { 21 INT i; 22 HIMC hIMC = ImmGetContext(hWnd); 23 HWND hImeWnd = ImmGetDefaultIMEWnd(hWnd); 24 25 trace("---\n"); 26 trace("__LINE__: %d\n", lineno); 27 trace("hWnd: %p\n", (LPVOID)hWnd); 28 trace("GetFocus(): %p\n", (LPVOID)GetFocus()); 29 trace("GetCapture(): %p\n", (LPVOID)GetCapture()); 30 trace("GetActiveWindow(): %p\n", (LPVOID)GetActiveWindow()); 31 trace("ImmGetContext(): %p\n", (LPVOID)hIMC); 32 trace("ImmGetDefaultIMEWnd(): %p\n", (LPVOID)hImeWnd); 33 34 for (i = 0; i < MAX_COUNT; ++i) 35 { 36 _SEH2_TRY 37 { 38 trace("ThreadState[%d]: %p\n", i, (LPVOID)NtUserGetThreadState(i)); 39 } 40 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 41 { 42 trace("ThreadState[%d]: exception\n", i); 43 } 44 _SEH2_END; 45 } 46 47 ImmReleaseContext(hWnd, hIMC); 48 } 49 #endif 50 51 static VOID CheckThreadState(INT lineno, INT i, DWORD_PTR dwState) 52 { 53 DWORD_PTR dwValue; 54 55 _SEH2_TRY 56 { 57 dwValue = (DWORD_PTR)NtUserGetThreadState(i); 58 } 59 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 60 { 61 dwValue = RAISED; 62 } 63 _SEH2_END; 64 65 if (dwState != IGNORED) 66 { 67 ok(dwValue == dwState, "Line %d: Mismatch 0x%lX vs. 0x%lX\n", 68 lineno, (DWORD)dwValue, (DWORD)dwState); 69 } 70 } 71 72 static VOID DoTest_EDIT(VOID) 73 { 74 HWND hWnd, hImeWnd; 75 HIMC hIMC; 76 77 hWnd = CreateWindowA("EDIT", "Test", ES_LEFT | ES_MULTILINE | WS_VISIBLE, 78 0, 0, 50, 30, 79 NULL, NULL, GetModuleHandleW(NULL), NULL); 80 hImeWnd = ImmGetDefaultIMEWnd(hWnd); 81 ok_int(hImeWnd != NULL, TRUE); 82 83 hIMC = ImmGetContext(hWnd); 84 ok_int(hIMC != NULL, TRUE); 85 ok_int(hIMC == (HIMC)NtUserGetThreadState(4), TRUE); 86 87 #ifdef DO_PRINT 88 PrintThreadState(__LINE__, hWnd); 89 #endif 90 DO_CHECK(0, hWnd); 91 DO_CHECK(1, hWnd); 92 DO_CHECK(2, 0); 93 DO_CHECK(3, hImeWnd); 94 DO_CHECK(4, hIMC); 95 96 SetCapture(hWnd); 97 98 #ifdef DO_PRINT 99 PrintThreadState(__LINE__, hWnd); 100 #endif 101 DO_CHECK(0, hWnd); 102 DO_CHECK(1, hWnd); 103 DO_CHECK(2, hWnd); 104 DO_CHECK(3, hImeWnd); 105 DO_CHECK(4, hIMC); 106 107 ReleaseCapture(); 108 109 #ifdef DO_PRINT 110 PrintThreadState(__LINE__, hWnd); 111 #endif 112 DO_CHECK(0, hWnd); 113 DO_CHECK(1, hWnd); 114 DO_CHECK(2, 0); 115 DO_CHECK(3, hImeWnd); 116 DO_CHECK(4, hIMC); 117 118 SetFocus(hWnd); 119 120 #ifdef DO_PRINT 121 PrintThreadState(__LINE__, hWnd); 122 #endif 123 DO_CHECK(0, hWnd); 124 DO_CHECK(1, hWnd); 125 DO_CHECK(2, 0); 126 DO_CHECK(3, hImeWnd); 127 DO_CHECK(4, hIMC); 128 129 SetActiveWindow(hWnd); 130 131 #ifdef DO_PRINT 132 PrintThreadState(__LINE__, hWnd); 133 #endif 134 DO_CHECK(0, hWnd); 135 DO_CHECK(1, hWnd); 136 DO_CHECK(2, 0); 137 DO_CHECK(3, hImeWnd); 138 DO_CHECK(4, hIMC); 139 140 SetActiveWindow(NULL); 141 142 #ifdef DO_PRINT 143 PrintThreadState(__LINE__, hWnd); 144 #endif 145 DO_CHECK(0, IGNORED); 146 DO_CHECK(1, IGNORED); 147 DO_CHECK(2, 0); 148 DO_CHECK(3, hImeWnd); 149 DO_CHECK(4, hIMC); 150 151 ImmReleaseContext(hWnd, hIMC); 152 DestroyWindow(hWnd); 153 } 154 155 static VOID DoTest_BUTTON(VOID) 156 { 157 HWND hWnd, hImeWnd; 158 HIMC hIMC; 159 160 hWnd = CreateWindowA("BUTTON", "Test", BS_PUSHBUTTON | WS_VISIBLE, 161 0, 0, 50, 30, 162 NULL, NULL, GetModuleHandleW(NULL), NULL); 163 hImeWnd = ImmGetDefaultIMEWnd(hWnd); 164 ok_int(hImeWnd != NULL, TRUE); 165 166 hIMC = ImmGetContext(hWnd); 167 ok_int(hIMC != NULL, FALSE); 168 169 hIMC = (HIMC)NtUserGetThreadState(4); 170 ok_int(hIMC != NULL, TRUE); 171 172 #ifdef DO_PRINT 173 PrintThreadState(__LINE__, hWnd); 174 #endif 175 DO_CHECK(0, hWnd); 176 DO_CHECK(1, hWnd); 177 DO_CHECK(2, 0); 178 DO_CHECK(3, hImeWnd); 179 DO_CHECK(4, hIMC); 180 181 SetCapture(hWnd); 182 183 #ifdef DO_PRINT 184 PrintThreadState(__LINE__, hWnd); 185 #endif 186 DO_CHECK(0, hWnd); 187 DO_CHECK(1, hWnd); 188 DO_CHECK(2, hWnd); 189 DO_CHECK(3, hImeWnd); 190 DO_CHECK(4, hIMC); 191 192 ReleaseCapture(); 193 194 #ifdef DO_PRINT 195 PrintThreadState(__LINE__, hWnd); 196 #endif 197 DO_CHECK(0, hWnd); 198 DO_CHECK(1, hWnd); 199 DO_CHECK(2, 0); 200 DO_CHECK(3, hImeWnd); 201 DO_CHECK(4, hIMC); 202 203 SetFocus(hWnd); 204 205 #ifdef DO_PRINT 206 PrintThreadState(__LINE__, hWnd); 207 #endif 208 DO_CHECK(0, hWnd); 209 DO_CHECK(1, hWnd); 210 DO_CHECK(2, 0); 211 DO_CHECK(3, hImeWnd); 212 DO_CHECK(4, hIMC); 213 214 SetActiveWindow(hWnd); 215 216 #ifdef DO_PRINT 217 PrintThreadState(__LINE__, hWnd); 218 #endif 219 DO_CHECK(0, hWnd); 220 DO_CHECK(1, hWnd); 221 DO_CHECK(2, 0); 222 DO_CHECK(3, hImeWnd); 223 DO_CHECK(4, hIMC); 224 225 SetActiveWindow(NULL); 226 227 #ifdef DO_PRINT 228 PrintThreadState(__LINE__, hWnd); 229 #endif 230 DO_CHECK(0, IGNORED); 231 DO_CHECK(1, IGNORED); 232 DO_CHECK(2, 0); 233 DO_CHECK(3, hImeWnd); 234 DO_CHECK(4, hIMC); 235 236 DestroyWindow(hWnd); 237 } 238 239 START_TEST(NtUserGetThreadState) 240 { 241 DoTest_EDIT(); 242 DoTest_BUTTON(); 243 } 244