Various MDI children activation fixes

Dmitry Timoshkov dmitry at baikal.ru
Tue Jun 1 10:15:34 CDT 2004


Hello,

this patch is a result of my work on MDI children activation
sequence. An application I'm working on hardly depends on it.
I'm also attaching latest cersion of my MDI tool which I'm using
for all MDI related investigations, perhaps it will be useful for
somebody else.

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    - Use better dimensions for MDI system menu buttons to avoid
      MDI client window resizing.
    - ShowWindow shouldn't fix SWP_ flags, it's the job of SetWindowPos.
    - Child windows can be activated, but CreateWindow does not activate
      child windows.
    - Change MDI children activation sequence to make message flow
      more like in Windows.

diff -u cvs/hq/wine/controls/menu.c wine/controls/menu.c
--- cvs/hq/wine/controls/menu.c	Sun Apr 18 10:37:37 2004
+++ wine/controls/menu.c	Tue Jun  1 19:03:43 2004
@@ -732,8 +732,8 @@ static void MENU_GetBitmapItemSize( UINT
         case (INT_PTR)HBMMENU_MBAR_MINIMIZE_D:
         case (INT_PTR)HBMMENU_MBAR_CLOSE:
         case (INT_PTR)HBMMENU_MBAR_CLOSE_D:
-            size->cx = GetSystemMetrics( SM_CXSIZE );
-            size->cy = GetSystemMetrics( SM_CYSIZE );
+            size->cx = GetSystemMetrics( SM_CXSMICON );
+            size->cy = GetSystemMetrics( SM_CYSMICON );
             return;
         case (INT_PTR)HBMMENU_CALLBACK:
         case (INT_PTR)HBMMENU_POPUP_CLOSE:
diff -u cvs/hq/wine/dlls/x11drv/winpos.c wine/dlls/x11drv/winpos.c
--- cvs/hq/wine/dlls/x11drv/winpos.c	Sat May  1 18:19:06 2004
+++ wine/dlls/x11drv/winpos.c	Tue Jun  1 20:49:54 2004
@@ -1313,15 +1313,6 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT c
             /* fall through */
 	case SW_SHOW:
 	    swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
-
-	    /*
-	     * ShowWindow has a little peculiar behavior that if the
-	     * window is already the topmost window, it will not
-	     * activate it.
-	     */
-	    if (GetTopWindow(NULL)==hwnd && (wasVisible || GetActiveWindow() == hwnd))
-	      swp |= SWP_NOACTIVATE;
-
 	    break;
 
 	case SW_SHOWNOACTIVATE:
@@ -1344,11 +1335,6 @@ BOOL X11DRV_ShowWindow( HWND hwnd, INT c
         SendMessageW( hwnd, WM_SHOWWINDOW, showFlag, 0 );
         if (!IsWindow( hwnd )) goto END;
     }
-
-    /* We can't activate a child window */
-    if ((wndPtr->dwStyle & WS_CHILD) &&
-        !(wndPtr->dwExStyle & WS_EX_MDICHILD))
-        swp |= SWP_NOACTIVATE | SWP_NOZORDER;
 
     SetWindowPos( hwnd, HWND_TOP, newPos.left, newPos.top,
                   newPos.right, newPos.bottom, LOWORD(swp) );
diff -u cvs/hq/wine/windows/mdi.c wine/windows/mdi.c
--- 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);
diff -u cvs/hq/wine/windows/win.c wine/windows/win.c
--- cvs/hq/wine/windows/win.c	Mon May 31 18:35:31 2004
+++ wine/windows/win.c	Tue Jun  1 21:22:45 2004
@@ -1001,7 +1001,7 @@ static void dump_window_styles( DWORD st
 static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
 				WINDOWPROCTYPE type )
 {
-    INT sw = SW_SHOW;
+    INT sw = (cs->style & WS_CHILD) ? SW_SHOWNOACTIVATE : SW_SHOW;
     WND *wndPtr;
     HWND hwnd, parent, owner, top_child = 0;
     BOOL unicode = (type == WIN_PROC_32W);






More information about the wine-patches mailing list