1 /*
2  * PROJECT:     ReactOS API tests
3  * LICENSE:     LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
4  * PURPOSE:     Test for SetFocus/GetFocus/GetGUIThreadInfo
5  * COPYRIGHT:   Copyright 2021 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6  */
7 
8 #include "precomp.h"
9 #include <dlgs.h> // psh1, ...
10 #include <process.h>
11 
12 #define INTERVAL 80
13 
14 static DWORD s_dwMainThreadID;
15 
16 static HWND GetMainThreadFocus(void)
17 {
18     GUITHREADINFO gui = { sizeof(gui) };
19     GetGUIThreadInfo(s_dwMainThreadID, &gui);
20     return gui.hwndFocus;
21 }
22 
23 static unsigned __stdcall thread_proc_0(void *arg)
24 {
25     HWND hwnd = arg;
26 
27     ok_int(GetFocus() == NULL, TRUE);
28     ok_int(GetMainThreadFocus() == GetDlgItem(hwnd, IDOK), TRUE);
29     SendMessageA(hwnd, WM_NEXTDLGCTL, FALSE, FALSE);
30 
31     ok_int(GetFocus() == NULL, TRUE);
32     ok_int(GetMainThreadFocus() == GetDlgItem(hwnd, IDCANCEL), TRUE);
33     SendMessageA(hwnd, WM_NEXTDLGCTL, FALSE, FALSE);
34 
35     ok_int(GetFocus() == NULL, TRUE);
36     ok_int(GetMainThreadFocus() == GetDlgItem(hwnd, psh1), TRUE);
37     SendMessageA(hwnd, WM_NEXTDLGCTL, FALSE, FALSE);
38 
39     ok_int(GetFocus() == NULL, TRUE);
40     ok_int(GetMainThreadFocus() == GetDlgItem(hwnd, IDOK), TRUE);
41     SendMessageA(hwnd, WM_NEXTDLGCTL, TRUE, FALSE);
42 
43     ok_int(GetFocus() == NULL, TRUE);
44     ok_int(GetMainThreadFocus() == GetDlgItem(hwnd, psh1), TRUE);
45     keybd_event(VK_TAB, KEYEVENTF_KEYUP, 0, 0);
46     Sleep(INTERVAL);
47 
48     ok_int(GetFocus() == NULL, TRUE);
49     ok_int(GetMainThreadFocus() == GetDlgItem(hwnd, IDOK), TRUE);
50     keybd_event(VK_TAB, KEYEVENTF_KEYUP, 0, 0);
51     Sleep(INTERVAL);
52 
53     ok_int(GetFocus() == NULL, TRUE);
54     ok_int(GetMainThreadFocus() == GetDlgItem(hwnd, IDCANCEL), TRUE);
55     keybd_event(VK_TAB, KEYEVENTF_KEYUP, 0, 0);
56     Sleep(INTERVAL);
57 
58     ok_int(GetFocus() == NULL, TRUE);
59     ok_int(GetMainThreadFocus() == GetDlgItem(hwnd, psh1), TRUE);
60     keybd_event(VK_TAB, KEYEVENTF_KEYUP, 0, 0);
61     Sleep(INTERVAL);
62 
63     ok_int(GetFocus() == NULL, TRUE);
64     ok_int(GetMainThreadFocus() == GetDlgItem(hwnd, IDOK), TRUE);
65 
66     PostMessageA(hwnd, WM_COMMAND, psh3, 0);
67     return 0;
68 }
69 
70 static unsigned __stdcall thread_proc_1(void *arg)
71 {
72     HWND hwnd = arg;
73 
74     ok_int(GetFocus() == NULL, TRUE);
75     ok_int(GetMainThreadFocus() == NULL, TRUE);
76     keybd_event(VK_TAB, KEYEVENTF_KEYUP, 0, 0);
77     Sleep(INTERVAL);
78 
79     ok_int(GetFocus() == NULL, TRUE);
80     ok_int(GetMainThreadFocus() == NULL, TRUE);
81     keybd_event(VK_TAB, KEYEVENTF_KEYUP, 0, 0);
82     Sleep(INTERVAL);
83 
84     ok_int(GetFocus() == NULL, TRUE);
85     ok_int(GetMainThreadFocus() == NULL, TRUE);
86 
87     PostMessageA(hwnd, WM_COMMAND, psh3, 0);
88     return 0;
89 }
90 
91 static unsigned __stdcall thread_proc_2(void *arg)
92 {
93     HWND hwnd = arg;
94 
95     ok_int(GetFocus() == NULL, TRUE);
96     ok_int(GetMainThreadFocus() == GetDlgItem(hwnd, IDCANCEL), TRUE);
97     keybd_event(VK_TAB, KEYEVENTF_KEYUP, 0, 0);
98     Sleep(INTERVAL);
99 
100     ok_int(GetFocus() == NULL, TRUE);
101     ok_int(GetMainThreadFocus() == GetDlgItem(hwnd, psh1), TRUE);
102     keybd_event(VK_TAB, KEYEVENTF_KEYUP, 0, 0);
103     Sleep(INTERVAL);
104 
105     ok_int(GetFocus() == NULL, TRUE);
106     ok_int(GetMainThreadFocus() == GetDlgItem(hwnd, IDOK), TRUE);
107     keybd_event(VK_TAB, KEYEVENTF_KEYUP, 0, 0);
108     Sleep(INTERVAL);
109 
110     PostMessageA(hwnd, WM_COMMAND, psh4, 0);
111     return 0;
112 }
113 
114 static INT_PTR CALLBACK
115 DialogProc_0(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
116 {
117     HANDLE hThread;
118     switch (uMsg)
119     {
120         case WM_INITDIALOG:
121             ok_int(GetFocus() == NULL, TRUE);
122             SetFocus(GetDlgItem(hwnd, IDOK));
123             ok_int(GetFocus() == GetDlgItem(hwnd, IDOK), TRUE);
124             SendMessageA(hwnd, WM_NEXTDLGCTL, FALSE, FALSE);
125 
126             ok_int(GetFocus() == GetDlgItem(hwnd, IDCANCEL), TRUE);
127             SendMessageA(hwnd, WM_NEXTDLGCTL, TRUE, FALSE);
128 
129             ok_int(GetFocus() == GetDlgItem(hwnd, IDOK), TRUE);
130             SendMessageA(hwnd, WM_NEXTDLGCTL, FALSE, FALSE);
131 
132             ok_int(GetFocus() == GetDlgItem(hwnd, IDCANCEL), TRUE);
133             SendMessageA(hwnd, WM_NEXTDLGCTL, FALSE, FALSE);
134 
135             ok_int(GetFocus() == GetDlgItem(hwnd, psh1), TRUE);
136             SendMessageA(hwnd, WM_NEXTDLGCTL, FALSE, FALSE);
137 
138             ok_int(GetFocus() == GetDlgItem(hwnd, IDOK), TRUE);
139             SetFocus(GetDlgItem(hwnd, IDCANCEL));
140             PostMessageA(hwnd, WM_COMMAND, psh2, 0);
141             return TRUE;
142 
143         case WM_COMMAND:
144             switch (LOWORD(wParam))
145             {
146                 case psh2:
147                     ok_int(GetFocus() == GetDlgItem(hwnd, IDOK), TRUE);
148                     hThread = (HANDLE)_beginthreadex(NULL, 0, thread_proc_0, hwnd, 0, NULL);
149                     CloseHandle(hThread);
150                     break;
151 
152                 case psh3:
153                     ok_int(GetFocus() == GetDlgItem(hwnd, IDOK), TRUE);
154                     EndDialog(hwnd, IDCLOSE);
155                     break;
156             }
157             break;
158     }
159     return 0;
160 }
161 
162 static INT_PTR CALLBACK
163 DialogProc_1(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
164 {
165     HANDLE hThread;
166     switch (uMsg)
167     {
168         case WM_INITDIALOG:
169             SetFocus(GetDlgItem(hwnd, IDCANCEL));
170             PostMessageA(hwnd, WM_COMMAND, psh2, 0);
171             return FALSE;
172 
173         case WM_COMMAND:
174             switch (LOWORD(wParam))
175             {
176                 case psh2:
177                     ok_int(GetFocus() == GetDlgItem(hwnd, IDCANCEL), TRUE);
178                     EnableWindow(GetDlgItem(hwnd, IDCANCEL), FALSE);
179                     ok_int(GetFocus() == NULL, TRUE);
180 
181                     hThread = (HANDLE)_beginthreadex(NULL, 0, thread_proc_1, hwnd, 0, NULL);
182                     CloseHandle(hThread);
183                     break;
184 
185                 case psh3:
186                     ok_int(GetFocus() == NULL, TRUE);
187                     EnableWindow(GetDlgItem(hwnd, IDCANCEL), TRUE);
188 
189                     ok_int(GetFocus() == NULL, TRUE);
190                     SetFocus(GetDlgItem(hwnd, IDCANCEL));
191                     ok_int(GetFocus() == GetDlgItem(hwnd, IDCANCEL), TRUE);
192 
193                     hThread = (HANDLE)_beginthreadex(NULL, 0, thread_proc_2, hwnd, 0, NULL);
194                     CloseHandle(hThread);
195                     break;
196 
197                 case psh4:
198                     ok_int(GetFocus() == GetDlgItem(hwnd, IDCANCEL), TRUE);
199                     ShowWindow(GetDlgItem(hwnd, IDCANCEL), SW_HIDE);
200 
201                     ok_int(GetFocus() == GetDlgItem(hwnd, IDOK), TRUE);
202                     ShowWindow(GetDlgItem(hwnd, IDCANCEL), SW_SHOW);
203 
204                     ok_int(GetFocus() == GetDlgItem(hwnd, IDOK), TRUE);
205                     EndDialog(hwnd, IDCLOSE);
206                     break;
207             }
208             break;
209     }
210     return 0;
211 }
212 
213 START_TEST(SetFocus)
214 {
215     s_dwMainThreadID = GetCurrentThreadId();
216     Sleep(INTERVAL);
217     ok_int((INT)DialogBoxA(GetModuleHandleA(NULL), "SETFOCUS", NULL, DialogProc_0), IDCLOSE);
218     ok_int((INT)DialogBoxA(GetModuleHandleA(NULL), "SETFOCUS", NULL, DialogProc_1), IDCLOSE);
219 }
220