diff --git a/modules/rostests/apitests/shell32/ShellExecuteEx.cpp b/modules/rostests/apitests/shell32/ShellExecuteEx.cpp index 2c26b33be37..64759a49c1e 100644 --- a/modules/rostests/apitests/shell32/ShellExecuteEx.cpp +++ b/modules/rostests/apitests/shell32/ShellExecuteEx.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "shell32_apitest_sub.h" static WCHAR s_win_dir[MAX_PATH]; @@ -313,8 +314,7 @@ static BOOL TEST_Start(void) static void TEST_End(void) { - Sleep(500); - GetWindowList(&s_List2); + GetWindowListForClose(&s_List2); CloseNewWindows(&s_List1, &s_List2); FreeWindowList(&s_List1); FreeWindowList(&s_List2); @@ -368,26 +368,40 @@ static void test_properties() static void test_sei_lpIDList() { - if (IsWindowsVistaOrGreater()) + // Note: SEE_MASK_FLAG_NO_UI prevents the test from blocking with a MessageBox + WCHAR path[MAX_PATH]; + + /* This tests ShellExecuteEx with lpIDList for explorer C:\ */ + GetSystemDirectoryW(path, _countof(path)); + PathStripToRootW(path); + LPITEMIDLIST pidl = ILCreateFromPathW(path); + if (!pidl) { - skip("Vista+\n"); + skip("Unable to initialize test\n"); return; } - /* This tests ShellExecuteEx with lpIDList for explorer C:\ */ - - /* ITEMIDLIST for CLSID of 'My Computer' followed by PIDL for 'C:\' */ - BYTE lpitemidlist[30] = { 0x14, 0, 0x1f, 0, 0xe0, 0x4f, 0xd0, 0x20, 0xea, - 0x3a, 0x69, 0x10, 0xa2, 0xd8, 0x08, 0, 0x2b, 0x30, 0x30, 0x9d, // My Computer - 0x8, 0, 0x23, 0x43, 0x3a, 0x5c, 0x5c, 0, 0, 0,}; // C:\\ + NUL-NUL ending - SHELLEXECUTEINFOW ShellExecInfo = { sizeof(ShellExecInfo) }; - ShellExecInfo.fMask = SEE_MASK_IDLIST; - ShellExecInfo.hwnd = NULL; ShellExecInfo.nShow = SW_SHOWNORMAL; - ShellExecInfo.lpIDList = lpitemidlist; + ShellExecInfo.fMask = SEE_MASK_IDLIST | SEE_MASK_FLAG_NO_UI | SEE_MASK_FLAG_DDEWAIT; + ShellExecInfo.lpIDList = pidl; BOOL ret = ShellExecuteExW(&ShellExecInfo); ok_int(ret, TRUE); + ILFree(pidl); + + /* This tests ShellExecuteEx with lpIDList going through IContextMenu */ + CCoInit ComInit; + pidl = SHCloneSpecialIDList(NULL, CSIDL_PROFILE, TRUE); + if (!pidl) + { + skip("Unable to initialize test\n"); + return; + } + ShellExecInfo.fMask = SEE_MASK_INVOKEIDLIST | SEE_MASK_FLAG_NO_UI | SEE_MASK_FLAG_DDEWAIT; + ShellExecInfo.lpIDList = pidl; + ret = ShellExecuteExW(&ShellExecInfo); + ok_int(ret, TRUE); + ILFree(pidl); } static BOOL diff --git a/modules/rostests/apitests/shell32/closewnd.cpp b/modules/rostests/apitests/shell32/closewnd.cpp index d868f65fd79..a3d26162679 100644 --- a/modules/rostests/apitests/shell32/closewnd.cpp +++ b/modules/rostests/apitests/shell32/closewnd.cpp @@ -37,6 +37,33 @@ void GetWindowList(PWINDOW_LIST pList) 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) @@ -61,30 +88,31 @@ HWND FindNewWindow(PWINDOW_LIST List1, PWINDOW_LIST List2) return NULL; } -#define TRIALS_COUNT 8 +static void WaitForForegroundWindow(HWND hWnd, UINT wait = 1500) +{ + 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) { - INT cDiff = List2->m_chWnds - List1->m_chWnds; - for (INT j = 0; j < cDiff; ++j) + for (SIZE_T i = 0; i < List2->m_chWnds; ++i) { - HWND hWnd = FindNewWindow(List1, List2); - if (!hWnd) - break; - - for (INT i = 0; i < TRIALS_COUNT; ++i) - { - if (!IsWindow(hWnd)) - break; + HWND hWnd = List2->m_phWnds[i]; + if (!IsWindow(hWnd) || FindInWindowList(*List1, hWnd)) + continue; - SwitchToThisWindow(hWnd, TRUE); + SwitchToThisWindow(hWnd, TRUE); + WaitForForegroundWindow(hWnd); - // Alt+F4 - keybd_event(VK_MENU, 0x38, 0, 0); - keybd_event(VK_F4, 0x3E, 0, 0); - keybd_event(VK_F4, 0x3E, KEYEVENTF_KEYUP, 0); - keybd_event(VK_MENU, 0x38, KEYEVENTF_KEYUP, 0); - Sleep(100); + if (!PostMessageW(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0)) + { + DWORD_PTR result; + SendMessageTimeoutW(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0, 0, 3000, &result); } } } diff --git a/modules/rostests/apitests/shell32/closewnd.h b/modules/rostests/apitests/shell32/closewnd.h index 367c058b054..096ce88c1fe 100644 --- a/modules/rostests/apitests/shell32/closewnd.h +++ b/modules/rostests/apitests/shell32/closewnd.h @@ -14,6 +14,7 @@ typedef struct WINDOW_LIST } 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);