https://git.reactos.org/?p=reactos.git;a=commitdiff;h=687eba26f32fe80e5419cbc7dee4d484bcc70c40

commit 687eba26f32fe80e5419cbc7dee4d484bcc70c40
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Wed Jan 23 22:44:11 2019 +0900
Commit:     GitHub <[email protected]>
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;

Reply via email to