//---------------------------------------------------------------------------- // ObjectWindows // (C) Copyright 1991, 1994 by Borland International, All Rights Reserved // // Implementation of class TMenuDescr //---------------------------------------------------------------------------- #pragma hdrignore SECTION #include #include #include #if !defined(SECTION) || SECTION == 1 // // Construct a default, empty menu descriptor // TMenuDescr::TMenuDescr() : TMenu() { Id = 0; Module = ::Module; for (int i = 0; i < NumGroups; i++) GroupCount[i] = 0; } // // Construct a menu descriptor from an existing one // TMenuDescr::TMenuDescr(const TMenuDescr& other) : TMenu(other) { Id = other.Id; Module = other.Module; for (int i = 0; i < NumGroups; i++) GroupCount[i] = other.GroupCount[i]; } // // Construct a menu descriptor from a normal menu resource, supplying group // counts here. If the resource has seperators, use those instead of the counts // TMenuDescr::TMenuDescr(TResId id, int fg, int eg, int cg, int og, int wg, int hg, TModule* module) : TMenu(*module, id), Module(module), Id(id) { if (!ExtractGroups()) { GroupCount[FileGroup] = fg; GroupCount[EditGroup] = eg; GroupCount[ContainerGroup] = cg; GroupCount[ObjectGroup] = og; GroupCount[WindowGroup] = wg; GroupCount[HelpGroup] = hg; } } // // Construct a menu descriptor from a menu resource with group separators // built in (using MF_SEPARATOR) // TMenuDescr::TMenuDescr(TResId id, TModule* module) : TMenu(*module, id), Module(module), Id(id) { ExtractGroups(); } // // Construct a menu descriptor that is an alias for an existing menu with group // information. If the menu has seperators, use those instead of the counts // TMenuDescr::TMenuDescr(HMENU hMenu, int fg, int eg, int cg, int og, int wg, int hg, TModule* module) : TMenu(hMenu, NoAutoDelete), Module(module) { if (!ExtractGroups()) { GroupCount[FileGroup] = fg; GroupCount[EditGroup] = eg; GroupCount[ContainerGroup] = cg; GroupCount[ObjectGroup] = og; GroupCount[WindowGroup] = wg; GroupCount[HelpGroup] = hg; } } // // destructor // TMenuDescr::~TMenuDescr() { } // // Assign another menu descriptor on to this one // TMenuDescr& TMenuDescr::operator =(const TMenuDescr& other) { *static_cast(this) = *static_cast(&other); Id = other.Id; Module = other.Module; for (int i = 0; i < NumGroups; i++) GroupCount[i] = other.GroupCount[i]; return *this; } // // Scan menu looking for separators that signify group divisions // return whether we found any at all // bool TMenuDescr::ExtractGroups() { if (!Handle) return false; // no menu to extract from... // walk menu & remove separators, setting up count as we go. // int itemCount = GetMenuItemCount(); int g = 0; int count = 0; for (int i = 0; i < itemCount; ) { uint s = GetMenuState(i, MF_BYPOSITION); if ((s & MF_SEPARATOR) && !(s & MF_POPUP)) { if (g < NumGroups) GroupCount[g++] = count; count = 0; RemoveMenu(i, MF_BYPOSITION); itemCount--; } else { i++; count++; } } // Leave if no separators were found // if (!g) return false; // Get trailing group // if (g < NumGroups) GroupCount[g++] = count; // Finish zeroing groups // for (; g < NumGroups; g++) GroupCount[g] = 0; return true; } // // Merge another menu descriptor into this menu descriptor // Popups are DeepCopied and are then owned by this menu // Group counts are merged too. // bool TMenuDescr::Merge(const TMenuDescr& srcMenuDescr) { int thisOffset = 0; int srcOffset = 0; for (int i = 0; i < NumGroups; i++) { if (srcMenuDescr.GroupCount[i] != 0) { // Delete same menu group in the dest. menudescr. for (int j = GroupCount[i] - 1; j >= 0; j--) { DeleteMenu(thisOffset+j, MF_BYPOSITION); } GroupCount[i] = 0; if (srcMenuDescr.GroupCount[i] > 0) { DeepCopy(*this, thisOffset, srcMenuDescr, srcOffset, srcMenuDescr.GroupCount[i]); srcOffset += srcMenuDescr.GroupCount[i]; GroupCount[i] += srcMenuDescr.GroupCount[i]; } } if (GroupCount[i] > 0) thisOffset += GroupCount[i]; } return true; } // // Merge another menu descriptor, with this menu descriptor into a third menu // Popups are DeepCopied and are then owned by the destMenu. // bool TMenuDescr::Merge(const TMenuDescr& srcMenuDescr, TMenu& dstMenu) { int thisOffset = 0; int srcOffset = 0; for (int i = 0; i < NumGroups; i++) { if (srcMenuDescr.GroupCount[i] > 0) { DeepCopy(dstMenu, srcMenuDescr, srcOffset, srcMenuDescr.GroupCount[i]); srcOffset += srcMenuDescr.GroupCount[i]; } else if (srcMenuDescr.GroupCount[i] == 0 && GroupCount[i] > 0) { DeepCopy(dstMenu, *this, thisOffset, GroupCount[i]); } // else don't copy either if (GroupCount[i] > 0) thisOffset += GroupCount[i]; } return true; } #endif #if !defined(SECTION) || SECTION == 2 ipstream& _OWLFUNC operator >>(ipstream& is, TMenuDescr& m) { is >> m.Id; is >> m.Module; for (int i = 0; i < TMenuDescr::NumGroups; i++) is >> m.GroupCount[i]; return is; } opstream& _OWLFUNC operator <<(opstream& os, const TMenuDescr& m) { os << m.Id; os << m.Module; for (int i = 0; i < TMenuDescr::NumGroups; i++) os << m.GroupCount[i]; return os; } #endif