mdi.c/MDI_ChildActivate query

Dmitry Timoshkov dmitry at baikal.ru
Mon Dec 6 03:39:03 CST 2004


"Jeremy White" <jwhite at codeweavers.com> wrote:

> When trying to run 'Swiss Perfect' (www.swissperfect.com,
> free download available), the app crashes and burns while
> processing a WM_MDIACTIVATE message when the prevWnd is 0.

This is due to a long standing hack in X11DRV_ShowWindow which
forces MDI child activation.

Attached patch adds a couple of new MDI message tests using existing
message sequences for ordinary child windows and confirms that
ShowWindow does the same job for MDI children in respect to activation.

This fixes a crash in Swiss Perfect.

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    ShowWindow activates only a being maximized child window,
    add a couple of message tests for MDI child activation.

-- 
Dmitry.
-------------- next part --------------
diff -up cvs/hq/wine/dlls/user/tests/msg.c wine/dlls/user/tests/msg.c
--- cvs/hq/wine/dlls/user/tests/msg.c	2004-12-02 14:04:48.000000000 +0800
+++ wine/dlls/user/tests/msg.c	2004-12-06 17:01:34.000000000 +0800
@@ -1778,6 +1778,47 @@ static void test_mdi_messages(void)
     SetFocus(0);
     flush_sequence();
 
+    trace("creating invisible MDI child window\n");
+    mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child",
+                                WS_CHILD,
+                                0, 0, CW_USEDEFAULT, CW_USEDEFAULT,
+                                mdi_client, 0, GetModuleHandleA(0), NULL);
+    assert(mdi_child);
+
+    flush_sequence();
+    ShowWindow(mdi_child, SW_SHOWNORMAL);
+    ok_sequence(WmShowChildSeq, "ShowWindow(SW_SHOWNORMAL) MDI child window", FALSE);
+
+    ok(GetWindowLongA(mdi_child, GWL_STYLE) & WS_VISIBLE, "MDI child should be visible\n");
+    ok(IsWindowVisible(mdi_child), "MDI child should be visible\n");
+
+    ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
+    ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
+
+    active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
+    ok(!active_child, "wrong active MDI child %p\n", active_child);
+    ok(!zoomed, "wrong zoomed state %d\n", zoomed);
+
+    ShowWindow(mdi_child, SW_HIDE);
+    ok_sequence(WmHideChildSeq, "ShowWindow(SW_HIDE) MDI child window", FALSE);
+    flush_sequence();
+
+    ShowWindow(mdi_child, SW_SHOW);
+    ok_sequence(WmShowChildSeq, "ShowWindow(SW_SHOW) MDI child window", FALSE);
+
+    ok(GetWindowLongA(mdi_child, GWL_STYLE) & WS_VISIBLE, "MDI child should be visible\n");
+    ok(IsWindowVisible(mdi_child), "MDI child should be visible\n");
+
+    ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
+    ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
+
+    active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
+    ok(!active_child, "wrong active MDI child %p\n", active_child);
+    ok(!zoomed, "wrong zoomed state %d\n", zoomed);
+
+    DestroyWindow(mdi_child);
+    flush_sequence();
+
     trace("creating visible MDI child window\n");
     mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child",
                                 WS_CHILD | WS_VISIBLE,
diff -up cvs/hq/wine/dlls/x11drv/winpos.c wine/dlls/x11drv/winpos.c
--- cvs/hq/wine/dlls/x11drv/winpos.c	2004-09-20 14:26:52.000000000 +0900
+++ wine/dlls/x11drv/winpos.c	2004-12-06 17:28:13.000000000 +0800
@@ -1288,13 +1288,15 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT c
 	    swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
 	    break;
 
+	case SW_RESTORE:
+	    swp |= SWP_FRAMECHANGED;
+            /* fall through */
 	case SW_SHOWNOACTIVATE:
             swp |= SWP_NOACTIVATE | SWP_NOZORDER;
             /* fall through */
 	case SW_SHOWNORMAL:  /* same as SW_NORMAL: */
 	case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
-	case SW_RESTORE:
-	    swp |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
+	    swp |= SWP_SHOWWINDOW;
 
             if( wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE) )
 		 swp |= WINPOS_MinMaximize( hwnd, SW_RESTORE, &newPos );
@@ -1309,9 +1311,8 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT c
         if (!IsWindow( hwnd )) goto END;
     }
 
-    /* We can't activate a child window */
-    if ((wndPtr->dwStyle & WS_CHILD) &&
-        !(wndPtr->dwExStyle & WS_EX_MDICHILD))
+    /* ShowWindow won't activate a not being maximized child window */
+    if ((wndPtr->dwStyle & WS_CHILD) && cmd != SW_MAXIMIZE)
         swp |= SWP_NOACTIVATE | SWP_NOZORDER;
 
     SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,


More information about the wine-patches mailing list