mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 14:30:57 +00:00
- 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 svn path=/trunk/; revision=33529
This commit is contained in:
parent
c091afbac7
commit
5961c78fbd
1 changed files with 116 additions and 33 deletions
|
@ -1049,6 +1049,7 @@ static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU hMenu)
|
|||
}
|
||||
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 @@ static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
|
|||
}
|
||||
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 @@ CheckMenuItem(HMENU hmenu,
|
|||
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 @@ CheckMenuRadioItem(HMENU hmenu,
|
|||
UINT idCheck,
|
||||
UINT uFlags)
|
||||
{
|
||||
ROSMENUINFO mi;
|
||||
PROSMENUITEMINFO Items;
|
||||
int i;
|
||||
BOOL ret = FALSE;
|
||||
UINT cChecked = 0;
|
||||
UINT cUnchecked = 0;
|
||||
UINT cMenuChanged = 0;
|
||||
|
||||
mi.cbSize = sizeof(MENUINFO);
|
||||
if (!MenuCheckMenuRadioItem(hmenu, idFirst, idLast, idCheck, uFlags, FALSE, &cChecked, &cUnchecked, &cMenuChanged))
|
||||
return FALSE;
|
||||
|
||||
TRACE("CheckMenuRadioItem\n");
|
||||
if (cMenuChanged > 1)
|
||||
return FALSE;
|
||||
|
||||
if(idFirst > idLast) return ret;
|
||||
cMenuChanged = 0;
|
||||
cChecked = 0;
|
||||
cUnchecked = 0;
|
||||
|
||||
if(!NtUserMenuInfo(hmenu, &mi, FALSE)) return ret;
|
||||
if (!MenuCheckMenuRadioItem(hmenu, idFirst, idLast, idCheck, uFlags, TRUE, &cChecked, &cUnchecked, &cMenuChanged))
|
||||
return FALSE;
|
||||
|
||||
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;
|
||||
return (cChecked != 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue