[ros-diffs] [janderwald] 33529: - use menu identifier for menu items which have submenus - menu item is a separator when id, flags and string is zero (verified with MS Visual 2005) - set item separator MF_GRAYED as default style - rewrite CheckMenuRadioItem - check if checkmarks applies to more than one submenu - check if checkmark was set - dont set checkmark on menu item separator - recurse into sub menus when available - implement handling by MF_BYPOSITION - ReactOS now passes now all tests from test_CheckMenuRadioItem in user32_winetest

janderwald at svn.reactos.org janderwald at svn.reactos.org
Thu May 15 16:10:55 CEST 2008


Author: janderwald
Date: Thu May 15 09:10:55 2008
New Revision: 33529

URL: http://svn.reactos.org/svn/reactos?rev=33529&view=rev
Log:
- use menu identifier for menu items which have submenus
- menu item is a separator when id, flags and string is zero (verified with MS Visual 2005)
- set item separator MF_GRAYED as default style
- rewrite CheckMenuRadioItem
- check if checkmarks applies to more than one submenu
- check if checkmark was set
- dont set checkmark on menu item separator
- recurse into sub menus when available
- implement handling by MF_BYPOSITION
- ReactOS now passes now all tests from test_CheckMenuRadioItem in user32_winetest

Modified:
    trunk/reactos/dll/win32/user32/windows/menu.c

Modified: trunk/reactos/dll/win32/user32/windows/menu.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/menu.c?rev=33529&r1=33528&r2=33529&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/menu.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/user32/windows/menu.c [iso-8859-1] Thu May 15 09:10:55 2008
@@ -1049,6 +1049,7 @@
 	  }
 	  mii.fMask |= MIIM_SUBMENU;
 	  mii.fType |= MF_POPUP;
+	  mii.wID = (UINT) mii.hSubMenu;
 	}
       else if(!*mii.dwTypeData && !(mii.fType & MF_SEPARATOR))
 	{
@@ -1108,6 +1109,8 @@
     }
     else  /* Not a popup */
     {
+      if (flags == 0 && id == 0 && *str == 0)
+        flags = MF_SEPARATOR | MF_GRAYED;
       if(!unicode)
         AppendMenuA(hMenu, flags, id, *str ? str : NULL);
       else
@@ -3848,6 +3851,106 @@
   return NtUserCheckMenuItem(hmenu, uIDCheckItem, uCheck);
 }
 
+static
+BOOL
+MenuCheckMenuRadioItem(HMENU hMenu, UINT idFirst, UINT idLast, UINT idCheck, UINT uFlags, BOOL bCheck, PUINT pChecked, PUINT pUnchecked, PUINT pMenuChanged)
+{
+  UINT ItemCount, i;
+  PROSMENUITEMINFO Items = NULL;
+  UINT cChecked, cUnchecked;
+  BOOL bRet = TRUE;
+  //ROSMENUINFO mi;
+
+  if(idFirst > idLast)
+      return FALSE;
+
+  ItemCount = GetMenuItemCount(hMenu);
+
+  //mi.cbSize = sizeof(ROSMENUINFO);
+  //if(!NtUserMenuInfo(hmenu, &mi, FALSE)) return ret;
+
+
+  if(MenuGetAllRosMenuItemInfo(hMenu, &Items) <= 0)
+  {
+    ERR("MenuGetAllRosMenuItemInfo failed\n");
+    return FALSE;
+  }
+
+  cChecked = cUnchecked = 0;
+
+  for (i = 0 ; i < ItemCount; i++)
+  {
+    BOOL check = FALSE;
+    if (0 != (Items[i].fType & MF_MENUBARBREAK)) continue;
+    if (0 != (Items[i].fType & MF_SEPARATOR)) continue;
+
+    if ((Items[i].fType & MF_POPUP) && (uFlags == MF_BYCOMMAND))
+    {
+      MenuCheckMenuRadioItem(Items[i].hSubMenu, idFirst, idLast, idCheck, uFlags, bCheck, pChecked, pUnchecked, pMenuChanged);
+      continue;
+    }
+    if (uFlags & MF_BYPOSITION)
+    {
+      if (i < idFirst || i > idLast)
+        continue;
+
+      if (i == idCheck)
+      {
+        cChecked++;
+        check = TRUE;
+      }
+      else
+      {
+        cUnchecked++;
+      }
+    }
+      else
+      {
+        if (Items[i].wID < idFirst || Items[i].wID > idLast)
+          continue;
+
+        if (Items[i].wID == idCheck)
+        {
+          cChecked++;
+          check = TRUE;
+        }
+        else
+        {
+          cUnchecked++;
+        }
+      }
+
+      if (!bCheck)
+        continue;
+
+      Items[i].fMask = MIIM_STATE | MIIM_FTYPE;
+      if (check)
+      {
+        Items[i].fType |= MFT_RADIOCHECK;
+        Items[i].fState |= MFS_CHECKED;
+      }
+      else
+      {
+        Items[i].fState &= ~MFS_CHECKED;
+      }
+
+      if(!MenuSetRosMenuItemInfo(hMenu, i ,&Items[i]))
+      {
+        ERR("MenuSetRosMenuItemInfo failed\n");
+        bRet = FALSE;
+        break;
+      }
+  }
+  MenuCleanupRosMenuItemInfo(Items);
+
+  *pChecked += cChecked;
+  *pUnchecked += cUnchecked;
+
+  if (cChecked || cUnchecked)
+    (*pMenuChanged)++;
+
+  return bRet;
+}
 
 /*
  * @implemented
@@ -3859,44 +3962,24 @@
 		   UINT idCheck,
 		   UINT uFlags)
 {
-  ROSMENUINFO mi;
-  PROSMENUITEMINFO Items;
-  int i;
-  BOOL ret = FALSE;
-
-  mi.cbSize = sizeof(MENUINFO);
-
-  TRACE("CheckMenuRadioItem\n");
-
-  if(idFirst > idLast) return ret;
-
-  if(!NtUserMenuInfo(hmenu, &mi, FALSE)) return ret;
-
-  if(MenuGetAllRosMenuItemInfo(mi.Self, &Items) <= 0) return ret;
-
-  for (i = 0 ; i < mi.MenuItemCount; i++)
-    {
-      if (0 != (Items[i].fType & MF_MENUBARBREAK)) break;
-      if ( i >= idFirst && i <= idLast )
-      {
-         Items[i].fMask = MIIM_STATE | MIIM_FTYPE;
-         if ( i == idCheck)
-         {
-             Items[i].fType |= MFT_RADIOCHECK;
-             Items[i].fState |= MFS_CHECKED;
-         }
-         else
-         {
-             Items[i].fType &= ~MFT_RADIOCHECK;
-             Items[i].fState &= ~MFS_CHECKED;
-         }
-         if(!MenuSetRosMenuItemInfo(mi.Self, i ,&Items[i]))
-             break;
-      }
-   if ( i == mi.MenuItemCount) ret = TRUE;
-    }
-  MenuCleanupRosMenuItemInfo(Items);
-  return ret;
+  UINT cChecked = 0;
+  UINT cUnchecked = 0;
+  UINT cMenuChanged = 0;
+
+  if (!MenuCheckMenuRadioItem(hmenu, idFirst, idLast, idCheck, uFlags, FALSE, &cChecked, &cUnchecked, &cMenuChanged))
+    return FALSE;
+
+  if (cMenuChanged > 1)
+    return FALSE;
+
+  cMenuChanged = 0;
+  cChecked = 0;
+  cUnchecked = 0;
+
+  if (!MenuCheckMenuRadioItem(hmenu, idFirst, idLast, idCheck, uFlags, TRUE, &cChecked, &cUnchecked, &cMenuChanged))
+    return FALSE;
+
+  return (cChecked != 0);
 }
 
 



More information about the Ros-diffs mailing list