From: Katayama Hirofumi MZ Date: Wed, 23 Jan 2019 13:44:11 +0000 (+0900) Subject: [USER32] Fix AppSwitcher (Alt+Tab) (#1296) X-Git-Tag: 0.4.13-dev~646 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=687eba26f32fe80e5419cbc7dee4d484bcc70c40 [USER32] Fix AppSwitcher (Alt+Tab) (#1296) CORE-15653 --- diff --git a/win32ss/user/user32/controls/appswitch.c b/win32ss/user/user32/controls/appswitch.c index 0a5c4f996a2..7f97d0dfacb 100644 --- a/win32ss/user/user32/controls/appswitch.c +++ b/win32ss/user/user32/controls/appswitch.c @@ -165,22 +165,9 @@ void CompleteSwitch(BOOL doSwitch) BOOL CALLBACK EnumerateCallback(HWND window, LPARAM lParam) { HICON hIcon; - HWND hwndOwner; UNREFERENCED_PARAMETER(lParam); - if (!IsWindowVisible(window)) - return TRUE; - - hwndOwner = GetWindow(window, GW_OWNER); - if (hwndOwner && IsWindowVisible(hwndOwner)) - return TRUE; - - GetClassNameW(window, windowText, _countof(windowText)); - if ((wcscmp(L"Shell_TrayWnd", windowText)==0) || - (wcscmp(L"Progman", windowText)==0) ) - return TRUE; - // First try to get the big icon assigned to the window hIcon = (HICON)SendMessageW(window, WM_GETICON, ICON_BIG, 0); if (!hIcon) @@ -221,21 +208,37 @@ BOOL CALLBACK EnumerateCallback(HWND window, LPARAM lParam) // Function mostly compatible with the normal EnumChildWindows, // except it lists in Z-Order and it doesn't ensure consistency // if a window is removed while enumerating -void EnumChildWindowsZOrder(HWND hwnd, WNDENUMPROC callback, LPARAM lParam) +void EnumWindowsZOrder(WNDENUMPROC callback, LPARAM lParam) { - HWND next = GetTopWindow(hwnd); - while (next != NULL) + HWND hwnd, hwndOwner; + WCHAR szClass[64]; + DWORD ExStyle; + + for (hwnd = GetTopWindow(NULL); hwnd; hwnd = GetWindow(hwnd, GW_HWNDNEXT)) { - if (!hwnd && !IsWindowVisible(next)) + if (!IsWindowVisible(hwnd)) + continue; + + // check special windows + if (!GetClassNameW(hwnd, szClass, _countof(szClass)) || + wcscmp(szClass, L"Shell_TrayWnd") == 0 || + wcscmp(szClass, L"Progman") == 0) { - // UPDATE: Seek also the owned windows of the hidden top-level window. - EnumChildWindowsZOrder(next, callback, lParam); + continue; } - if (!callback(next, lParam)) - break; + ExStyle = GetWindowLongPtrW(hwnd, GWL_EXSTYLE); + if (ExStyle & WS_EX_TOOLWINDOW) + continue; + + hwndOwner = GetWindow(hwnd, GW_OWNER); + if ((ExStyle & WS_EX_APPWINDOW) || !IsWindowVisible(hwndOwner)) + { + if (!callback(hwnd, lParam)) + break; - next = GetWindow(next, GW_HWNDNEXT); + continue; + } } } @@ -422,7 +425,7 @@ BOOL ProcessHotKey(VOID) if (!isOpen) { windowCount=0; - EnumChildWindowsZOrder(NULL, EnumerateCallback, 0); + EnumWindowsZOrder(EnumerateCallback, 0); if (windowCount == 0) return FALSE; @@ -567,7 +570,7 @@ LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam ) Esc = TRUE; windowCount = 0; - EnumChildWindowsZOrder(NULL, EnumerateCallback, 0); + EnumWindowsZOrder(EnumerateCallback, 0); if (windowCount < 2) return 0;