https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f7fc10c17c7172aee040c…
commit f7fc10c17c7172aee040c1cb2f631d6824917d80
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sun Jun 2 19:17:50 2019 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sun Jun 2 19:17:50 2019 +0900
[WIN32SS][USER32] Fix Task Switcher more (#1602)
This PR will fix task switcher (Alt+Tab) as Win2k3. It became more reliable.
CORE-15653
c.f. Raymond Chen's article:
http://blogs.msdn.com/b/oldnewthing/archive/2007/10/08/5351207.aspx
---
win32ss/user/user32/controls/appswitch.c | 74 +++++++++++++++++++++++++++-----
1 file changed, 64 insertions(+), 10 deletions(-)
diff --git a/win32ss/user/user32/controls/appswitch.c
b/win32ss/user/user32/controls/appswitch.c
index ee9c10677cc..ac9c5d0ee24 100644
--- a/win32ss/user/user32/controls/appswitch.c
+++ b/win32ss/user/user32/controls/appswitch.c
@@ -209,15 +209,52 @@ BOOL CALLBACK EnumerateCallback(HWND window, LPARAM lParam)
return TRUE;
}
-static BOOL CALLBACK
-EnumWindowsProc(HWND hwnd, LPARAM lParam)
+static HWND GetNiceRootOwner(HWND hwnd)
{
HWND hwndOwner;
- WCHAR szClass[64];
+ DWORD ExStyle, OwnerExStyle;
+
+ for (;;)
+ {
+ // A window with WS_EX_APPWINDOW is treated as if it has no owner
+ ExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
+ if (ExStyle & WS_EX_APPWINDOW)
+ break;
+
+ // Is the owner visible?
+ // An window with WS_EX_TOOLWINDOW is treated as if it weren't visible
+ hwndOwner = GetWindow(hwnd, GW_OWNER);
+ OwnerExStyle = GetWindowLong(hwndOwner, GWL_EXSTYLE);
+ if (!IsWindowVisible(hwndOwner) || (OwnerExStyle & WS_EX_TOOLWINDOW))
+ break;
+
+ hwnd = hwndOwner;
+ }
+
+ return hwnd;
+}
+
+// c.f.
http://blogs.msdn.com/b/oldnewthing/archive/2007/10/08/5351207.aspx
+BOOL IsAltTabWindow(HWND hwnd)
+{
DWORD ExStyle;
+ RECT rc;
+ HWND hwndTry, hwndWalk;
+ WCHAR szClass[64];
+ // must be visible
if (!IsWindowVisible(hwnd))
- return TRUE;
+ return FALSE;
+
+ // must not be WS_EX_TOOLWINDOW
+ ExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
+ if (ExStyle & WS_EX_TOOLWINDOW)
+ return FALSE;
+
+ // must be not empty rect
+ GetWindowRect(hwnd, &rc);
+ if (IsRectEmpty(&rc))
+ return FALSE;
// check special windows
if (!GetClassNameW(hwnd, szClass, _countof(szClass)) ||
@@ -227,17 +264,34 @@ EnumWindowsProc(HWND hwnd, LPARAM lParam)
return TRUE;
}
- ExStyle = GetWindowLongPtrW(hwnd, GWL_EXSTYLE);
- if (ExStyle & WS_EX_TOOLWINDOW)
- return TRUE;
+ // get 'nice' root owner
+ hwndWalk = GetNiceRootOwner(hwnd);
+
+ // walk back from hwndWalk toward hwnd
+ for (;;)
+ {
+ hwndTry = GetLastActivePopup(hwndWalk);
+ if (hwndTry == hwndWalk)
+ break;
+
+ ExStyle = GetWindowLong(hwndTry, GWL_EXSTYLE);
+ if (IsWindowVisible(hwndTry) && !(ExStyle & WS_EX_TOOLWINDOW))
+ break;
+
+ hwndWalk = hwndTry;
+ }
+
+ return hwnd == hwndTry; // Reached?
+}
- hwndOwner = GetWindow(hwnd, GW_OWNER);
- if (!IsWindowVisible(hwndOwner) || (ExStyle & WS_EX_APPWINDOW))
+static BOOL CALLBACK
+EnumWindowsProc(HWND hwnd, LPARAM lParam)
+{
+ if (IsAltTabWindow(hwnd))
{
if (!EnumerateCallback(hwnd, lParam))
return FALSE;
}
-
return TRUE;
}