mirror of
https://github.com/reactos/reactos.git
synced 2025-07-30 14:42:11 +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)
|
spec2def(shell32_apitest.exe shell32_apitest.spec)
|
||||||
|
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
closewnd.cpp
|
|
||||||
AddCommas.cpp
|
AddCommas.cpp
|
||||||
CFSFolder.cpp
|
CFSFolder.cpp
|
||||||
CheckEscapes.cpp
|
CheckEscapes.cpp
|
||||||
|
|
|
@ -53,7 +53,10 @@ static void TEST_Start(void)
|
||||||
|
|
||||||
static void TEST_End(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);
|
GetWindowList(&s_List2);
|
||||||
CloseNewWindows(&s_List1, &s_List2);
|
CloseNewWindows(&s_List1, &s_List2);
|
||||||
FreeWindowList(&s_List1);
|
FreeWindowList(&s_List1);
|
||||||
|
@ -62,8 +65,6 @@ static void TEST_End(void)
|
||||||
|
|
||||||
static void TEST_RealShellExecuteExA(void)
|
static void TEST_RealShellExecuteExA(void)
|
||||||
{
|
{
|
||||||
TEST_Start();
|
|
||||||
|
|
||||||
INT_PTR ret;
|
INT_PTR ret;
|
||||||
|
|
||||||
ret = (INT_PTR)s_fnRealShellExecuteExA(
|
ret = (INT_PTR)s_fnRealShellExecuteExA(
|
||||||
|
@ -82,14 +83,10 @@ static void TEST_RealShellExecuteExA(void)
|
||||||
ok_long((LONG)ret, 42);
|
ok_long((LONG)ret, 42);
|
||||||
else
|
else
|
||||||
ok_long((LONG)ret, 2);
|
ok_long((LONG)ret, 2);
|
||||||
|
|
||||||
TEST_End();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TEST_RealShellExecuteExW(void)
|
static void TEST_RealShellExecuteExW(void)
|
||||||
{
|
{
|
||||||
TEST_Start();
|
|
||||||
|
|
||||||
INT_PTR ret;
|
INT_PTR ret;
|
||||||
|
|
||||||
ret = (INT_PTR)s_fnRealShellExecuteExW(
|
ret = (INT_PTR)s_fnRealShellExecuteExW(
|
||||||
|
@ -105,8 +102,6 @@ static void TEST_RealShellExecuteExW(void)
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0);
|
||||||
ok_long((LONG)ret, 42);
|
ok_long((LONG)ret, 42);
|
||||||
|
|
||||||
TEST_End();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
START_TEST(RealShellExecuteEx)
|
START_TEST(RealShellExecuteEx)
|
||||||
|
@ -129,8 +124,12 @@ START_TEST(RealShellExecuteEx)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_Start();
|
||||||
|
|
||||||
TEST_RealShellExecuteExA();
|
TEST_RealShellExecuteExA();
|
||||||
TEST_RealShellExecuteExW();
|
TEST_RealShellExecuteExW();
|
||||||
|
|
||||||
|
TEST_End();
|
||||||
|
|
||||||
FreeLibrary(s_hSHELL32);
|
FreeLibrary(s_hSHELL32);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
#include <versionhelpers.h>
|
#include <versionhelpers.h>
|
||||||
#include "shell32_apitest_sub.h"
|
#include "shell32_apitest_sub.h"
|
||||||
|
#include "closewnd.h"
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#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 },
|
{ __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)
|
static void DoEntry(const TEST_ENTRY *pEntry)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
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",
|
ok(result == pEntry->result, "Line %d: result expected %d, was %d\n",
|
||||||
pEntry->lineno, pEntry->result, result);
|
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)
|
START_TEST(ShellExecCmdLine)
|
||||||
|
@ -657,14 +643,6 @@ START_TEST(ShellExecCmdLine)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// record open windows
|
|
||||||
if (!EnumWindows(EnumWindowsProc, (LPARAM)&s_wi0))
|
|
||||||
{
|
|
||||||
skip("EnumWindows failed\n");
|
|
||||||
free(s_wi0.phwnd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// s_win_test_exe
|
// s_win_test_exe
|
||||||
GetWindowsDirectoryW(s_win_test_exe, _countof(s_win_test_exe));
|
GetWindowsDirectoryW(s_win_test_exe, _countof(s_win_test_exe));
|
||||||
PathAppendW(s_win_test_exe, L"test program.exe");
|
PathAppendW(s_win_test_exe, L"test program.exe");
|
||||||
|
@ -672,7 +650,6 @@ START_TEST(ShellExecCmdLine)
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
skip("Please retry with admin rights\n");
|
skip("Please retry with admin rights\n");
|
||||||
free(s_wi0.phwnd);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -700,27 +677,14 @@ START_TEST(ShellExecCmdLine)
|
||||||
// s_cur_dir
|
// s_cur_dir
|
||||||
GetCurrentDirectoryW(_countof(s_cur_dir), s_cur_dir);
|
GetCurrentDirectoryW(_countof(s_cur_dir), s_cur_dir);
|
||||||
|
|
||||||
// do tests
|
TEST_ShellExecCmdLine();
|
||||||
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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Sleep(2000);
|
// Some process can lock the file of s_win_test_exe
|
||||||
CleanupNewlyCreatedWindows();
|
Sleep(1000);
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
ok(DeleteFileW(s_win_test_exe), "failed to delete the test file\n");
|
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(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 1.txt"), "failed to delete the test file\n");
|
||||||
ok(DeleteFileA("Test File 2.bat"), "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);
|
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);
|
CloseNewWindows(&s_List1, &s_List2);
|
||||||
FreeWindowList(&s_List1);
|
FreeWindowList(&s_List1);
|
||||||
FreeWindowList(&s_List2);
|
FreeWindowList(&s_List2);
|
||||||
|
return lstrcmpiW(szClass, L"Notepad") == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
START_TEST(ShellExec_RunDLL)
|
START_TEST(ShellExec_RunDLL)
|
||||||
{
|
{
|
||||||
HWND hwndNotepad;
|
BOOL ret;
|
||||||
|
|
||||||
GetWindowList(&s_List1);
|
GetWindowList(&s_List1);
|
||||||
TEST_ShellExec_RunDLL();
|
TEST_ShellExec_RunDLL();
|
||||||
Sleep(1000);
|
ret = CloseNotepad();
|
||||||
hwndNotepad = FindWindowW(L"Notepad", NULL);
|
ok(ret, "Notepad not found\n");
|
||||||
ok(hwndNotepad != NULL, "Notepad not found\n");
|
|
||||||
CleanupWindowList();
|
|
||||||
|
|
||||||
GetWindowList(&s_List1);
|
GetWindowList(&s_List1);
|
||||||
TEST_ShellExec_RunDLLA();
|
TEST_ShellExec_RunDLLA();
|
||||||
Sleep(1000);
|
ret = CloseNotepad();
|
||||||
hwndNotepad = FindWindowW(L"Notepad", NULL);
|
ok(ret, "Notepad not found\n");
|
||||||
ok(hwndNotepad != NULL, "Notepad not found\n");
|
|
||||||
CleanupWindowList();
|
|
||||||
|
|
||||||
GetWindowList(&s_List1);
|
GetWindowList(&s_List1);
|
||||||
TEST_ShellExec_RunDLLW();
|
TEST_ShellExec_RunDLLW();
|
||||||
Sleep(1000);
|
ret = CloseNotepad();
|
||||||
hwndNotepad = FindWindowW(L"Notepad", NULL);
|
ok(ret, "Notepad not found\n");
|
||||||
ok(hwndNotepad != NULL, "Notepad not found\n");
|
|
||||||
CleanupWindowList();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -314,17 +314,30 @@ static BOOL TEST_Start(void)
|
||||||
|
|
||||||
static void TEST_End(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_win_test_exe);
|
||||||
DeleteFileW(s_sys_test_exe);
|
DeleteFileW(s_sys_test_exe);
|
||||||
DeleteFileW(s_win_txt_file);
|
DeleteFileW(s_win_txt_file);
|
||||||
DeleteFileW(s_sys_txt_file);
|
DeleteFileW(s_sys_txt_file);
|
||||||
DeleteFileW(s_win_bat_file);
|
DeleteFileW(s_win_bat_file);
|
||||||
DeleteFileW(s_sys_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()
|
static void test_properties()
|
||||||
|
|
|
@ -10,18 +10,22 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <winbase.h>
|
#include <winbase.h>
|
||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
|
#include "closewnd.h"
|
||||||
|
|
||||||
#define WAIT_SLEEP 700
|
#define WAIT_SLEEP 700
|
||||||
|
|
||||||
// ShellExecuteW(handle, "open", <path_to_executable>, <parameters>, NULL, SW_SHOWNORMAL);
|
// ShellExecuteW(handle, "open", <path_to_executable>, <parameters>, NULL, SW_SHOWNORMAL);
|
||||||
|
|
||||||
|
static WINDOW_LIST s_List1, s_List2;
|
||||||
|
|
||||||
START_TEST(ShellExecuteW)
|
START_TEST(ShellExecuteW)
|
||||||
{
|
{
|
||||||
INT ret;
|
INT ret;
|
||||||
HINSTANCE hInstance;
|
HINSTANCE hInstance;
|
||||||
HWND hWnd;
|
|
||||||
WCHAR WinDir[MAX_PATH], SysDir[MAX_PATH], SysDrive[MAX_PATH];
|
WCHAR WinDir[MAX_PATH], SysDir[MAX_PATH], SysDrive[MAX_PATH];
|
||||||
|
|
||||||
|
GetWindowList(&s_List1);
|
||||||
|
|
||||||
if (!GetWindowsDirectoryW(WinDir, _countof(WinDir)))
|
if (!GetWindowsDirectoryW(WinDir, _countof(WinDir)))
|
||||||
{
|
{
|
||||||
skip("GetWindowsDirectoryW failed\n");
|
skip("GetWindowsDirectoryW failed\n");
|
||||||
|
@ -47,104 +51,57 @@ START_TEST(ShellExecuteW)
|
||||||
ret = (INT)(UINT_PTR)hInstance;
|
ret = (INT)(UINT_PTR)hInstance;
|
||||||
ok(ret > 31, "TEST #1: ret:%d, LastError: %ld\n", ret, GetLastError());
|
ok(ret > 31, "TEST #1: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||||
trace("TEST #1 ret: %d.\n", ret);
|
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
|
// TEST #2: Open Notepad
|
||||||
hInstance = ShellExecuteW(NULL, L"open", L"notepad.exe", NULL, NULL, SW_SHOWNORMAL);
|
hInstance = ShellExecuteW(NULL, L"open", L"notepad.exe", NULL, NULL, SW_SHOWNORMAL);
|
||||||
ret = (INT)(UINT_PTR)hInstance;
|
ret = (INT)(UINT_PTR)hInstance;
|
||||||
ok(ret > 31, "TEST #2: ret:%d, LastError: %ld\n", ret, GetLastError());
|
ok(ret > 31, "TEST #2: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||||
trace("TEST #2 ret: %d.\n", ret);
|
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
|
// TEST #3: Open Windows folder
|
||||||
hInstance = ShellExecuteW(NULL, NULL, WinDir, NULL, NULL, SW_SHOWNORMAL);
|
hInstance = ShellExecuteW(NULL, NULL, WinDir, NULL, NULL, SW_SHOWNORMAL);
|
||||||
ret = (INT)(UINT_PTR)hInstance;
|
ret = (INT)(UINT_PTR)hInstance;
|
||||||
ok(ret > 31, "TEST #3: ret:%d, LastError: %ld\n", ret, GetLastError());
|
ok(ret > 31, "TEST #3: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||||
trace("TEST #3 ret: %d.\n", ret);
|
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
|
// TEST #4: Open system32 folder
|
||||||
hInstance = ShellExecuteW(NULL, L"open", SysDir, NULL, NULL, SW_SHOWNORMAL);
|
hInstance = ShellExecuteW(NULL, L"open", SysDir, NULL, NULL, SW_SHOWNORMAL);
|
||||||
ret = (INT)(UINT_PTR)hInstance;
|
ret = (INT)(UINT_PTR)hInstance;
|
||||||
ok(ret > 31, "TEST #4: ret:%d, LastError: %ld\n", ret, GetLastError());
|
ok(ret > 31, "TEST #4: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||||
trace("TEST #4 ret: %d.\n", ret);
|
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%
|
// TEST #5: Open %SystemDrive%
|
||||||
hInstance = ShellExecuteW(NULL, L"explore", SysDrive, NULL, NULL, SW_SHOWNORMAL);
|
hInstance = ShellExecuteW(NULL, L"explore", SysDrive, NULL, NULL, SW_SHOWNORMAL);
|
||||||
ret = (INT)(UINT_PTR)hInstance;
|
ret = (INT)(UINT_PTR)hInstance;
|
||||||
ok(ret > 31, "TEST #5: ret:%d, LastError: %ld\n", ret, GetLastError());
|
ok(ret > 31, "TEST #5: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||||
trace("TEST #5 ret: %d.\n", ret);
|
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%
|
// TEST #6: Open Explorer Search on %SYSTEMDRIVE%
|
||||||
hInstance = ShellExecuteW(NULL, L"find", SysDrive, NULL, NULL, SW_SHOWNORMAL);
|
hInstance = ShellExecuteW(NULL, L"find", SysDrive, NULL, NULL, SW_SHOWNORMAL);
|
||||||
ret = (INT)(UINT_PTR)hInstance;
|
ret = (INT)(UINT_PTR)hInstance;
|
||||||
ok(ret > 31, "TEST #6: ret:%d, LastError: %ld\n", ret, GetLastError());
|
ok(ret > 31, "TEST #6: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||||
trace("TEST #6 ret: %d.\n", ret);
|
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}")
|
// TEST #7: Open My Documents ("::{450d8fba-ad25-11d0-98a8-0800361b1103}")
|
||||||
hInstance = ShellExecuteW(NULL, NULL, L"::{450d8fba-ad25-11d0-98a8-0800361b1103}", NULL, NULL, SW_SHOWNORMAL);
|
hInstance = ShellExecuteW(NULL, NULL, L"::{450d8fba-ad25-11d0-98a8-0800361b1103}", NULL, NULL, SW_SHOWNORMAL);
|
||||||
ret = (INT)(UINT_PTR)hInstance;
|
ret = (INT)(UINT_PTR)hInstance;
|
||||||
ok(ret > 31, "TEST #7: ret:%d, LastError: %ld\n", ret, GetLastError());
|
ok(ret > 31, "TEST #7: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||||
trace("TEST #7 ret: %d.\n", ret);
|
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}")
|
// 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);
|
hInstance = ShellExecuteW(NULL, L"open", L"shell:::{450d8fba-ad25-11d0-98a8-0800361b1103}", NULL, NULL, SW_SHOWNORMAL);
|
||||||
ret = (INT)(UINT_PTR)hInstance;
|
ret = (INT)(UINT_PTR)hInstance;
|
||||||
ok(ret > 31, "TEST #8: ret:%d, LastError: %ld\n", ret, GetLastError());
|
ok(ret > 31, "TEST #8: ret:%d, LastError: %ld\n", ret, GetLastError());
|
||||||
trace("TEST #8 ret: %d.\n", ret);
|
trace("TEST #8 ret: %d.\n", ret);
|
||||||
if (hInstance)
|
|
||||||
{
|
// Execution can be asynchronous; you have to wait for it to finish.
|
||||||
Sleep(WAIT_SLEEP);
|
Sleep(2000);
|
||||||
// Terminate Window
|
|
||||||
hWnd = FindWindowW(L"CabinetWClass", NULL);
|
// Close newly-opened window(s)
|
||||||
PostMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
|
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)
|
// 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
|
* PROJECT: ReactOS API tests
|
||||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||||
* PURPOSE: Close windows after tests
|
* 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
|
#pragma once
|
||||||
|
@ -13,8 +13,122 @@ typedef struct WINDOW_LIST
|
||||||
HWND *m_phWnds;
|
HWND *m_phWnds;
|
||||||
} WINDOW_LIST, *PWINDOW_LIST;
|
} WINDOW_LIST, *PWINDOW_LIST;
|
||||||
|
|
||||||
void GetWindowList(PWINDOW_LIST pList);
|
static inline VOID FreeWindowList(PWINDOW_LIST pList)
|
||||||
void GetWindowListForClose(PWINDOW_LIST pList);
|
{
|
||||||
HWND FindNewWindow(PWINDOW_LIST List1, PWINDOW_LIST List2);
|
free(pList->m_phWnds);
|
||||||
void CloseNewWindows(PWINDOW_LIST List1, PWINDOW_LIST List2);
|
pList->m_phWnds = NULL;
|
||||||
void FreeWindowList(PWINDOW_LIST pList);
|
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