[USER32] Fix AppSwitcher (Alt+Tab) (#1296)

CORE-15653
This commit is contained in:
Katayama Hirofumi MZ 2019-01-23 22:44:11 +09:00 committed by GitHub
parent f2e0de2f31
commit 687eba26f3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -165,22 +165,9 @@ void CompleteSwitch(BOOL doSwitch)
BOOL CALLBACK EnumerateCallback(HWND window, LPARAM lParam) BOOL CALLBACK EnumerateCallback(HWND window, LPARAM lParam)
{ {
HICON hIcon; HICON hIcon;
HWND hwndOwner;
UNREFERENCED_PARAMETER(lParam); 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 // First try to get the big icon assigned to the window
hIcon = (HICON)SendMessageW(window, WM_GETICON, ICON_BIG, 0); hIcon = (HICON)SendMessageW(window, WM_GETICON, ICON_BIG, 0);
if (!hIcon) if (!hIcon)
@ -221,21 +208,37 @@ BOOL CALLBACK EnumerateCallback(HWND window, LPARAM lParam)
// Function mostly compatible with the normal EnumChildWindows, // Function mostly compatible with the normal EnumChildWindows,
// except it lists in Z-Order and it doesn't ensure consistency // except it lists in Z-Order and it doesn't ensure consistency
// if a window is removed while enumerating // 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); HWND hwnd, hwndOwner;
while (next != NULL) 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. continue;
EnumChildWindowsZOrder(next, callback, lParam);
} }
if (!callback(next, lParam)) ExStyle = GetWindowLongPtrW(hwnd, GWL_EXSTYLE);
break; if (ExStyle & WS_EX_TOOLWINDOW)
continue;
next = GetWindow(next, GW_HWNDNEXT); hwndOwner = GetWindow(hwnd, GW_OWNER);
if ((ExStyle & WS_EX_APPWINDOW) || !IsWindowVisible(hwndOwner))
{
if (!callback(hwnd, lParam))
break;
continue;
}
} }
} }
@ -422,7 +425,7 @@ BOOL ProcessHotKey(VOID)
if (!isOpen) if (!isOpen)
{ {
windowCount=0; windowCount=0;
EnumChildWindowsZOrder(NULL, EnumerateCallback, 0); EnumWindowsZOrder(EnumerateCallback, 0);
if (windowCount == 0) if (windowCount == 0)
return FALSE; return FALSE;
@ -567,7 +570,7 @@ LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam )
Esc = TRUE; Esc = TRUE;
windowCount = 0; windowCount = 0;
EnumChildWindowsZOrder(NULL, EnumerateCallback, 0); EnumWindowsZOrder(EnumerateCallback, 0);
if (windowCount < 2) if (windowCount < 2)
return 0; return 0;