https://git.reactos.org/?p=reactos.git;a=commitdiff;h=687eba26f32fe80e5419c…
commit 687eba26f32fe80e5419cbc7dee4d484bcc70c40
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Wed Jan 23 22:44:11 2019 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Wed Jan 23 22:44:11 2019 +0900
[USER32] Fix AppSwitcher (Alt+Tab) (#1296)
CORE-15653
---
win32ss/user/user32/controls/appswitch.c | 51 +++++++++++++++++---------------
1 file changed, 27 insertions(+), 24 deletions(-)
diff --git a/win32ss/user/user32/controls/appswitch.c
b/win32ss/user/user32/controls/appswitch.c
index 0a5c4f996a..7f97d0dfac 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;