// Copy a menu onto the beginning or end of another menu // Adds uIDAdjust to each menu ID (pass in 0 for no adjustment) // Will not add any item whose adjusted ID is greater than uMaxIDAdjust // (pass in 0xffff to allow everything) // Returns one more than the maximum adjusted ID that is used //
UINT WINAPI Shell_MergeMenus(HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags) { int nItem; HMENU hmSubMenu; BOOL bAlreadySeparated; MENUITEMINFO miiSrc; TCHAR szName[256]; UINT uTemp, uIDMax = uIDAdjust;
if (!hmDst || !hmSrc) { goto MM_Exit; }
nItem = GetMenuItemCount(hmDst); if (uInsert >= (UINT)nItem) { uInsert = (UINT)nItem; bAlreadySeparated = TRUE; } else { bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert);; }
if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated) { // Add a separator between the menus InsertMenu(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); bAlreadySeparated = TRUE; }
// Go through the menu items and clone them for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--) { miiSrc.cbSize = SIZEOF(MENUITEMINFO); miiSrc.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA; // We need to reset this every time through the loop in case // menus DON'T have IDs miiSrc.fType = MFT_STRING; miiSrc.dwTypeData = szName; miiSrc.dwItemData = 0; miiSrc.cch = ARRAYSIZE(szName);
if (!GetMenuItemInfo(hmSrc, nItem, TRUE, &miiSrc)) { continue; }
// If it's a separator, then add it. If the separator has a // submenu, then the caller is smoking crash and needs their butt kicked. if ((miiSrc.fType & MFT_SEPARATOR) && EVAL(!miiSrc.hSubMenu)) { // This is a separator; don't put two of them in a row if (bAlreadySeparated && miiSrc.wID == -1 && !(uFlags & MM_DONTREMOVESEPS)) { continue; }
bAlreadySeparated = TRUE; } else if (miiSrc.hSubMenu) { if (uFlags & MM_SUBMENUSHAVEIDS) { // Adjust the ID and check it miiSrc.wID += uIDAdjust; if (miiSrc.wID > uIDAdjustMax) { continue; }
if (uIDMax <= miiSrc.wID) { uIDMax = miiSrc.wID + 1; } } else { // Don't set IDs for submenus that didn't have // them already miiSrc.fMask &= ~MIIM_ID; }
hmSubMenu = miiSrc.hSubMenu; miiSrc.hSubMenu = CreatePopupMenu(); if (!miiSrc.hSubMenu) { goto MM_Exit; }
uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags&MM_SUBMENUSHAVEIDS); if (uIDMax <= uTemp) { uIDMax = uTemp; }
bAlreadySeparated = FALSE; } else { // Adjust the ID and check it miiSrc.wID += uIDAdjust; if (miiSrc.wID > uIDAdjustMax) { continue; }
if (uIDMax <= miiSrc.wID) { uIDMax = miiSrc.wID + 1; }
bAlreadySeparated = FALSE; }
if (!EVAL(InsertMenuItem(hmDst, uInsert, TRUE, &miiSrc))) { goto MM_Exit; } }
// Ensure the correct number of separators at the beginning of the // inserted menu items if (uInsert == 0) { if (bAlreadySeparated && !(uFlags & MM_DONTREMOVESEPS)) { DeleteMenu(hmDst, uInsert, MF_BYPOSITION); } } else { if (_SHIsMenuSeparator(hmDst, uInsert-1)) { if (bAlreadySeparated && !(uFlags & MM_DONTREMOVESEPS)) { DeleteMenu(hmDst, uInsert, MF_BYPOSITION); } } else { if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated) { // Add a separator between the menus InsertMenu(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); } } }
MM_Exit: #ifdef DEBUG DBCheckMenu(hmDst); #endif return(uIDMax); } 
|