https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f7fc10c17c7172aee040c1...
commit f7fc10c17c7172aee040c1cb2f631d6824917d80 Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Sun Jun 2 19:17:50 2019 +0900 Commit: GitHub noreply@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; }