Dmitry Timoshkov : user: Add a test for ShowWindow(SW_MAXIMIZE) called on an invisible maximized MDI child, make it mostly pass under Wine .

Alexandre Julliard julliard at wine.codeweavers.com
Wed Oct 18 07:38:47 CDT 2006


Module: wine
Branch: master
Commit: dbd43c622f7bde8c44d5b082df247dbe6e3955d9
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=dbd43c622f7bde8c44d5b082df247dbe6e3955d9

Author: Dmitry Timoshkov <dmitry at codeweavers.com>
Date:   Mon Oct 16 23:23:34 2006 +0900

user: Add a test for ShowWindow(SW_MAXIMIZE) called on an invisible maximized MDI child, make it mostly pass under Wine.

---

 dlls/user/mdi.c           |    8 +++
 dlls/user/tests/msg.c     |  103 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/winex11.drv/winpos.c |    4 +-
 3 files changed, 110 insertions(+), 5 deletions(-)

diff --git a/dlls/user/mdi.c b/dlls/user/mdi.c
index bfeb2db..13da1ec 100644
--- a/dlls/user/mdi.c
+++ b/dlls/user/mdi.c
@@ -618,7 +618,13 @@ static LONG MDI_ChildActivate( HWND clie
     if( isActiveFrameWnd )
     {
         SendMessageW( child, WM_NCACTIVATE, TRUE, 0L);
-        SetFocus( client );
+        /* Let the client window manage focus for children, but if the focus
+         * is already on the client (for instance this is the 1st child) then
+         * SetFocus won't work. It appears that Windows sends WM_SETFOCUS
+         * manually in this case.
+         */
+        if (SetFocus(client) == client)
+            SendMessageW( client, WM_SETFOCUS, (WPARAM)client, 0 );
     }
 
     SendMessageW( child, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child );
diff --git a/dlls/user/tests/msg.c b/dlls/user/tests/msg.c
index 6714f54..027810f 100644
--- a/dlls/user/tests/msg.c
+++ b/dlls/user/tests/msg.c
@@ -1968,11 +1968,12 @@ static const struct message WmCreateMDIc
     /* Win9x: message sequence terminates here. */
 
     { WM_NCACTIVATE, sent|wparam|defwinproc, 1 },
+    { WM_SETFOCUS, sent|optional }, /* in MDI client */
     { HCBT_SETFOCUS, hook }, /* in MDI client */
     { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
     { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
-    { WM_SETFOCUS, sent }, /* in MDI client */
-    { HCBT_SETFOCUS, hook },
+    { WM_SETFOCUS, sent|optional }, /* in MDI client */
+    { HCBT_SETFOCUS, hook|optional },
     { WM_KILLFOCUS, sent }, /* in MDI client */
     { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
     { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
@@ -2014,6 +2015,41 @@ static const struct message WmCreateMDIc
 
     { 0 }
 };
+/* CreateWindow for the 1st MDI child window, initially invisible and maximized */
+static const struct message WmCreateMDIchildInvisibleMaxSeq4[] = {
+    { HCBT_CREATEWND, hook },
+    { WM_GETMINMAXINFO, sent },
+    { WM_NCCREATE, sent }, 
+    { WM_NCCALCSIZE, sent|wparam, 0 },
+    { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
+    { WM_CREATE, sent },
+    { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
+    { WM_SIZE, sent },
+    { WM_MOVE, sent },
+    { HCBT_MINMAX, hook|lparam, 0, SW_MAXIMIZE },
+    { WM_GETMINMAXINFO, sent },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|0x8000 },
+    { WM_GETMINMAXINFO, sent|defwinproc },
+    { WM_NCCALCSIZE, sent|wparam, 1 },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOREDRAW|SWP_NOCLIENTSIZE|0x8000 },
+    { WM_MOVE, sent|defwinproc },
+    { WM_SIZE, sent|defwinproc },
+     /* in MDI frame */
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER },
+    { WM_NCCALCSIZE, sent|wparam, 1 },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+    { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
+    { WM_NCCALCSIZE, sent|wparam, 1 }, /* MDI child */
+    { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
+    { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
+    /* Win2k sends wparam set to
+     * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
+     * while Win9x doesn't bother to set child window id according to
+     * CLIENTCREATESTRUCT.idFirstChild
+     */
+    { WM_PARENTNOTIFY, sent /*|wparam, WM_CREATE*/ }, /* in MDI client */
+    { 0 }
+};
 /* WM_SYSCOMMAND/SC_CLOSE for the 2nd MDI child window, initially visible and maximized */
 static const struct message WmDestroyMDIchildVisibleMaxSeq2[] = {
     { WM_SYSCOMMAND, sent|wparam, SC_CLOSE },
@@ -2289,6 +2325,33 @@ static const struct message WmMaximizeMD
     { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
     { 0 }
 };
+/* ShowWindow(SW_MAXIMIZE) for a not visible maximized MDI child window */
+static const struct message WmMaximizeMDIchildInvisibleSeq2[] = {
+    { HCBT_MINMAX, hook|lparam, 0, SW_MAXIMIZE },
+    { WM_GETMINMAXINFO, sent },
+    { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED },
+    { WM_GETMINMAXINFO, sent|defwinproc },
+    { WM_NCCALCSIZE, sent|wparam, 1 },
+    { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
+    { WM_CHILDACTIVATE, sent|wparam|lparam, 0, 0 },
+
+    { WM_WINDOWPOSCHANGING, sent|wparam|defwinproc, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE },
+    { WM_NCACTIVATE, sent|wparam|defwinproc, 1 },
+    { HCBT_SETFOCUS, hook },
+    { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
+    { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+    { WM_SETFOCUS, sent }, /* in MDI client */
+    { HCBT_SETFOCUS, hook },
+    { WM_KILLFOCUS, sent }, /* in MDI client */
+    { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
+    { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
+    { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+    { WM_SETFOCUS, sent|defwinproc },
+    { WM_MDIACTIVATE, sent|defwinproc },
+    { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+    { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
+    { 0 }
+};
 /* WM_MDIMAXIMIZE for an MDI child window with invisible parent */
 static const struct message WmMaximizeMDIchildInvisibleParentSeq[] = {
     { WM_MDIMAXIMIZE, sent }, /* in MDI client */
@@ -2906,6 +2969,42 @@ static void test_mdi_messages(void)
        !active_child, /* win9x */
        "wrong active MDI child %p\n", active_child);
     flush_sequence();
+
+    trace("creating maximized invisible MDI child window\n");
+    mdi_child2 = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child",
+                                WS_CHILD | WS_MAXIMIZE | WS_CAPTION | WS_THICKFRAME,
+                                0, 0, CW_USEDEFAULT, CW_USEDEFAULT,
+                                mdi_client, 0, GetModuleHandleA(0), NULL);
+    assert(mdi_child2);
+    ok_sequence(WmCreateMDIchildInvisibleMaxSeq4, "Create maximized invisible MDI child window", TRUE);
+    ok(IsZoomed(mdi_child2), "MDI child should be maximized\n");
+    ok(!(GetWindowLongA(mdi_child2, GWL_STYLE) & WS_VISIBLE), "MDI child should be not visible\n");
+    ok(!IsWindowVisible(mdi_child2), "MDI child should be not visible\n");
+
+    /* Win2k: MDI client still returns a just destroyed child as active
+     * Win9x: MDI client returns 0
+     */
+    active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
+    ok(active_child == mdi_child || /* win2k */
+       !active_child, /* win9x */
+       "wrong active MDI child %p\n", active_child);
+    flush_sequence();
+
+    trace("call ShowWindow(mdi_child, SW_MAXIMIZE)\n");
+    ShowWindow(mdi_child2, SW_MAXIMIZE);
+    ok_sequence(WmMaximizeMDIchildInvisibleSeq2, "ShowWindow(SW_MAXIMIZE):invisible maximized MDI child", TRUE);
+    ok(IsZoomed(mdi_child2), "MDI child should be maximized\n");
+    ok(GetWindowLongA(mdi_child2, GWL_STYLE) & WS_VISIBLE, "MDI child should be visible\n");
+    ok(IsWindowVisible(mdi_child2), "MDI child should be visible\n");
+
+    active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
+    ok(active_child == mdi_child2, "wrong active MDI child %p\n", active_child);
+    ok(zoomed, "wrong zoomed state %d\n", zoomed);
+    flush_sequence();
+
+    SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child2, 0);
+    flush_sequence();
+
     /* end of test for maximized MDI children */
 
     mdi_cs.szClass = "MDI_child_Class";
diff --git a/dlls/winex11.drv/winpos.c b/dlls/winex11.drv/winpos.c
index 6f9b8f6..2f4ad51 100644
--- a/dlls/winex11.drv/winpos.c
+++ b/dlls/winex11.drv/winpos.c
@@ -938,7 +938,7 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT
 
     case SW_MAXIMIZE:
         old_style = GetWindowLongW( hwnd, GWL_STYLE );
-        if ((old_style & WS_MAXIMIZE) && (old_style & WS_CHILD)) return SWP_NOSIZE | SWP_NOMOVE;
+        if ((old_style & WS_MAXIMIZE) && (old_style & WS_VISIBLE)) return SWP_NOSIZE | SWP_NOMOVE;
 
         WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL );
 
@@ -1029,7 +1029,7 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT c
 	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;
+            if ((style & WS_MAXIMIZE) && wasVisible) return wasVisible;
             state_change = TRUE;
             break;
 




More information about the wine-cvs mailing list