1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * PURPOSE:         Test for SwitchToThisWindow
5  * PROGRAMMERS:     Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6  */
7 
8 #include "precomp.h"
9 
10 static const WCHAR s_szClassName[] = L"SwitchTest";
11 
12 static BOOL s_bTracing = FALSE;
13 
14 static INT s_nWM_SYSCOMMAND_SC_RESTORE = 0;
15 static INT s_nWM_SYSCOMMAND_NOT_SC_RESTORE = 0;
16 static INT s_nWM_NCACTIVATE = 0;
17 static INT s_nWM_WINDOWPOSCHANGING = 0;
18 static INT s_nWM_ACTIVATE = 0;
19 
20 #define TIMER_INTERVAL 200
21 
22 static const char *
DumpInSMEX(void)23 DumpInSMEX(void)
24 {
25     static char s_buf[128];
26     DWORD dwRet = InSendMessageEx(NULL);
27     if (dwRet == ISMEX_NOSEND)
28     {
29         strcpy(s_buf, "ISMEX_NOSEND,");
30         return s_buf;
31     }
32     s_buf[0] = 0;
33     if (dwRet & ISMEX_CALLBACK)
34         strcat(s_buf, "ISMEX_CALLBACK,");
35     if (dwRet & ISMEX_NOTIFY)
36         strcat(s_buf, "ISMEX_NOTIFY,");
37     if (dwRet & ISMEX_REPLIED)
38         strcat(s_buf, "ISMEX_REPLIED,");
39     if (dwRet & ISMEX_SEND)
40         strcat(s_buf, "ISMEX_SEND,");
41     return s_buf;
42 }
43 
44 static void
DoMessage(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)45 DoMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
46 {
47     if (uMsg == WM_TIMER || !s_bTracing)
48         return;
49 
50     trace("%s: uMsg:0x%04X, wParam:0x%08lX, lParam:0x%08lX, ISMEX_:%s\n",
51           (InSendMessage() ? "S" : "P"), uMsg, (LONG)wParam, (LONG)lParam,
52            DumpInSMEX());
53 
54     if (uMsg == WM_SYSCOMMAND)  // 0x0112
55     {
56         ok(InSendMessageEx(NULL) == ISMEX_NOSEND,
57            "InSendMessageEx(NULL) was 0x%08lX\n", InSendMessageEx(NULL));
58         if (wParam == SC_RESTORE)
59             ++s_nWM_SYSCOMMAND_SC_RESTORE;
60         else
61             ++s_nWM_SYSCOMMAND_NOT_SC_RESTORE;
62     }
63 
64     if (uMsg == WM_NCACTIVATE)  // 0x0086
65     {
66         ok(InSendMessageEx(NULL) == ISMEX_NOSEND,
67            "InSendMessageEx(NULL) was 0x%08lX\n", InSendMessageEx(NULL));
68         ++s_nWM_NCACTIVATE;
69     }
70 
71     if (uMsg == WM_WINDOWPOSCHANGING)   // 0x0046
72     {
73         ok(InSendMessageEx(NULL) == ISMEX_NOSEND,
74            "InSendMessageEx(NULL) was 0x%08lX\n", InSendMessageEx(NULL));
75         ++s_nWM_WINDOWPOSCHANGING;
76     }
77 
78     if (uMsg == WM_ACTIVATE)    // 0x0006
79     {
80         ok(InSendMessageEx(NULL) == ISMEX_NOSEND,
81            "InSendMessageEx(NULL) was 0x%08lX\n", InSendMessageEx(NULL));
82         ++s_nWM_ACTIVATE;
83     }
84 }
85 
86 // WM_TIMER
87 static void
OnTimer(HWND hwnd,UINT id)88 OnTimer(HWND hwnd, UINT id)
89 {
90     KillTimer(hwnd, id);
91     switch (id)
92     {
93         //
94         // SwitchToThisWindow(TRUE)
95         //
96         case 0: // minimize
97             SetForegroundWindow(GetDesktopWindow());
98             SetActiveWindow(GetDesktopWindow());
99             ok(GetForegroundWindow() == NULL, "GetForegroundWindow() != NULL\n");
100             ok(GetActiveWindow() == NULL, "GetActiveWindow() != NULL\n");
101             ok(GetFocus() == NULL, "GetFocus() != NULL\n");
102             CloseWindow(hwnd);  // minimize
103             break;
104         case 1: // start tracing
105             ok(GetForegroundWindow() == NULL, "GetForegroundWindow() != NULL\n");
106             ok(GetActiveWindow() == hwnd, "GetActiveWindow() != hwnd\n");
107             ok(GetFocus() == NULL, "GetFocus() != NULL\n");
108             s_nWM_SYSCOMMAND_SC_RESTORE = 0;
109             s_nWM_SYSCOMMAND_NOT_SC_RESTORE = 0;
110             s_nWM_NCACTIVATE = 0;
111             s_nWM_WINDOWPOSCHANGING = 0;
112             s_nWM_ACTIVATE = 0;
113             s_bTracing = TRUE;
114             SwitchToThisWindow(hwnd, TRUE);
115             trace("SwitchToThisWindow(TRUE): tracing...\n");
116             break;
117         case 2: // tracing done
118             s_bTracing = FALSE;
119             trace("SwitchToThisWindow(TRUE): tracing done\n");
120             ok(GetForegroundWindow() == hwnd, "GetForegroundWindow() != hwnd\n");
121             ok(GetActiveWindow() == hwnd, "GetActiveWindow() != hwnd\n");
122             ok(GetFocus() == hwnd, "GetFocus() != hwnd\n");
123             ok(s_nWM_SYSCOMMAND_SC_RESTORE == 1, "WM_SYSCOMMAND SC_RESTORE: %d\n", s_nWM_SYSCOMMAND_SC_RESTORE);
124             ok(!s_nWM_SYSCOMMAND_NOT_SC_RESTORE, "WM_SYSCOMMAND non-SC_RESTORE: %d\n", s_nWM_SYSCOMMAND_NOT_SC_RESTORE);
125             ok(s_nWM_NCACTIVATE == 1, "WM_NCACTIVATE: %d\n", s_nWM_NCACTIVATE);
126             ok(s_nWM_WINDOWPOSCHANGING == 2, "WM_WINDOWPOSCHANGING: %d\n", s_nWM_WINDOWPOSCHANGING);
127             ok(s_nWM_ACTIVATE == 1, "WM_ACTIVATE: %d\n", s_nWM_ACTIVATE);
128             break;
129         //
130         // SwitchToThisWindow(FALSE)
131         //
132         case 3: // minimize
133             SetForegroundWindow(GetDesktopWindow());
134             SetActiveWindow(GetDesktopWindow());
135             ok(GetForegroundWindow() == NULL, "GetForegroundWindow() != NULL\n");
136             ok(GetActiveWindow() == NULL, "GetActiveWindow() != NULL\n");
137             ok(GetFocus() == NULL, "GetFocus() != NULL\n");
138             CloseWindow(hwnd);  // minimize
139             break;
140         case 4: // start tracing
141             ok(GetForegroundWindow() == NULL, "GetForegroundWindow() != NULL\n");
142             ok(GetActiveWindow() == hwnd, "GetActiveWindow() != hwnd\n");
143             ok(GetFocus() == NULL, "GetFocus() != NULL\n");
144             s_nWM_SYSCOMMAND_SC_RESTORE = 0;
145             s_nWM_SYSCOMMAND_NOT_SC_RESTORE = 0;
146             s_nWM_NCACTIVATE = 0;
147             s_nWM_WINDOWPOSCHANGING = 0;
148             s_nWM_ACTIVATE = 0;
149             s_bTracing = TRUE;
150             SwitchToThisWindow(hwnd, FALSE);
151             trace("SwitchToThisWindow(FALSE): tracing...\n");
152             break;
153         case 5: // tracing done
154             s_bTracing = FALSE;
155             trace("SwitchToThisWindow(FALSE): tracing done\n");
156             ok(GetForegroundWindow() == NULL, "GetForegroundWindow() != NULL\n");
157             ok(GetActiveWindow() == hwnd, "GetActiveWindow() != hwnd\n");
158             ok(GetFocus() == NULL, "GetFocus() != NULL\n");
159             ok(!s_nWM_SYSCOMMAND_SC_RESTORE, "WM_SYSCOMMAND SC_RESTORE: %d\n", s_nWM_SYSCOMMAND_SC_RESTORE);
160             ok(!s_nWM_SYSCOMMAND_NOT_SC_RESTORE, "WM_SYSCOMMAND non-SC_RESTORE: %d\n", s_nWM_SYSCOMMAND_NOT_SC_RESTORE);
161             ok(!s_nWM_NCACTIVATE, "WM_NCACTIVATE: %d\n", s_nWM_NCACTIVATE);
162             ok(!s_nWM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING: %d\n", s_nWM_WINDOWPOSCHANGING);
163             ok(!s_nWM_ACTIVATE, "WM_ACTIVATE: %d\n", s_nWM_ACTIVATE);
164             break;
165         default: // finish
166             DestroyWindow(hwnd);
167             return;
168     }
169     SetTimer(hwnd, id + 1, TIMER_INTERVAL, NULL);
170 }
171 
172 static LRESULT CALLBACK
WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)173 WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
174 {
175     DoMessage(hwnd, uMsg, wParam, lParam);
176     switch (uMsg)
177     {
178         case WM_CREATE:
179             SetTimer(hwnd, 0, TIMER_INTERVAL, NULL);
180             break;
181         case WM_TIMER:
182             OnTimer(hwnd, (UINT)wParam);
183             break;
184         case WM_DESTROY:
185             PostQuitMessage(0);
186             break;
187         default:
188             return DefWindowProc(hwnd, uMsg, wParam, lParam);
189     }
190     return 0;
191 }
192 
START_TEST(SwitchToThisWindow)193 START_TEST(SwitchToThisWindow)
194 {
195     WNDCLASSW wc;
196     HICON hIcon;
197     HCURSOR hCursor;
198     ATOM atom;
199     HWND hwnd;
200     MSG msg;
201 
202     hIcon = LoadIcon(NULL, IDI_APPLICATION);
203     ok(hIcon != NULL, "hIcon was NULL\n");
204     hCursor = LoadCursor(NULL, IDC_ARROW);
205     ok(hCursor != NULL, "hCursor was NULL\n");
206 
207     ZeroMemory(&wc, sizeof(wc));
208     wc.lpfnWndProc = WindowProc;
209     wc.hInstance = GetModuleHandleW(NULL);
210     wc.hIcon = hIcon;
211     wc.hCursor = hCursor;
212     wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
213     wc.lpszClassName = s_szClassName;
214     atom = RegisterClassW(&wc);
215     ok(atom != 0, "RegisterClassW failed\n");
216 
217     if (!atom)
218     {
219         skip("atom is zero\n");
220         DestroyIcon(hIcon);
221         DestroyCursor(hCursor);
222         return;
223     }
224 
225     hwnd = CreateWindowW(s_szClassName, L"SwitchToThisWindow", WS_OVERLAPPEDWINDOW,
226                          CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
227                          NULL, NULL, GetModuleHandleW(NULL), NULL);
228     ok(hwnd != NULL, "CreateWindowW failed\n");
229     trace("hwnd: %p\n", hwnd);
230 
231     if (!hwnd)
232     {
233         skip("hwnd is NULL\n");
234         UnregisterClassW(s_szClassName, GetModuleHandleW(NULL));
235         DestroyIcon(hIcon);
236         DestroyCursor(hCursor);
237         return;
238     }
239 
240     ShowWindow(hwnd, SW_SHOWNORMAL);
241     UpdateWindow(hwnd);
242 
243     while (GetMessage(&msg, NULL, 0, 0))
244     {
245         TranslateMessage(&msg);
246         DispatchMessage(&msg);
247     }
248 
249     UnregisterClassW(s_szClassName, GetModuleHandleW(NULL));
250     DestroyIcon(hIcon);
251     DestroyCursor(hCursor);
252 }
253