Make sure that both deactivated and activated MDI children receive WM_MDIACTIVATE message in all cases

Dmitry Timoshkov dmitry at baikal.ru
Fri Jun 18 08:16:24 CDT 2004


Hello,

this patch merges two existing paths for activating MDI children
and makes sure that both deactivated and activated children get
WM_MDIACTIVATE message in all cases. Right now due to different
code paths last destroyed MDI child doesn't receive WM_MDIACTIVATE,
and an app I'm working on has no chance to do a proper clean up.

The logs created under Windows show that Windows doesn't mess
with WS_SYSMENU window style at all, and DefMDIChildProc does
nothing on WM_SETFOCUS.

I'll add message tests for MDI at some point, when I persuade
myself that it's a real showstopper for future work.

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    Make sure that both deactivated and activated MDI children
    receive WM_MDIACTIVATE message in all cases.

--- cvs/hq/wine/windows/mdi.c	Fri May 28 12:23:06 2004
+++ wine/windows/mdi.c	Tue Jun  1 21:08:31 2004
@@ -490,17 +490,11 @@ static void MDI_SwitchActiveChild( HWND 
 
     TRACE("from %p, to %p\n",childHwnd,hwndTo);
 
-    if ( !hwndTo ) return; /* no window to switch to */
-
-    if ( hwndTo != hwndPrev )
-    {
+    if ( !hwndTo )
+        MDI_ChildActivate( clientHwnd, 0 );
+    else if ( hwndTo != hwndPrev )
 	SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0,
                       SWP_NOMOVE | SWP_NOSIZE );
-
-	if( bNextWindow && hwndPrev )
-	    SetWindowPos( hwndPrev, HWND_BOTTOM, 0, 0, 0, 0,
-                          SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
-    }
 }
 
 
@@ -517,19 +511,7 @@ static LRESULT MDIDestroyChild( HWND par
     if( child == ci->hwndActiveChild )
     {
         MDI_SwitchActiveChild(parent, child, TRUE);
-
-        if( child == ci->hwndActiveChild )
-        {
-            ShowWindow( child, SW_HIDE);
-            if( child == ci->hwndActiveChild && IsZoomed(ci->hwndActiveChild) )
-            {
-                HWND frame = GetParent(parent);
-                MDI_RestoreFrameMenu( frame, child );
-                MDI_UpdateFrameText( frame, parent, TRUE, NULL);
-            }
-
-            MDI_ChildActivate(parent, 0);
-        }
+        ShowWindow(child, SW_HIDE);
     }
 
     for (i = 0; i < ci->nActiveChildren; i++)
@@ -567,7 +549,7 @@ static LRESULT MDIDestroyChild( HWND par
 static LONG MDI_ChildActivate( HWND client, HWND child )
 {
     MDICLIENTINFO *clientInfo;
-    HWND prevActiveWnd;
+    HWND prevActiveWnd, frame;
     BOOL isActiveFrameWnd;
 
     if (child && (!IsWindowEnabled( child ))) return 0;
@@ -576,42 +558,41 @@ static LONG MDI_ChildActivate( HWND clie
 
     TRACE("%p\n", child);
 
-    isActiveFrameWnd = (GetActiveWindow() == GetParent(client));
+    frame = GetParent(client);
+    isActiveFrameWnd = (GetActiveWindow() == frame);
     prevActiveWnd = clientInfo->hwndActiveChild;
 
+    if (prevActiveWnd == child) return 0;
+
     /* deactivate prev. active child */
     if(prevActiveWnd)
     {
-        SetWindowLongW( prevActiveWnd, GWL_STYLE,
-                        GetWindowLongW( prevActiveWnd, GWL_STYLE ) | WS_SYSMENU );
         SendMessageW( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
         SendMessageW( prevActiveWnd, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child);
     }
 
+    clientInfo->hwndActiveChild = child;
+
     /* set appearance */
-    if (IsZoomed(clientInfo->hwndActiveChild) && clientInfo->hwndActiveChild != child)
+    if (IsZoomed(prevActiveWnd) && prevActiveWnd != child)
     {
-        INT cmd = SW_SHOWNORMAL;
-
         if( child )
         {
+            INT cmd = SW_SHOWNORMAL;
             HMENU hSysMenu = GetSystemMenu(child, FALSE);
             UINT state = 0;
             if (hSysMenu)
                 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
             if (state != 0xFFFFFFFF && !(state & (MF_DISABLED | MF_GRAYED)))
-            {
-                SendMessageW(clientInfo->hwndActiveChild, WM_SYSCOMMAND, SC_RESTORE, 0);
                 cmd = SW_SHOWMAXIMIZED;
-            }
 
-            clientInfo->hwndActiveChild = child;
+            ShowWindow( child, cmd );
         }
-
-        ShowWindow( clientInfo->hwndActiveChild, cmd );
+        else
+            MDI_RestoreFrameMenu(frame, child);
     }
 
-    clientInfo->hwndActiveChild = child;
+    MDI_UpdateFrameText(frame, client, TRUE, NULL);
 
     /* check if we have any children left */
     if( !child )
@@ -623,18 +604,10 @@ static LONG MDI_ChildActivate( HWND clie
 
     MDI_RefreshMenu(clientInfo);
 
-    /* bring active child to the top */
-    SetWindowPos( child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
-
     if( isActiveFrameWnd )
-    {
-	    SendMessageA( child, WM_NCACTIVATE, TRUE, 0L);
-	    if( GetFocus() == client )
-		SendMessageA( client, WM_SETFOCUS, (WPARAM)client, 0L );
-	    else
-		SetFocus( client );
-    }
-    SendMessageA( child, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child );
+        SendMessageW( child, WM_NCACTIVATE, TRUE, 0L);
+
+    SendMessageW( child, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, (LPARAM)child );
     return TRUE;
 }
 
@@ -937,11 +910,11 @@ static BOOL MDI_RestoreFrameMenu( HWND f
     }
 
     /* close */
-    DeleteMenu(menu,GetMenuItemCount(menu) - 1,MF_BYPOSITION);
+    DeleteMenu(menu, SC_CLOSE, MF_BYCOMMAND);
     /* restore */
-    DeleteMenu(menu,GetMenuItemCount(menu) - 1,MF_BYPOSITION);
+    DeleteMenu(menu, SC_RESTORE, MF_BYCOMMAND);
     /* minimize */
-    DeleteMenu(menu,GetMenuItemCount(menu) - 1,MF_BYPOSITION);
+    DeleteMenu(menu, SC_MINIMIZE, MF_BYCOMMAND);
 
     DrawMenuBar(frame);
 
@@ -1089,11 +1062,7 @@ static LRESULT MDIClientWndProc_common( 
 
       case WM_MDIACTIVATE:
       {
-        HWND hwndActive;
-
-        hwndActive = ci->hwndActiveChild;
-
-        if( hwndActive != (HWND)wParam )
+        if( ci->hwndActiveChild != (HWND)wParam )
 	    SetWindowPos((HWND)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE);
         return 0;
       }
@@ -1195,6 +1164,9 @@ static LRESULT MDIClientWndProc_common( 
                 else
                     ci->child = HeapReAlloc(GetProcessHeap(), 0, ci->child, sizeof(HWND) * ci->nActiveChildren);
 
+                TRACE("Adding MDI child %p, # of children %d\n",
+                      (HWND)lParam, ci->nActiveChildren);
+
                 ci->child[ci->nActiveChildren - 1] = (HWND)lParam;
             }
             break;
@@ -1468,11 +1440,6 @@ LRESULT WINAPI DefMDIChildProcW( HWND hw
         SendMessageW( client, WM_MDIDESTROY, (WPARAM)hwnd, 0 );
         return 0;
 
-    case WM_SETFOCUS:
-        if (ci->hwndActiveChild != hwnd && IsWindowVisible(hwnd))
-            MDI_ChildActivate( client, hwnd );
-        break;
-
     case WM_CHILDACTIVATE:
         MDI_ChildActivate( client, hwnd );
         return 0;
@@ -1486,14 +1453,10 @@ LRESULT WINAPI DefMDIChildProcW( HWND hw
             break;
         case SC_RESTORE:
         case SC_MINIMIZE:
-            SetWindowLongW( hwnd, GWL_STYLE,
-                            GetWindowLongW( hwnd, GWL_STYLE ) | WS_SYSMENU );
             break;
         case SC_MAXIMIZE:
             if (ci->hwndActiveChild == hwnd && IsZoomed(ci->hwndActiveChild))
                 return SendMessageW( GetParent(client), message, wParam, lParam);
-            SetWindowLongW( hwnd, GWL_STYLE,
-                            GetWindowLongW( hwnd, GWL_STYLE ) & ~WS_SYSMENU );
             break;
         case SC_NEXTWINDOW:
             SendMessageW( client, WM_MDINEXT, 0, 0);






More information about the wine-patches mailing list