mirror of
https://github.com/reactos/reactos.git
synced 2025-07-28 12:01:55 +00:00
[SHELL32_APITEST] Certainly close newly-opened windows (#8171)
It's frustrating when windows open during a test and remain after the test is over. JIRA issue: ROSTESTS-402 - Delete closewnd.cpp. Enhance closewnd.h. - Modify ShellExecCmdLine, ShellExec_RunDLL, ShellExecuteEx, and ShellExecuteW testcases. - Certainly close the newly-opened windows.
This commit is contained in:
parent
f1332c7722
commit
f7c36c6d94
8 changed files with 210 additions and 277 deletions
|
@ -2,7 +2,6 @@
|
|||
spec2def(shell32_apitest.exe shell32_apitest.spec)
|
||||
|
||||
list(APPEND SOURCE
|
||||
closewnd.cpp
|
||||
AddCommas.cpp
|
||||
CFSFolder.cpp
|
||||
CheckEscapes.cpp
|
||||
|
|
|
@ -53,7 +53,10 @@ static void TEST_Start(void)
|
|||
|
||||
static void TEST_End(void)
|
||||
{
|
||||
Sleep(500);
|
||||
// Execution can be asynchronous; you have to wait for it to finish.
|
||||
Sleep(2000);
|
||||
|
||||
// Close newly-opened window(s)
|
||||
GetWindowList(&s_List2);
|
||||
CloseNewWindows(&s_List1, &s_List2);
|
||||
FreeWindowList(&s_List1);
|
||||
|
@ -62,8 +65,6 @@ static void TEST_End(void)
|
|||
|
||||
static void TEST_RealShellExecuteExA(void)
|
||||
{
|
||||
TEST_Start();
|
||||
|
||||
INT_PTR ret;
|
||||
|
||||
ret = (INT_PTR)s_fnRealShellExecuteExA(
|
||||
|
@ -82,14 +83,10 @@ static void TEST_RealShellExecuteExA(void)
|
|||
ok_long((LONG)ret, 42);
|
||||
else
|
||||
ok_long((LONG)ret, 2);
|
||||
|
||||
TEST_End();
|
||||
}
|
||||
|
||||
static void TEST_RealShellExecuteExW(void)
|
||||
{
|
||||
TEST_Start();
|
||||
|
||||
INT_PTR ret;
|
||||
|
||||
ret = (INT_PTR)s_fnRealShellExecuteExW(
|
||||
|
@ -105,8 +102,6 @@ static void TEST_RealShellExecuteExW(void)
|
|||
NULL,
|
||||
0);
|
||||
ok_long((LONG)ret, 42);
|
||||
|
||||
TEST_End();
|
||||
}
|
||||
|
||||
START_TEST(RealShellExecuteEx)
|
||||
|
@ -129,8 +124,12 @@ START_TEST(RealShellExecuteEx)
|
|||
return;
|
||||
}
|
||||
|
||||
TEST_Start();
|
||||
|
||||
TEST_RealShellExecuteExA();
|
||||
TEST_RealShellExecuteExW();
|
||||
|
||||
TEST_End();
|
||||
|
||||
FreeLibrary(s_hSHELL32);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <strsafe.h>
|
||||
#include <versionhelpers.h>
|
||||
#include "shell32_apitest_sub.h"
|
||||
#include "closewnd.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
@ -549,46 +550,6 @@ static const TEST_ENTRY s_entries_2[] =
|
|||
{ __LINE__, FALSE, TRUE, L"\"Test File 2.bat\" \"Test File.txt\"", s_cur_dir },
|
||||
};
|
||||
|
||||
typedef struct OPENWNDS
|
||||
{
|
||||
UINT count;
|
||||
HWND *phwnd;
|
||||
} OPENWNDS;
|
||||
|
||||
static OPENWNDS s_wi0 = { 0 }, s_wi1 = { 0 };
|
||||
|
||||
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
|
||||
{
|
||||
OPENWNDS *info = (OPENWNDS *)lParam;
|
||||
info->phwnd = (HWND *)realloc(info->phwnd, (info->count + 1) * sizeof(HWND));
|
||||
if (!info->phwnd)
|
||||
return FALSE;
|
||||
info->phwnd[info->count] = hwnd;
|
||||
++(info->count);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void CleanupNewlyCreatedWindows(void)
|
||||
{
|
||||
EnumWindows(EnumWindowsProc, (LPARAM)&s_wi1);
|
||||
for (UINT i1 = 0; i1 < s_wi1.count; ++i1)
|
||||
{
|
||||
BOOL bFound = FALSE;
|
||||
for (UINT i0 = 0; i0 < s_wi0.count; ++i0)
|
||||
{
|
||||
if (s_wi1.phwnd[i1] == s_wi0.phwnd[i0])
|
||||
{
|
||||
bFound = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bFound)
|
||||
PostMessageW(s_wi1.phwnd[i1], WM_CLOSE, 0, 0);
|
||||
}
|
||||
free(s_wi1.phwnd);
|
||||
ZeroMemory(&s_wi1, sizeof(s_wi1));
|
||||
}
|
||||
|
||||
static void DoEntry(const TEST_ENTRY *pEntry)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
@ -626,8 +587,33 @@ static void DoEntry(const TEST_ENTRY *pEntry)
|
|||
|
||||
ok(result == pEntry->result, "Line %d: result expected %d, was %d\n",
|
||||
pEntry->lineno, pEntry->result, result);
|
||||
}
|
||||
|
||||
CleanupNewlyCreatedWindows();
|
||||
static WINDOW_LIST s_List1, s_List2;
|
||||
|
||||
static VOID TEST_ShellExecCmdLine(VOID)
|
||||
{
|
||||
GetWindowList(&s_List1);
|
||||
|
||||
// do tests
|
||||
for (size_t i = 0; i < _countof(s_entries_1); ++i)
|
||||
{
|
||||
DoEntry(&s_entries_1[i]);
|
||||
}
|
||||
SetEnvironmentVariableW(L"PATH", s_cur_dir);
|
||||
for (size_t i = 0; i < _countof(s_entries_2); ++i)
|
||||
{
|
||||
DoEntry(&s_entries_2[i]);
|
||||
}
|
||||
|
||||
// Execution can be asynchronous; you have to wait for it to finish.
|
||||
Sleep(2000);
|
||||
|
||||
// Close newly-opened window(s)
|
||||
GetWindowList(&s_List2);
|
||||
CloseNewWindows(&s_List1, &s_List2);
|
||||
FreeWindowList(&s_List1);
|
||||
FreeWindowList(&s_List2);
|
||||
}
|
||||
|
||||
START_TEST(ShellExecCmdLine)
|
||||
|
@ -657,14 +643,6 @@ START_TEST(ShellExecCmdLine)
|
|||
return;
|
||||
}
|
||||
|
||||
// record open windows
|
||||
if (!EnumWindows(EnumWindowsProc, (LPARAM)&s_wi0))
|
||||
{
|
||||
skip("EnumWindows failed\n");
|
||||
free(s_wi0.phwnd);
|
||||
return;
|
||||
}
|
||||
|
||||
// s_win_test_exe
|
||||
GetWindowsDirectoryW(s_win_test_exe, _countof(s_win_test_exe));
|
||||
PathAppendW(s_win_test_exe, L"test program.exe");
|
||||
|
@ -672,7 +650,6 @@ START_TEST(ShellExecCmdLine)
|
|||
if (!ret)
|
||||
{
|
||||
skip("Please retry with admin rights\n");
|
||||
free(s_wi0.phwnd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -700,27 +677,14 @@ START_TEST(ShellExecCmdLine)
|
|||
// s_cur_dir
|
||||
GetCurrentDirectoryW(_countof(s_cur_dir), s_cur_dir);
|
||||
|
||||
// do tests
|
||||
for (size_t i = 0; i < _countof(s_entries_1); ++i)
|
||||
{
|
||||
DoEntry(&s_entries_1[i]);
|
||||
}
|
||||
SetEnvironmentVariableW(L"PATH", s_cur_dir);
|
||||
for (size_t i = 0; i < _countof(s_entries_2); ++i)
|
||||
{
|
||||
DoEntry(&s_entries_2[i]);
|
||||
}
|
||||
TEST_ShellExecCmdLine();
|
||||
|
||||
Sleep(2000);
|
||||
CleanupNewlyCreatedWindows();
|
||||
// Some process can lock the file of s_win_test_exe
|
||||
Sleep(1000);
|
||||
|
||||
// clean up
|
||||
ok(DeleteFileW(s_win_test_exe), "failed to delete the test file\n");
|
||||
ok(DeleteFileW(s_sys_bat_file), "failed to delete the test file\n");
|
||||
ok(DeleteFileA("Test File 1.txt"), "failed to delete the test file\n");
|
||||
ok(DeleteFileA("Test File 2.bat"), "failed to delete the test file\n");
|
||||
free(s_wi0.phwnd);
|
||||
|
||||
DoWaitForWindow(SUB_CLASSNAME, SUB_CLASSNAME, TRUE, TRUE);
|
||||
Sleep(100);
|
||||
}
|
||||
|
|
|
@ -26,36 +26,41 @@ static VOID TEST_ShellExec_RunDLLW(VOID)
|
|||
ShellExec_RunDLLW(NULL, NULL, L"?0?notepad.exe", SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
static VOID CleanupWindowList(VOID)
|
||||
static BOOL CloseNotepad(VOID)
|
||||
{
|
||||
GetWindowListForClose(&s_List2);
|
||||
HWND hwndNew;
|
||||
WCHAR szClass[64];
|
||||
|
||||
// Execution can be asynchronous; you have to wait for it to finish.
|
||||
Sleep(1000);
|
||||
|
||||
// Close newly-opened window(s)
|
||||
GetWindowList(&s_List2);
|
||||
hwndNew = FindNewWindow(&s_List1, &s_List2);
|
||||
if (!GetClassNameW(hwndNew, szClass, _countof(szClass)))
|
||||
szClass[0] = UNICODE_NULL;
|
||||
CloseNewWindows(&s_List1, &s_List2);
|
||||
FreeWindowList(&s_List1);
|
||||
FreeWindowList(&s_List2);
|
||||
return lstrcmpiW(szClass, L"Notepad") == 0;
|
||||
}
|
||||
|
||||
START_TEST(ShellExec_RunDLL)
|
||||
{
|
||||
HWND hwndNotepad;
|
||||
BOOL ret;
|
||||
|
||||
GetWindowList(&s_List1);
|
||||
TEST_ShellExec_RunDLL();
|
||||
Sleep(1000);
|
||||
hwndNotepad = FindWindowW(L"Notepad", NULL);
|
||||
ok(hwndNotepad != NULL, "Notepad not found\n");
|
||||
CleanupWindowList();
|
||||
ret = CloseNotepad();
|
||||
ok(ret, "Notepad not found\n");
|
||||
|
||||
GetWindowList(&s_List1);
|
||||
TEST_ShellExec_RunDLLA();
|
||||
Sleep(1000);
|
||||
hwndNotepad = FindWindowW(L"Notepad", NULL);
|
||||
ok(hwndNotepad != NULL, "Notepad not found\n");
|
||||
CleanupWindowList();
|
||||
ret = CloseNotepad();
|
||||
ok(ret, "Notepad not found\n");
|
||||
|
||||
GetWindowList(&s_List1);
|
||||
TEST_ShellExec_RunDLLW();
|
||||
Sleep(1000);
|
||||
hwndNotepad = FindWindowW(L"Notepad", NULL);
|
||||
ok(hwndNotepad != NULL, "Notepad not found\n");
|
||||
CleanupWindowList();
|
||||
ret = CloseNotepad();
|
||||
ok(ret, "Notepad not found\n");
|
||||
}
|
||||
|
|
|
@ -314,17 +314,30 @@ static BOOL TEST_Start(void)
|
|||
|
||||
static void TEST_End(void)
|
||||
{
|
||||
GetWindowListForClose(&s_List2);
|
||||
CloseNewWindows(&s_List1, &s_List2);
|
||||
FreeWindowList(&s_List1);
|
||||
FreeWindowList(&s_List2);
|
||||
|
||||
DeleteFileW(s_win_test_exe);
|
||||
DeleteFileW(s_sys_test_exe);
|
||||
DeleteFileW(s_win_txt_file);
|
||||
DeleteFileW(s_sys_txt_file);
|
||||
DeleteFileW(s_win_bat_file);
|
||||
DeleteFileW(s_sys_bat_file);
|
||||
|
||||
// Execution can be asynchronous; you have to wait for it to finish.
|
||||
INT nCount = GetWindowCount();
|
||||
for (INT i = 0; i < 100; ++i)
|
||||
{
|
||||
INT nOldCount = nCount;
|
||||
Sleep(3000);
|
||||
nCount = GetWindowCount();
|
||||
if (nOldCount == nCount)
|
||||
break;
|
||||
}
|
||||
Sleep(3000);
|
||||
|
||||
// Close newly-opened window(s)
|
||||
GetWindowList(&s_List2);
|
||||
CloseNewWindows(&s_List1, &s_List2);
|
||||
FreeWindowList(&s_List1);
|
||||
FreeWindowList(&s_List2);
|
||||
}
|
||||
|
||||
static void test_properties()
|
||||
|
|
|
@ -10,18 +10,22 @@
|
|||
#include <stdio.h>
|
||||
#include <winbase.h>
|
||||
#include <shlwapi.h>
|
||||
#include "closewnd.h"
|
||||
|
||||
#define WAIT_SLEEP 700
|
||||
|
||||
// ShellExecuteW(handle, "open", <path_to_executable>, <parameters>, NULL, SW_SHOWNORMAL);
|
||||
|
||||
static WINDOW_LIST s_List1, s_List2;
|
||||
|
||||
START_TEST(ShellExecuteW)
|
||||
{
|
||||
INT ret;
|
||||
HINSTANCE hInstance;
|
||||
HWND hWnd;
|
||||
WCHAR WinDir[MAX_PATH], SysDir[MAX_PATH], SysDrive[MAX_PATH];
|
||||
|
||||
GetWindowList(&s_List1);
|
||||
|
||||
if (!GetWindowsDirectoryW(WinDir, _countof(WinDir)))
|
||||
{
|
||||
skip("GetWindowsDirectoryW failed\n");
|
||||
|
@ -47,104 +51,57 @@ START_TEST(ShellExecuteW)
|
|||
ret = (INT)(UINT_PTR)hInstance;
|
||||
ok(ret > 31, "TEST #1: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||
trace("TEST #1 ret: %d.\n", ret);
|
||||
if (hInstance)
|
||||
{
|
||||
Sleep(WAIT_SLEEP);
|
||||
// Terminate Window
|
||||
hWnd = FindWindowW(NULL, L"Display Properties");
|
||||
PostMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
|
||||
}
|
||||
|
||||
// TEST #2: Open Notepad
|
||||
hInstance = ShellExecuteW(NULL, L"open", L"notepad.exe", NULL, NULL, SW_SHOWNORMAL);
|
||||
ret = (INT)(UINT_PTR)hInstance;
|
||||
ok(ret > 31, "TEST #2: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||
trace("TEST #2 ret: %d.\n", ret);
|
||||
if (hInstance)
|
||||
{
|
||||
Sleep(WAIT_SLEEP);
|
||||
// Terminate Window
|
||||
hWnd = FindWindowW(L"Notepad", L"Untitled - Notepad");
|
||||
PostMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
|
||||
}
|
||||
|
||||
// TEST #3: Open Windows folder
|
||||
hInstance = ShellExecuteW(NULL, NULL, WinDir, NULL, NULL, SW_SHOWNORMAL);
|
||||
ret = (INT)(UINT_PTR)hInstance;
|
||||
ok(ret > 31, "TEST #3: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||
trace("TEST #3 ret: %d.\n", ret);
|
||||
if (hInstance)
|
||||
{
|
||||
Sleep(WAIT_SLEEP);
|
||||
// Terminate Window
|
||||
hWnd = FindWindowW(L"CabinetWClass", WinDir);
|
||||
PostMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
|
||||
}
|
||||
|
||||
// TEST #4: Open system32 folder
|
||||
hInstance = ShellExecuteW(NULL, L"open", SysDir, NULL, NULL, SW_SHOWNORMAL);
|
||||
ret = (INT)(UINT_PTR)hInstance;
|
||||
ok(ret > 31, "TEST #4: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||
trace("TEST #4 ret: %d.\n", ret);
|
||||
if (hInstance)
|
||||
{
|
||||
Sleep(WAIT_SLEEP);
|
||||
// Terminate Window
|
||||
hWnd = FindWindowW(L"CabinetWClass", SysDir);
|
||||
PostMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
|
||||
}
|
||||
|
||||
// TEST #5: Open %SystemDrive%
|
||||
hInstance = ShellExecuteW(NULL, L"explore", SysDrive, NULL, NULL, SW_SHOWNORMAL);
|
||||
ret = (INT)(UINT_PTR)hInstance;
|
||||
ok(ret > 31, "TEST #5: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||
trace("TEST #5 ret: %d.\n", ret);
|
||||
if (hInstance)
|
||||
{
|
||||
Sleep(WAIT_SLEEP);
|
||||
// Terminate Window
|
||||
hWnd = FindWindowW(L"ExploreWClass", SysDrive);
|
||||
PostMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
|
||||
}
|
||||
|
||||
// TEST #6: Open Explorer Search on %SYSTEMDRIVE%
|
||||
hInstance = ShellExecuteW(NULL, L"find", SysDrive, NULL, NULL, SW_SHOWNORMAL);
|
||||
ret = (INT)(UINT_PTR)hInstance;
|
||||
ok(ret > 31, "TEST #6: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||
trace("TEST #6 ret: %d.\n", ret);
|
||||
if (hInstance)
|
||||
{
|
||||
Sleep(WAIT_SLEEP);
|
||||
// Terminate Window
|
||||
hWnd = FindWindowW(L"CabinetWClass", L"Search Results");
|
||||
PostMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
|
||||
}
|
||||
|
||||
// TEST #7: Open My Documents ("::{450d8fba-ad25-11d0-98a8-0800361b1103}")
|
||||
hInstance = ShellExecuteW(NULL, NULL, L"::{450d8fba-ad25-11d0-98a8-0800361b1103}", NULL, NULL, SW_SHOWNORMAL);
|
||||
ret = (INT)(UINT_PTR)hInstance;
|
||||
ok(ret > 31, "TEST #7: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||
trace("TEST #7 ret: %d.\n", ret);
|
||||
if (hInstance)
|
||||
{
|
||||
Sleep(WAIT_SLEEP);
|
||||
// Terminate Window
|
||||
hWnd = FindWindowW(L"CabinetWClass", NULL);
|
||||
PostMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
|
||||
}
|
||||
|
||||
// TEST #8: Open My Documents ("shell:::{450d8fba-ad25-11d0-98a8-0800361b1103}")
|
||||
hInstance = ShellExecuteW(NULL, L"open", L"shell:::{450d8fba-ad25-11d0-98a8-0800361b1103}", NULL, NULL, SW_SHOWNORMAL);
|
||||
ret = (INT)(UINT_PTR)hInstance;
|
||||
ok(ret > 31, "TEST #8: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||
trace("TEST #8 ret: %d.\n", ret);
|
||||
if (hInstance)
|
||||
{
|
||||
Sleep(WAIT_SLEEP);
|
||||
// Terminate Window
|
||||
hWnd = FindWindowW(L"CabinetWClass", NULL);
|
||||
PostMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
|
||||
}
|
||||
|
||||
// Execution can be asynchronous; you have to wait for it to finish.
|
||||
Sleep(2000);
|
||||
|
||||
// Close newly-opened window(s)
|
||||
GetWindowList(&s_List2);
|
||||
CloseNewWindows(&s_List1, &s_List2);
|
||||
FreeWindowList(&s_List1);
|
||||
FreeWindowList(&s_List2);
|
||||
}
|
||||
|
||||
// Windows Server 2003 and Windows XP SP3 return values (Win 7 returns 42 in all cases)
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
/*
|
||||
* PROJECT: ReactOS API tests
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: Close windows after tests
|
||||
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
|
||||
#include "shelltest.h"
|
||||
#include "closewnd.h"
|
||||
|
||||
void FreeWindowList(PWINDOW_LIST pList)
|
||||
{
|
||||
free(pList->m_phWnds);
|
||||
pList->m_phWnds = NULL;
|
||||
pList->m_chWnds = 0;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
|
||||
{
|
||||
if (!IsWindowVisible(hwnd))
|
||||
return TRUE;
|
||||
|
||||
PWINDOW_LIST pList = (PWINDOW_LIST)lParam;
|
||||
SIZE_T cb = (pList->m_chWnds + 1) * sizeof(HWND);
|
||||
HWND *phWnds = (HWND *)realloc(pList->m_phWnds, cb);
|
||||
if (!phWnds)
|
||||
return FALSE;
|
||||
phWnds[pList->m_chWnds++] = hwnd;
|
||||
pList->m_phWnds = phWnds;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void GetWindowList(PWINDOW_LIST pList)
|
||||
{
|
||||
pList->m_phWnds = NULL;
|
||||
pList->m_chWnds = 0;
|
||||
EnumWindows(EnumWindowsProc, (LPARAM)pList);
|
||||
}
|
||||
|
||||
void GetWindowListForClose(PWINDOW_LIST pList)
|
||||
{
|
||||
for (UINT tries = 5; tries--;)
|
||||
{
|
||||
if (tries)
|
||||
FreeWindowList(pList);
|
||||
GetWindowList(pList);
|
||||
Sleep(500);
|
||||
WINDOW_LIST list;
|
||||
GetWindowList(&list);
|
||||
SIZE_T count = list.m_chWnds;
|
||||
FreeWindowList(&list);
|
||||
if (count == pList->m_chWnds)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static HWND FindInWindowList(const WINDOW_LIST &list, HWND hWnd)
|
||||
{
|
||||
for (SIZE_T i = 0; i < list.m_chWnds; ++i)
|
||||
{
|
||||
if (list.m_phWnds[i] == hWnd)
|
||||
return hWnd;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HWND FindNewWindow(PWINDOW_LIST List1, PWINDOW_LIST List2)
|
||||
{
|
||||
for (SIZE_T i2 = 0; i2 < List2->m_chWnds; ++i2)
|
||||
{
|
||||
HWND hWnd = List2->m_phWnds[i2];
|
||||
if (!IsWindowEnabled(hWnd) || !IsWindowVisible(hWnd))
|
||||
continue;
|
||||
|
||||
BOOL bFoundInList1 = FALSE;
|
||||
for (SIZE_T i1 = 0; i1 < List1->m_chWnds; ++i1)
|
||||
{
|
||||
if (hWnd == List1->m_phWnds[i1])
|
||||
{
|
||||
bFoundInList1 = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFoundInList1)
|
||||
return hWnd;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void WaitForForegroundWindow(HWND hWnd, UINT wait = 250)
|
||||
{
|
||||
for (UINT waited = 0, interval = 50; waited < wait; waited += interval)
|
||||
{
|
||||
if (GetForegroundWindow() == hWnd || !IsWindowVisible(hWnd))
|
||||
return;
|
||||
Sleep(interval);
|
||||
}
|
||||
}
|
||||
|
||||
void CloseNewWindows(PWINDOW_LIST List1, PWINDOW_LIST List2)
|
||||
{
|
||||
for (SIZE_T i = 0; i < List2->m_chWnds; ++i)
|
||||
{
|
||||
HWND hWnd = List2->m_phWnds[i];
|
||||
if (!IsWindow(hWnd) || FindInWindowList(*List1, hWnd))
|
||||
continue;
|
||||
|
||||
SwitchToThisWindow(hWnd, TRUE);
|
||||
WaitForForegroundWindow(hWnd);
|
||||
|
||||
if (!PostMessageW(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0))
|
||||
{
|
||||
DWORD_PTR result;
|
||||
SendMessageTimeoutW(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0, 0, 3000, &result);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
* PROJECT: ReactOS API tests
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: Close windows after tests
|
||||
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
* COPYRIGHT: Copyright 2024-2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@ -13,8 +13,122 @@ typedef struct WINDOW_LIST
|
|||
HWND *m_phWnds;
|
||||
} WINDOW_LIST, *PWINDOW_LIST;
|
||||
|
||||
void GetWindowList(PWINDOW_LIST pList);
|
||||
void GetWindowListForClose(PWINDOW_LIST pList);
|
||||
HWND FindNewWindow(PWINDOW_LIST List1, PWINDOW_LIST List2);
|
||||
void CloseNewWindows(PWINDOW_LIST List1, PWINDOW_LIST List2);
|
||||
void FreeWindowList(PWINDOW_LIST pList);
|
||||
static inline VOID FreeWindowList(PWINDOW_LIST pList)
|
||||
{
|
||||
free(pList->m_phWnds);
|
||||
pList->m_phWnds = NULL;
|
||||
pList->m_chWnds = 0;
|
||||
}
|
||||
|
||||
static inline BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
|
||||
{
|
||||
if (!IsWindowVisible(hwnd))
|
||||
return TRUE;
|
||||
|
||||
PWINDOW_LIST pList = (PWINDOW_LIST)lParam;
|
||||
SIZE_T cb = (pList->m_chWnds + 1) * sizeof(HWND);
|
||||
HWND *phWnds = (HWND *)realloc(pList->m_phWnds, cb);
|
||||
if (!phWnds)
|
||||
return FALSE;
|
||||
phWnds[pList->m_chWnds++] = hwnd;
|
||||
pList->m_phWnds = phWnds;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline VOID GetWindowList(PWINDOW_LIST pList)
|
||||
{
|
||||
pList->m_phWnds = NULL;
|
||||
pList->m_chWnds = 0;
|
||||
EnumWindows(EnumWindowsProc, (LPARAM)pList);
|
||||
}
|
||||
|
||||
static inline HWND FindInWindowList(const WINDOW_LIST &list, HWND hWnd)
|
||||
{
|
||||
for (SIZE_T i = 0; i < list.m_chWnds; ++i)
|
||||
{
|
||||
if (list.m_phWnds[i] == hWnd)
|
||||
return hWnd;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline VOID CloseNewWindows(PWINDOW_LIST List1, PWINDOW_LIST List2)
|
||||
{
|
||||
for (SIZE_T i = 0; i < List2->m_chWnds; ++i)
|
||||
{
|
||||
HWND hWnd = List2->m_phWnds[i];
|
||||
if (!IsWindowVisible(hWnd) || FindInWindowList(*List1, hWnd))
|
||||
continue;
|
||||
|
||||
if (!PostMessageW(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0))
|
||||
{
|
||||
DWORD_PTR result;
|
||||
if (!SendMessageTimeoutW(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0, SMTO_ABORTIFHUNG, 3000, &result))
|
||||
{
|
||||
SwitchToThisWindow(hWnd, TRUE);
|
||||
|
||||
// SwitchToThisWindow may take time
|
||||
Sleep(500);
|
||||
|
||||
// Alt+F4
|
||||
INPUT inputs[4];
|
||||
ZeroMemory(&inputs, sizeof(inputs));
|
||||
inputs[0].type = inputs[1].type = inputs[2].type = inputs[3].type = INPUT_KEYBOARD;
|
||||
inputs[0].ki.wVk = inputs[3].ki.wVk = VK_LMENU;
|
||||
inputs[1].ki.wVk = inputs[2].ki.wVk = VK_F4;
|
||||
inputs[2].ki.dwFlags = inputs[3].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
SendInput(_countof(inputs), inputs, sizeof(INPUT));
|
||||
|
||||
// Closing a window may take time
|
||||
Sleep(1000);
|
||||
|
||||
if (IsWindowVisible(hWnd))
|
||||
{
|
||||
CHAR szClass[64];
|
||||
GetClassNameA(hWnd, szClass, _countof(szClass));
|
||||
trace("Unable to close window %p (%s)\n", hWnd, szClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline HWND FindNewWindow(PWINDOW_LIST List1, PWINDOW_LIST List2)
|
||||
{
|
||||
for (SIZE_T i2 = 0; i2 < List2->m_chWnds; ++i2)
|
||||
{
|
||||
HWND hWnd = List2->m_phWnds[i2];
|
||||
if (!IsWindowEnabled(hWnd) || !IsWindowVisible(hWnd))
|
||||
continue;
|
||||
|
||||
BOOL bFoundInList1 = FALSE;
|
||||
for (SIZE_T i1 = 0; i1 < List1->m_chWnds; ++i1)
|
||||
{
|
||||
if (hWnd == List1->m_phWnds[i1])
|
||||
{
|
||||
bFoundInList1 = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFoundInList1)
|
||||
return hWnd;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline BOOL CALLBACK CountWindowsProc(HWND hwnd, LPARAM lParam)
|
||||
{
|
||||
if (!IsWindowVisible(hwnd))
|
||||
return TRUE;
|
||||
|
||||
*(PINT)lParam += 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline INT GetWindowCount(VOID)
|
||||
{
|
||||
INT nCount = 0;
|
||||
EnumWindows(CountWindowsProc, (LPARAM)&nCount);
|
||||
return nCount;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue