If an MDI child becomes active restore previously maximized MDI child. Take 3.

Dmitry Timoshkov dmitry at baikal.ru
Tue Mar 22 08:53:35 CST 2005


Hello,

Alexandre, please use this version of the patch instead.

I was so happy to see that my own test and the app I'm working on no more
crash that I forgot to actually run 'make test' and see the result. But now
after another tiny tweak one more MDI test passes!

-- 
I believe that this is a more correct solution for the problem described
below. At least my test cases and a misbehaving app are now happy.

The app I'm working on creates a maximized MDI child. Then creates another
not yet visible MDI child, and does ShowWindow(SW_SHOW) on it. The state of
the 1st MDI child remains maximized, but the 2nd MDI child becomes an active
one. If I click on the 1st MDI child the app simply crashes.

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    If an MDI child becomes active restore previously maximized MDI child.

diff -up cvs/hq/wine/dlls/user/tests/msg.c wine/dlls/user/tests/msg.c
--- cvs/hq/wine/dlls/user/tests/msg.c	2005-03-16 16:26:50.000000000 +0800
+++ wine/dlls/user/tests/msg.c	2005-03-22 22:39:01.000000000 +0800
@@ -2259,7 +2259,7 @@ static void test_mdi_messages(void)
                                 0, 0, CW_USEDEFAULT, CW_USEDEFAULT,
                                 mdi_client, 0, GetModuleHandleA(0), NULL);
     assert(mdi_child);
-    ok_sequence(WmCreateMDIchildVisibleSeq, "Create visible MDI child window", TRUE);
+    ok_sequence(WmCreateMDIchildVisibleSeq, "Create visible 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");
diff -up cvs/hq/wine/windows/mdi.c wine/windows/mdi.c
--- cvs/hq/wine/windows/mdi.c	2005-03-05 23:26:30.000000000 +0800
+++ wine/windows/mdi.c	2005-03-22 22:42:42.000000000 +0800
@@ -482,7 +482,7 @@ static void MDI_ChildGetMinMaxInfo( HWND
  * Note: SetWindowPos sends WM_CHILDACTIVATE to the child window that is
  *       being activated
  */
-static void MDI_SwitchActiveChild( MDICLIENTINFO *ci, HWND hwndTo )
+static void MDI_SwitchActiveChild( MDICLIENTINFO *ci, HWND hwndTo, BOOL activate )
 {
     HWND hwndPrev;
 
@@ -507,7 +507,7 @@ static void MDI_SwitchActiveChild( MDICL
             ShowWindow( hwndTo, SW_MAXIMIZE );
         }
         /* activate new MDI child */
-        SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
+        SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | (activate ? 0 : SWP_NOACTIVATE) );
     }
 }
 
@@ -526,7 +526,7 @@ static LRESULT MDIDestroyChild( HWND cli
     {
         HWND next = MDI_GetWindow(ci, child, TRUE, 0);
         if (next)
-            MDI_SwitchActiveChild(ci, next);
+            MDI_SwitchActiveChild(ci, next, TRUE);
         else
         {
             ShowWindow(child, SW_HIDE);
@@ -597,6 +597,7 @@ static LONG MDI_ChildActivate( HWND clie
         SendMessageW( prevActiveWnd, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child);
     }
 
+    MDI_SwitchActiveChild( clientInfo, child, FALSE );
     clientInfo->hwndActiveChild = child;
 
     MDI_RefreshMenu(clientInfo);
@@ -604,7 +605,7 @@ static LONG MDI_ChildActivate( HWND clie
     if( isActiveFrameWnd )
     {
         SendMessageW( child, WM_NCACTIVATE, TRUE, 0L);
-        SetFocus(child);
+        SetFocus( client );
     }
 
     SendMessageW( child, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child );
@@ -1061,7 +1062,7 @@ static LRESULT MDIClientWndProc_common( 
 
       case WM_MDIACTIVATE:
       {
-        MDI_SwitchActiveChild( ci, (HWND)wParam );
+        MDI_SwitchActiveChild( ci, (HWND)wParam, TRUE );
         return 0;
       }
 
@@ -1122,7 +1123,7 @@ static LRESULT MDIClientWndProc_common( 
       case WM_MDINEXT: /* lParam != 0 means previous window */
       {
         HWND next = MDI_GetWindow( ci, WIN_GetFullHandle( (HWND)wParam ), !lParam, 0 );
-        MDI_SwitchActiveChild( ci, next );
+        MDI_SwitchActiveChild( ci, next, TRUE );
 	break;
       }
 
@@ -1200,7 +1201,7 @@ static LRESULT MDIClientWndProc_common( 
 
       case WM_SIZE:
         if( IsWindow(ci->hwndActiveChild) && IsZoomed(ci->hwndActiveChild) &&
-            IsWindowVisible(ci->hwndActiveChild) )
+            (GetWindowLongW(ci->hwndActiveChild, GWL_STYLE) & WS_VISIBLE) )
 	{
 	    RECT	rect;
 






More information about the wine-patches mailing list