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