MDI Window menu handling fixes

Dmitry Timoshkov dmitry at baikal.ru
Tue Apr 27 07:08:33 CDT 2004


Hello,

No, Windows does not remember how many items a Window menu had
at the creation time. Our code is already compliant with that.

But it looks like Windows before removing menu items after a separator
in MDI Window menu checks if the next menu item has a "magic" value.
That's our code has problems with.

Also it seems that WM_SETVISIBLE is so old that it exists only
in Wine headers these days. We need to handle WM_SHOWWINDOW
instead. I hope this change doesn't require a separate patch.

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    Before removing menu items in the MDI Window menu check whether
    a menu item following a separator has our "magic" value.

--- cvs/hq/wine/windows/mdi.c	2004-04-01 19:05:41.000000000 +0900
+++ wine/windows/mdi.c	2004-04-27 20:50:59.000000000 +0900
@@ -315,7 +315,6 @@ static LRESULT MDISetMenu( HWND hwnd, HM
 
             /* Add items to the new Window menu */
             ci->nActiveChildren = nActiveChildren_old;
-            AppendMenuW(hmenuWindow, MF_SEPARATOR, 0, NULL);
             MDI_RefreshMenu(ci);
         }
         else
@@ -356,7 +355,7 @@ static LRESULT MDISetMenu( HWND hwnd, HM
  */
 static LRESULT MDI_RefreshMenu(MDICLIENTINFO *ci)
 {
-    UINT i, count, visible, separator_pos;
+    UINT i, count, visible, separator_pos, id;
     WCHAR buf[MDI_MAXTITLELENGTH];
 
     TRACE("children %u, window menu %p\n", ci->nActiveChildren, ci->hWindowMenu);
@@ -370,9 +369,11 @@ static LRESULT MDI_RefreshMenu(MDICLIENT
         return 0;
     }
 
-    /* Windows finds the last separator in the menu, removes all existing
+    /* Windows finds the last separator in the menu, and if after it
+     * there is a menu item with MDI magic ID removes all existing
      * menu items after it, and then adds visible MDI children.
      */
+    id = (UINT)-1;
     separator_pos = 0;
     count = GetMenuItemCount(ci->hWindowMenu);
     for (i = 0; i < count; i++)
@@ -382,30 +383,43 @@ static LRESULT MDI_RefreshMenu(MDICLIENT
         memset(&mii, 0, sizeof(mii));
         mii.cbSize = sizeof(mii);
         mii.fMask  = MIIM_TYPE;
-        GetMenuItemInfoW(ci->hWindowMenu, i, TRUE, &mii);
+        if (GetMenuItemInfoW(ci->hWindowMenu, i, TRUE, &mii))
+        {
+            if (mii.fType & MF_SEPARATOR)
+            {
+                separator_pos = i;
 
-        if (mii.fType & MFT_SEPARATOR)
-            separator_pos = i;
+                /* Windows checks only ID of the menu item */
+                memset(&mii, 0, sizeof(mii));
+                mii.cbSize = sizeof(mii);
+                mii.fMask  = MIIM_ID;
+                if (GetMenuItemInfoW(ci->hWindowMenu, i + 1, TRUE, &mii))
+                    id = mii.wID;
+            }
+        }
     }
 
-    for (i = separator_pos + 1; i < count; i++)
-        RemoveMenu(ci->hWindowMenu, separator_pos + 1, MF_BYPOSITION);
+    if (separator_pos && id == ci->idFirstChild)
+    {
+        for (i = separator_pos; i < count; i++)
+            RemoveMenu(ci->hWindowMenu, separator_pos, MF_BYPOSITION);
+    }
 
     visible = 0;
     for (i = 0; i < ci->nActiveChildren; i++)
     {
-        UINT id = ci->idFirstChild + i;
-
-        if (visible == MDI_MOREWINDOWSLIMIT)
-        {
-            LoadStringW(user32_module, IDS_MDI_MOREWINDOWS, buf, sizeof(buf)/sizeof(WCHAR));
-            AppendMenuW(ci->hWindowMenu, MF_STRING, id, buf);
-            break;
-        }
-
         if (GetWindowLongW(ci->child[i], GWL_STYLE) & WS_VISIBLE)
         {
-            if (!visible && !separator_pos)
+            id = ci->idFirstChild + visible;
+
+            if (visible == MDI_MOREWINDOWSLIMIT)
+            {
+                LoadStringW(user32_module, IDS_MDI_MOREWINDOWS, buf, sizeof(buf)/sizeof(WCHAR));
+                AppendMenuW(ci->hWindowMenu, MF_STRING, id, buf);
+                break;
+            }
+
+            if (!visible)
                 /* Visio expects that separator has id 0 */
                 AppendMenuW(ci->hWindowMenu, MF_SEPARATOR, 0, NULL);
 
@@ -1409,6 +1423,7 @@ LRESULT WINAPI DefMDIChildProcA( HWND hw
     case WM_SETFOCUS:
     case WM_CHILDACTIVATE:
     case WM_SYSCOMMAND:
+    case WM_SHOWWINDOW:
     case WM_SETVISIBLE:
     case WM_SIZE:
     case WM_NEXTMENU:
@@ -1487,6 +1502,7 @@ LRESULT WINAPI DefMDIChildProcW( HWND hw
         }
         break;
 
+    case WM_SHOWWINDOW:
     case WM_SETVISIBLE:
         if (IsZoomed(ci->hwndActiveChild)) ci->mdiFlags &= ~MDIF_NEEDUPDATE;
         else MDI_PostUpdate(client, ci, SB_BOTH+1);






More information about the wine-patches mailing list