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/m…
==============================================================================
--- 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);
}