user32: Make all the recently added ShowWindow tests pass in Wine, take 2

Dmitry Timoshkov dmitry at codeweavers.com
Wed May 17 02:35:26 CDT 2006


Hello,

this version of the patch tries harder to not break existing tests.
-- 

This patch makes all the recently added ShowWindow tests pass in Wine,
and is aimed to fix the bug #4960.

Changelog:
    Make all the recently added ShowWindow tests pass in Wine.

diff -up cvs/hq/wine/dlls/user/tests/msg.c wine/dlls/user/tests/msg.c
--- cvs/hq/wine/dlls/user/tests/msg.c	2006-05-17 11:16:59.000000000 +0900
+++ wine/dlls/user/tests/msg.c	2006-05-17 15:43:18.000000000 +0900
@@ -643,6 +643,9 @@ static const struct message WmShowChildI
     { WM_MOVE, sent|defwinproc },
     { WM_SIZE, sent|defwinproc },
     { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
+    /* FIXME: Wine creates an icon/title window while Windows doesn't */
+    { WM_PARENTNOTIFY, sent|parent|wparam|optional, WM_CREATE },
+    { WM_GETTEXT, sent|optional },
     { 0 }
 };
 /* repeated ShowWindow(SW_MINIMIZE) for child with invisible parent */
@@ -677,6 +680,9 @@ static const struct message WmShowChildI
     { WM_MOVE, sent|defwinproc },
     { WM_SIZE, sent|defwinproc },
     { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
+    /* FIXME: Wine creates an icon/title window while Windows doesn't */
+    { WM_PARENTNOTIFY, sent|parent|wparam|optional, WM_CREATE },
+    { WM_GETTEXT, sent|optional },
     { 0 }
 };
 /* repeated ShowWindow(SW_SHOWMINIMIZED) for child with invisible parent */
@@ -693,6 +699,9 @@ static const struct message WmShowChildI
     { WM_MOVE, sent|defwinproc },
     { WM_SIZE, sent|defwinproc },
     { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
+    /* FIXME: Wine creates an icon/title window while Windows doesn't */
+    { WM_PARENTNOTIFY, sent|parent|wparam|optional, WM_CREATE },
+    { WM_GETTEXT, sent|optional },
     { 0 }
 };
 /* repeated ShowWindow(SW_SHOWMINNOACTIVE) for child with invisible parent */
@@ -3281,6 +3290,7 @@ static void test_showwindow(void)
     hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_MAXIMIZE,
                            100, 100, 200, 200, 0, 0, 0, NULL);
     ok (hwnd != 0, "Failed to create popup window\n");
+    ok(IsZoomed(hwnd), "window should be maximized\n");
     ok_sequence(WmCreateInvisibleMaxPopupSeq, "CreateWindow(WS_MAXIMIZED):popup", FALSE);
     trace("done\n");
 
@@ -3291,10 +3301,12 @@ static void test_showwindow(void)
         rc.left, rc.top, rc.right, rc.bottom);
     /* Reset window's size & position */
     SetWindowPos(hwnd, 0, 10, 10, 200, 200, SWP_NOZORDER | SWP_NOACTIVATE);
+    ok(IsZoomed(hwnd), "window should be maximized\n");
     flush_sequence();
 
-    trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible popup window\n");
+    trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible maximized popup window\n");
     ShowWindow(hwnd, SW_SHOWMAXIMIZED);
+    ok(IsZoomed(hwnd), "window should be maximized\n");
     ok_sequence(WmShowMaxPopupResizedSeq, "ShowWindow(SW_SHOWMAXIMIZED):popup", FALSE);
     trace("done\n");
 
@@ -3314,11 +3326,13 @@ static void test_showwindow(void)
     hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_MAXIMIZE,
                            100, 100, 200, 200, 0, 0, 0, NULL);
     ok (hwnd != 0, "Failed to create popup window\n");
+    ok(IsZoomed(hwnd), "window should be maximized\n");
     ok_sequence(WmCreateInvisibleMaxPopupSeq, "CreateWindow(WS_MAXIMIZED):popup", FALSE);
     trace("done\n");
 
-    trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible popup window\n");
+    trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible maximized popup window\n");
     ShowWindow(hwnd, SW_SHOWMAXIMIZED);
+    ok(IsZoomed(hwnd), "window should be maximized\n");
     ok_sequence(WmShowMaxPopupSeq, "ShowWindow(SW_SHOWMAXIMIZED):popup", FALSE);
     trace("done\n");
     DestroyWindow(hwnd);
@@ -3331,6 +3345,7 @@ static void test_showwindow(void)
     hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_MAXIMIZE | WS_VISIBLE,
                            100, 100, 200, 200, 0, 0, 0, NULL);
     ok (hwnd != 0, "Failed to create popup window\n");
+    ok(IsZoomed(hwnd), "window should be maximized\n");
     ok_sequence(WmCreateMaxPopupSeq, "CreateWindow(WS_MAXIMIZED):popup", FALSE);
     trace("done\n");
     DestroyWindow(hwnd);
@@ -3344,11 +3359,13 @@ static void test_showwindow(void)
     hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_VISIBLE,
                            100, 100, 200, 200, 0, 0, 0, NULL);
     ok (hwnd != 0, "Failed to create popup window\n");
+    ok(!IsZoomed(hwnd), "window should NOT be maximized\n");
     ok_sequence(WmCreatePopupSeq, "CreateWindow(WS_VISIBLE):popup", TRUE);
     trace("done\n");
 
     trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for visible popup window\n");
     ShowWindow(hwnd, SW_SHOWMAXIMIZED);
+    ok(IsZoomed(hwnd), "window should be maximized\n");
     ok_sequence(WmShowVisMaxPopupSeq, "ShowWindow(SW_SHOWMAXIMIZED):popup", TRUE);
     trace("done\n");
     DestroyWindow(hwnd);
@@ -3740,14 +3757,14 @@ static void invisible_parent_tests(void)
     ok_sequence(WmCreateChildSeq, "CreateWindow:child", FALSE);
 
     ShowWindow( hchild, SW_MINIMIZE );
-    ok_sequence(WmShowChildInvisibleParentSeq_1, "ShowWindow(SW_MINIMIZE) child with invisible parent", TRUE);
+    ok_sequence(WmShowChildInvisibleParentSeq_1, "ShowWindow(SW_MINIMIZE) child with invisible parent", FALSE);
     ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
     ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
 
     /* repeat */
     flush_events();
     ShowWindow( hchild, SW_MINIMIZE );
-    ok_sequence(WmShowChildInvisibleParentSeq_1r, "ShowWindow(SW_MINIMIZE) child with invisible parent", TRUE);
+    ok_sequence(WmShowChildInvisibleParentSeq_1r, "ShowWindow(SW_MINIMIZE) child with invisible parent", FALSE);
 
     DestroyWindow(hchild);
     hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD,
@@ -3755,14 +3772,14 @@ static void invisible_parent_tests(void)
     flush_sequence();
 
     ShowWindow( hchild, SW_MAXIMIZE );
-    ok_sequence(WmShowChildInvisibleParentSeq_2, "ShowWindow(SW_MAXIMIZE) child with invisible parent", TRUE);
+    ok_sequence(WmShowChildInvisibleParentSeq_2, "ShowWindow(SW_MAXIMIZE) child with invisible parent", FALSE);
     ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
     ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
 
     /* repeat */
     flush_events();
     ShowWindow( hchild, SW_MAXIMIZE );
-    ok_sequence(WmShowChildInvisibleParentSeq_2r, "ShowWindow(SW_MAXIMIZE) child with invisible parent", TRUE);
+    ok_sequence(WmShowChildInvisibleParentSeq_2r, "ShowWindow(SW_MAXIMIZE) child with invisible parent", FALSE);
 
     DestroyWindow(hchild);
     hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD,
@@ -3770,14 +3787,14 @@ static void invisible_parent_tests(void)
     flush_sequence();
 
     ShowWindow( hchild, SW_SHOWMINIMIZED );
-    ok_sequence(WmShowChildInvisibleParentSeq_3, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", TRUE);
+    ok_sequence(WmShowChildInvisibleParentSeq_3, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", FALSE);
     ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
     ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
 
     /* repeat */
     flush_events();
     ShowWindow( hchild, SW_SHOWMINIMIZED );
-    ok_sequence(WmShowChildInvisibleParentSeq_3r, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", TRUE);
+    ok_sequence(WmShowChildInvisibleParentSeq_3r, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", FALSE);
 
     DestroyWindow(hchild);
     hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD,
@@ -3786,7 +3803,7 @@ static void invisible_parent_tests(void)
 
     /* same as ShowWindow( hchild, SW_MAXIMIZE ); */
     ShowWindow( hchild, SW_SHOWMAXIMIZED );
-    ok_sequence(WmShowChildInvisibleParentSeq_2, "ShowWindow(SW_SHOWMAXIMIZED) child with invisible parent", TRUE);
+    ok_sequence(WmShowChildInvisibleParentSeq_2, "ShowWindow(SW_SHOWMAXIMIZED) child with invisible parent", FALSE);
     ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
     ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
 
@@ -3796,14 +3813,14 @@ static void invisible_parent_tests(void)
     flush_sequence();
 
     ShowWindow( hchild, SW_SHOWMINNOACTIVE );
-    ok_sequence(WmShowChildInvisibleParentSeq_4, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", TRUE);
+    ok_sequence(WmShowChildInvisibleParentSeq_4, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", FALSE);
     ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
     ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
 
     /* repeat */
     flush_events();
     ShowWindow( hchild, SW_SHOWMINNOACTIVE );
-    ok_sequence(WmShowChildInvisibleParentSeq_4r, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", TRUE);
+    ok_sequence(WmShowChildInvisibleParentSeq_4r, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", FALSE);
 
     DestroyWindow(hchild);
     hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD,
diff -up cvs/hq/wine/dlls/x11drv/winpos.c wine/dlls/x11drv/winpos.c
--- cvs/hq/wine/dlls/x11drv/winpos.c	2006-05-17 11:17:04.000000000 +0900
+++ wine/dlls/x11drv/winpos.c	2006-05-17 16:18:36.000000000 +0900
@@ -852,13 +852,23 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT
 
     if (IsIconic( hwnd ))
     {
-        if (cmd == SW_MINIMIZE) return SWP_NOSIZE | SWP_NOMOVE;
+        switch (cmd)
+        {
+        case SW_SHOWMINNOACTIVE:
+        case SW_SHOWMINIMIZED:
+        case SW_FORCEMINIMIZE:
+        case SW_MINIMIZE:
+            return SWP_NOSIZE | SWP_NOMOVE;
+        }
         if (!SendMessageW( hwnd, WM_QUERYOPEN, 0, 0 )) return SWP_NOSIZE | SWP_NOMOVE;
         swpFlags |= SWP_NOCOPYBITS;
     }
 
     switch( cmd )
     {
+    case SW_SHOWMINNOACTIVE:
+    case SW_SHOWMINIMIZED:
+    case SW_FORCEMINIMIZE:
     case SW_MINIMIZE:
         if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
         if( wndPtr->dwStyle & WS_MAXIMIZE) wndPtr->flags |= WIN_RESTORE_MAX;
@@ -877,6 +887,9 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT
         break;
 
     case SW_MAXIMIZE:
+        old_style = GetWindowLongW( hwnd, GWL_STYLE );
+        if ((old_style & WS_MAXIMIZE) && (old_style & WS_CHILD)) return SWP_NOSIZE | SWP_NOMOVE;
+
         WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL );
 
         old_style = WIN_SetStyle( hwnd, WS_MAXIMIZE, WS_MINIMIZE );
@@ -933,7 +946,7 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT c
     HWND parent;
     LONG style = GetWindowLongW( hwnd, GWL_STYLE );
     BOOL wasVisible = (style & WS_VISIBLE) != 0;
-    BOOL showFlag = TRUE;
+    BOOL showFlag = TRUE, state_change = FALSE;
     RECT newPos = {0, 0, 0, 0};
     UINT swp = 0;
 
@@ -949,23 +962,24 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT c
                 swp |= SWP_NOACTIVATE | SWP_NOZORDER;
 	    break;
 
+	case SW_MINIMIZE:
 	case SW_SHOWMINNOACTIVE:
             swp |= SWP_NOACTIVATE | SWP_NOZORDER;
             /* fall through */
 	case SW_SHOWMINIMIZED:
         case SW_FORCEMINIMIZE: /* FIXME: Does not work if thread is hung. */
-            swp |= SWP_SHOWWINDOW;
+            swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
             /* fall through */
-	case SW_MINIMIZE:
-            swp |= SWP_FRAMECHANGED;
-            if( !(style & WS_MINIMIZE) )
-		 swp |= WINPOS_MinMaximize( hwnd, SW_MINIMIZE, &newPos );
-            else swp |= SWP_NOSIZE | SWP_NOMOVE;
+            swp |= WINPOS_MinMaximize( hwnd, cmd, &newPos );
+            if (style & WS_MINIMIZE) return wasVisible;
+            state_change = TRUE;
 	    break;
 
 	case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
             swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
             swp |= WINPOS_MinMaximize( hwnd, SW_MAXIMIZE, &newPos );
+            if ((style & WS_MAXIMIZE) && (style & WS_CHILD)) return wasVisible;
+            state_change = TRUE;
             break;
 
 	case SW_SHOWNA:
@@ -979,6 +993,7 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT c
 
 	case SW_RESTORE:
 	    swp |= SWP_FRAMECHANGED;
+            state_change = TRUE;
             /* fall through */
 	case SW_SHOWNOACTIVATE:
             swp |= SWP_NOACTIVATE | SWP_NOZORDER;
@@ -993,14 +1008,14 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT c
 	    break;
     }
 
-    if ((showFlag != wasVisible || cmd == SW_SHOWNA) && cmd != SW_SHOWMAXIMIZED)
+    if ((showFlag != wasVisible || cmd == SW_SHOWNA) && !state_change)
     {
         SendMessageW( hwnd, WM_SHOWWINDOW, showFlag, 0 );
         if (!IsWindow( hwnd )) return wasVisible;
     }
 
     parent = GetAncestor( hwnd, GA_PARENT );
-    if (parent && !IsWindowVisible( parent ))
+    if (parent && !IsWindowVisible( parent ) && !state_change)
     {
         /* if parent is not visible simply toggle WS_VISIBLE and return */
         if (showFlag) WIN_SetStyle( hwnd, WS_VISIBLE, 0 );
@@ -1009,8 +1024,19 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT c
     else
     {
         /* ShowWindow won't activate a not being maximized child window */
-        if ((style & WS_CHILD) && cmd != SW_MAXIMIZE)
-            swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+        if (style & WS_CHILD)
+        {
+            if (!state_change)
+                swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+            else
+            {
+                /* it appears that Windows always adds an undocumented 0x8000
+                 * flag if the state of a window changes.
+                 * FIXME: real SWP_xxxx name?
+                 */
+                swp |= 0x8000;
+            }
+        }
 
         SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,
                       newPos.right, newPos.bottom, LOWORD(swp) );





More information about the wine-patches mailing list