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 11 void FreeWindowList(PWINDOW_LIST pList) 12 { 13 free(pList->m_phWnds); 14 pList->m_phWnds = NULL; 15 pList->m_chWnds = 0; 16 } 17 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 33 void GetWindowList(PWINDOW_LIST pList) 34 { 35 pList->m_phWnds = NULL; 36 pList->m_chWnds = 0; 37 EnumWindows(EnumWindowsProc, (LPARAM)pList); 38 } 39 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 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 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 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 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