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/me... ============================================================================== --- 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); }