user: test and fix SwitchToThisWindow [2nd try]

Jan Zerebecki jan.wine at zerebecki.de
Thu Sep 7 08:56:36 CDT 2006


Bugreport about this patch: http://bugs.winehq.org/show_bug.cgi?id=5725
I compiled-tested this and successfully ran the test on wine and
(thx kblin) on native, because the author said that he is not
able to compile wine.

If this patch is rejected from inclusion, please tell me why, as
I would have to ask anyway.

From: Neil Rashbrook <neil at parkwaycc.co.uk>
Changelog:
user: test and fix SwitchToThisWindow

---

 dlls/user/tests/Makefile.in |    1 
 dlls/user/tests/win_sttw.c  |  127 +++++++++++++++++++++++++++++++++++++++++++
 dlls/user/winpos.c          |   15 +++++
 3 files changed, 142 insertions(+), 1 deletions(-)

diff --git a/dlls/user/tests/Makefile.in b/dlls/user/tests/Makefile.in
index 7a78a5b..4e10563 100644
--- a/dlls/user/tests/Makefile.in
+++ b/dlls/user/tests/Makefile.in
@@ -23,6 +23,7 @@ CTESTS = \
 	sysparams.c \
 	text.c \
 	win.c \
+	win_sttw.c \
 	winstation.c \
 	wsprintf.c
 
diff --git a/dlls/user/tests/win_sttw.c b/dlls/user/tests/win_sttw.c
new file mode 100644
index 0000000..ddc2d3e
--- /dev/null
+++ b/dlls/user/tests/win_sttw.c
@@ -0,0 +1,127 @@
+/*
+ * Unit tests for SwitchToThisWindow
+ *
+ * Copyright 2006 Neil Rashbrook
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "wine/test.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+
+DWORD exstyle[] = { WS_EX_OVERLAPPEDWINDOW, WS_EX_OVERLAPPEDWINDOW
+                    | WS_EX_TOPMOST };
+
+typedef struct sttw_test {
+    int show; /* SW_ flag for ShowWindow */
+    int topmost; /* whether to make the active window topmost */
+    int which; /* which window to switch to */
+    int flag; /* flag parameter */
+    int iconic; /* whether the window should be iconic */
+    int zoomed; /* whether the window should be zoomed */
+    int order; /* if not topmost, which window should be in front */
+} sttw_test;
+
+sttw_test sttw_tests[] = {
+    { SW_SHOWNORMAL, 0, 0, 0, 0, 0, 0 },
+    { SW_SHOWNORMAL, 0, 0, 1, 0, 0, 0 },
+    { SW_SHOWNORMAL, 0, 1, 0, 0, 0, 0 },
+    { SW_SHOWNORMAL, 0, 1, 1, 0, 0, 1 },
+    { SW_SHOWNORMAL, 1, 0, 0, 0, 0 },
+    { SW_SHOWNORMAL, 1, 0, 1, 0, 0 },
+    { SW_SHOWNORMAL, 1, 1, 0, 0, 0 },
+    { SW_SHOWNORMAL, 1, 1, 1, 0, 0 },
+    { SW_SHOWMINIMIZED, 0, 0, 0, 1, 0, 0 },
+    { SW_SHOWMINIMIZED, 0, 0, 1, 0, 0, 0 },
+    { SW_SHOWMINIMIZED, 0, 1, 0, 1, 0, 0 },
+    { SW_SHOWMINIMIZED, 0, 1, 1, 0, 0, 1 },
+    { SW_SHOWMINIMIZED, 1, 0, 0, 1, 0 },
+    { SW_SHOWMINIMIZED, 1, 0, 1, 0, 0 },
+    { SW_SHOWMINIMIZED, 1, 1, 0, 1, 0 },
+    { SW_SHOWMINIMIZED, 1, 1, 1, 0, 0 },
+    { SW_SHOWMAXIMIZED, 0, 0, 0, 0, 1, 0 },
+    { SW_SHOWMAXIMIZED, 0, 0, 1, 0, 1, 0 },
+    { SW_SHOWMAXIMIZED, 0, 1, 0, 0, 1, 0 },
+    { SW_SHOWMAXIMIZED, 0, 1, 1, 0, 1, 1 },
+    { SW_SHOWMAXIMIZED, 1, 0, 0, 0, 1 },
+    { SW_SHOWMAXIMIZED, 1, 0, 1, 0, 1 },
+    { SW_SHOWMAXIMIZED, 1, 1, 0, 0, 1 },
+    { SW_SHOWMAXIMIZED, 1, 1, 1, 0, 1 }
+};
+
+START_TEST(win_sttw)
+{
+    MSG msg;
+    int i;
+    HWND hwnd, hwndfront, hwndback, hwnds[2];
+    for (i = 0; i < sizeof(sttw_tests) / sizeof(sttw_test); ++i)
+    {
+        hwnds[0] = CreateWindow( "static", "", WS_OVERLAPPEDWINDOW,
+                                 CW_USEDEFAULT, CW_USEDEFAULT,
+                                 CW_USEDEFAULT, CW_USEDEFAULT,
+                                 NULL, NULL, NULL, NULL );
+        ShowWindow( hwnds[0], sttw_tests[i].show );
+        hwnds[1] = CreateWindowEx( exstyle[sttw_tests[i].topmost],
+                                   "static", "", WS_OVERLAPPEDWINDOW,
+                                   CW_USEDEFAULT, CW_USEDEFAULT,
+                                   CW_USEDEFAULT, CW_USEDEFAULT,
+                                   NULL, NULL, NULL, NULL );
+        ShowWindow( hwnds[1], sttw_tests[i].show );
+        SetActiveWindow( hwnds[1] );
+        SetForegroundWindow( hwnds[1] );
+        hwnd = hwnds[sttw_tests[i].which];
+        SwitchToThisWindow( hwnd, sttw_tests[i].flag );
+        /* On Windows, restoring a window is asynchronous. Give it 100ms */
+        while (PeekMessage( &msg, 0, 0, 0, TRUE ))
+            DispatchMessage( &msg );
+        Sleep(100);
+        while (PeekMessage( &msg, 0, 0, 0, TRUE ))
+            DispatchMessage( &msg );
+        ok( GetActiveWindow() == hwnd,
+            "[%d] switched window did not become active\n", i);
+        ok( GetForegroundWindow() == hwnd,
+            "[%d] switched window not in the foreground\n", i);
+        if (sttw_tests[i].iconic)
+            ok( IsIconic(hwnd),
+                "[%d] switched window unexpectedly iconic\n", i);
+        else
+            ok( !IsIconic(hwnd),
+                "[%d] switched window unexpectedly non-iconic\n", i);
+        if (sttw_tests[i].zoomed)
+            ok( IsZoomed(hwnd),
+                "[%d] switched window unexpectedly zoomed\n", i);
+        else
+            ok( !IsZoomed(hwnd),
+                "[%d] switched window unexpectedly non-zoomed\n", i);
+        if (sttw_tests[i].topmost)
+            ok( GetWindowLong( hwnds[1], GWL_EXSTYLE ) & WS_EX_TOPMOST,
+                "[%d] topmost window unexpectedly lost topmost\n", i);
+        else
+        {
+            hwndfront = hwnds[sttw_tests[i].order];
+            hwndback = hwnds[1 - sttw_tests[i].order];
+            while (hwndfront && hwndfront != hwndback)
+                hwndfront = GetWindow( hwndfront, GW_HWNDNEXT );
+            if(2==i||18==i) todo_wine ok( hwndfront != NULL,
+                "[%d] window relative z-order incorrect\n", i);
+            else ok( hwndfront != NULL,
+                "[%d] window relative z-order incorrect\n", i);
+        }
+    }
+}
diff --git a/dlls/user/winpos.c b/dlls/user/winpos.c
index 6bc9056..e78f484 100644
--- a/dlls/user/winpos.c
+++ b/dlls/user/winpos.c
@@ -152,7 +152,20 @@ UINT WINAPI ArrangeIconicWindows( HWND p
  */
 void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore )
 {
-    ShowWindow( hwnd, restore ? SW_RESTORE : SW_SHOWMINIMIZED );
+    HWND hwndOld = GetForegroundWindow();
+    SetActiveWindow( hwnd );
+    SetForegroundWindow( hwnd );
+    if ( restore )
+    {
+        if ( IsIconic( hwnd ) )
+            ShowWindow( hwnd, SW_RESTORE );
+    }
+    else
+    {
+        if ( !( GetWindowLongW( hwndOld, GWL_EXSTYLE ) & WS_EX_TOPMOST ) )
+            SetWindowPos( hwndOld, HWND_BOTTOM, 0, 0, 0, 0,
+                SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
+    }
 }
 
 



More information about the wine-patches mailing list