1 /*
2 * PROJECT: ReactOS API tests
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Close windows after tests
5 * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
6 */
7
8 #include "shelltest.h"
9 #include "closewnd.h"
10
FreeWindowList(PWINDOW_LIST pList)11 void FreeWindowList(PWINDOW_LIST pList)
12 {
13 free(pList->m_phWnds);
14 pList->m_phWnds = NULL;
15 pList->m_chWnds = 0;
16 }
17
EnumWindowsProc(HWND hwnd,LPARAM lParam)18 static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
19 {
20 if (!IsWindowVisible(hwnd))
21 return TRUE;
22
23 PWINDOW_LIST pList = (PWINDOW_LIST)lParam;
24 SIZE_T cb = (pList->m_chWnds + 1) * sizeof(HWND);
25 HWND *phWnds = (HWND *)realloc(pList->m_phWnds, cb);
26 if (!phWnds)
27 return FALSE;
28 phWnds[pList->m_chWnds++] = hwnd;
29 pList->m_phWnds = phWnds;
30 return TRUE;
31 }
32
GetWindowList(PWINDOW_LIST pList)33 void GetWindowList(PWINDOW_LIST pList)
34 {
35 pList->m_phWnds = NULL;
36 pList->m_chWnds = 0;
37 EnumWindows(EnumWindowsProc, (LPARAM)pList);
38 }
39
GetWindowListForClose(PWINDOW_LIST pList)40 void GetWindowListForClose(PWINDOW_LIST pList)
41 {
42 for (UINT tries = 5; tries--;)
43 {
44 if (tries)
45 FreeWindowList(pList);
46 GetWindowList(pList);
47 Sleep(500);
48 WINDOW_LIST list;
49 GetWindowList(&list);
50 SIZE_T count = list.m_chWnds;
51 FreeWindowList(&list);
52 if (count == pList->m_chWnds)
53 break;
54 }
55 }
56
FindInWindowList(const WINDOW_LIST & list,HWND hWnd)57 static HWND FindInWindowList(const WINDOW_LIST &list, HWND hWnd)
58 {
59 for (SIZE_T i = 0; i < list.m_chWnds; ++i)
60 {
61 if (list.m_phWnds[i] == hWnd)
62 return hWnd;
63 }
64 return NULL;
65 }
66
FindNewWindow(PWINDOW_LIST List1,PWINDOW_LIST List2)67 HWND FindNewWindow(PWINDOW_LIST List1, PWINDOW_LIST List2)
68 {
69 for (SIZE_T i2 = 0; i2 < List2->m_chWnds; ++i2)
70 {
71 HWND hWnd = List2->m_phWnds[i2];
72 if (!IsWindowEnabled(hWnd) || !IsWindowVisible(hWnd))
73 continue;
74
75 BOOL bFoundInList1 = FALSE;
76 for (SIZE_T i1 = 0; i1 < List1->m_chWnds; ++i1)
77 {
78 if (hWnd == List1->m_phWnds[i1])
79 {
80 bFoundInList1 = TRUE;
81 break;
82 }
83 }
84
85 if (!bFoundInList1)
86 return hWnd;
87 }
88 return NULL;
89 }
90
WaitForForegroundWindow(HWND hWnd,UINT wait=250)91 static void WaitForForegroundWindow(HWND hWnd, UINT wait = 250)
92 {
93 for (UINT waited = 0, interval = 50; waited < wait; waited += interval)
94 {
95 if (GetForegroundWindow() == hWnd || !IsWindowVisible(hWnd))
96 return;
97 Sleep(interval);
98 }
99 }
100
CloseNewWindows(PWINDOW_LIST List1,PWINDOW_LIST List2)101 void CloseNewWindows(PWINDOW_LIST List1, PWINDOW_LIST List2)
102 {
103 for (SIZE_T i = 0; i < List2->m_chWnds; ++i)
104 {
105 HWND hWnd = List2->m_phWnds[i];
106 if (!IsWindow(hWnd) || FindInWindowList(*List1, hWnd))
107 continue;
108
109 SwitchToThisWindow(hWnd, TRUE);
110 WaitForForegroundWindow(hWnd);
111
112 if (!PostMessageW(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0))
113 {
114 DWORD_PTR result;
115 SendMessageTimeoutW(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0, 0, 3000, &result);
116 }
117 }
118 }
119