home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / owlsrc.pak / MENUDESC.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-24  |  5.7 KB  |  246 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // (C) Copyright 1991, 1994 by Borland International, All Rights Reserved
  4. //
  5. //   Implementation of class TMenuDescr
  6. //----------------------------------------------------------------------------
  7. #pragma hdrignore SECTION
  8. #include <owl/owlpch.h>
  9. #include <owl/menu.h>
  10. #include <owl/module.h>
  11.  
  12. #if !defined(SECTION) || SECTION == 1
  13.  
  14. //
  15. // Construct a default, empty menu descriptor
  16. //
  17. TMenuDescr::TMenuDescr()
  18. :
  19.   TMenu()
  20. {
  21.   Id = 0;
  22.   Module = ::Module;
  23.   for (int i = 0; i < NumGroups; i++)
  24.     GroupCount[i] = 0;
  25. }
  26.  
  27. //
  28. // Construct a menu descriptor from an existing one
  29. //
  30. TMenuDescr::TMenuDescr(const TMenuDescr& other)
  31. :
  32.   TMenu(other)
  33. {
  34.   Id = other.Id;
  35.   Module = other.Module;
  36.   for (int i = 0; i < NumGroups; i++)
  37.     GroupCount[i] = other.GroupCount[i];
  38. }
  39.  
  40. //
  41. // Construct a menu descriptor from a normal menu resource, supplying group
  42. // counts here. If the resource has seperators, use those instead of the counts
  43. //
  44. TMenuDescr::TMenuDescr(TResId id,
  45.                        int fg, int eg, int cg, int og, int wg, int hg,
  46.                        TModule* module)
  47. :
  48.   TMenu(*module, id),
  49.   Module(module),
  50.   Id(id)
  51. {
  52.   if (!ExtractGroups()) {
  53.     GroupCount[FileGroup] = fg;
  54.     GroupCount[EditGroup] = eg;
  55.     GroupCount[ContainerGroup] = cg;
  56.     GroupCount[ObjectGroup] = og;
  57.     GroupCount[WindowGroup] = wg;
  58.     GroupCount[HelpGroup] = hg;
  59.   }
  60. }
  61.  
  62. //
  63. // Construct a menu descriptor from a menu resource with group separators
  64. // built in (using MF_SEPARATOR)
  65. //
  66. TMenuDescr::TMenuDescr(TResId id, TModule* module)
  67. :
  68.   TMenu(*module, id),
  69.   Module(module),
  70.   Id(id)
  71. {
  72.   ExtractGroups();
  73. }
  74.  
  75. //
  76. // Construct a menu descriptor that is an alias for an existing menu with group
  77. // information. If the menu has seperators, use those instead of the counts
  78. //
  79. TMenuDescr::TMenuDescr(HMENU hMenu,
  80.                        int fg, int eg, int cg, int og, int wg, int hg,
  81.                        TModule* module)
  82. :
  83.   TMenu(hMenu, NoAutoDelete),
  84.   Module(module)
  85. {
  86.   if (!ExtractGroups()) {
  87.     GroupCount[FileGroup] = fg;
  88.     GroupCount[EditGroup] = eg;
  89.     GroupCount[ContainerGroup] = cg;
  90.     GroupCount[ObjectGroup] = og;
  91.     GroupCount[WindowGroup] = wg;
  92.     GroupCount[HelpGroup] = hg;
  93.   }
  94. }
  95.  
  96. //
  97. // destructor
  98. //
  99. TMenuDescr::~TMenuDescr()
  100. {
  101. }
  102.  
  103. //
  104. // Assign another menu descriptor on to this one
  105. //
  106. TMenuDescr&
  107. TMenuDescr::operator =(const TMenuDescr& other)
  108. {
  109.   *static_cast<TMenu*>(this) = *static_cast<const TMenu*>(&other);
  110.   Id = other.Id;
  111.   Module = other.Module;
  112.   for (int i = 0; i < NumGroups; i++)
  113.     GroupCount[i] = other.GroupCount[i];
  114.   return *this;
  115. }
  116.  
  117. //
  118. // Scan menu looking for separators that signify group divisions
  119. // return whether we found any at all
  120. //
  121. bool
  122. TMenuDescr::ExtractGroups()
  123. {
  124.   if (!Handle)
  125.     return false;  // no menu to extract from...
  126.  
  127.   // walk menu & remove separators, setting up count as we go.
  128.   //
  129.   int itemCount = GetMenuItemCount();
  130.   int g = 0;
  131.   int count = 0;
  132.   for (int i = 0; i < itemCount; ) {
  133.     uint s = GetMenuState(i, MF_BYPOSITION);
  134.     if ((s & MF_SEPARATOR) && !(s & MF_POPUP)) {
  135.       if (g < NumGroups)
  136.         GroupCount[g++] = count;
  137.       count = 0;
  138.       RemoveMenu(i, MF_BYPOSITION);
  139.       itemCount--;
  140.     }
  141.     else {
  142.       i++;
  143.       count++;
  144.     }
  145.   }
  146.   // Leave if no separators were found
  147.   //
  148.   if (!g)
  149.     return false;
  150.  
  151.   // Get trailing group
  152.   //
  153.   if (g < NumGroups)
  154.     GroupCount[g++] = count;
  155.  
  156.   // Finish zeroing groups
  157.   //
  158.   for (; g < NumGroups; g++)
  159.     GroupCount[g] = 0;
  160.   return true;
  161. }
  162.  
  163. //
  164. // Merge another menu descriptor into this menu descriptor
  165. // Popups are DeepCopied and are then owned by this menu
  166. // Group counts are merged too.
  167. //
  168. bool
  169. TMenuDescr::Merge(const TMenuDescr& srcMenuDescr)
  170. {
  171.   int thisOffset = 0;
  172.   int srcOffset = 0;
  173.  
  174.   for (int i = 0; i < NumGroups; i++) {
  175.     if (srcMenuDescr.GroupCount[i] != 0) {
  176.       // Delete same menu group in the dest. menudescr.
  177.       for (int j = GroupCount[i] - 1; j >= 0; j--) {
  178.         DeleteMenu(thisOffset+j, MF_BYPOSITION);
  179.       }
  180.       GroupCount[i] = 0;
  181.  
  182.       if (srcMenuDescr.GroupCount[i] > 0) {
  183.         DeepCopy(*this, thisOffset, srcMenuDescr, srcOffset, srcMenuDescr.GroupCount[i]);
  184.         srcOffset += srcMenuDescr.GroupCount[i];
  185.         GroupCount[i] += srcMenuDescr.GroupCount[i];
  186.       }
  187.     }
  188.  
  189.     if (GroupCount[i] > 0)
  190.       thisOffset += GroupCount[i];
  191.   }
  192.   return true;
  193. }
  194.  
  195. //
  196. // Merge another menu descriptor, with this menu descriptor into a third menu
  197. // Popups are DeepCopied and are then owned by the destMenu.
  198. //
  199. bool
  200. TMenuDescr::Merge(const TMenuDescr& srcMenuDescr, TMenu& dstMenu)
  201. {
  202.   int thisOffset = 0;
  203.   int srcOffset = 0;
  204.  
  205.   for (int i = 0; i < NumGroups; i++) {
  206.     if (srcMenuDescr.GroupCount[i] > 0) {
  207.       DeepCopy(dstMenu, srcMenuDescr, srcOffset, srcMenuDescr.GroupCount[i]);
  208.       srcOffset += srcMenuDescr.GroupCount[i];
  209.     }
  210.     else if (srcMenuDescr.GroupCount[i] == 0 && GroupCount[i] > 0) {
  211.       DeepCopy(dstMenu, *this, thisOffset, GroupCount[i]);
  212.     }
  213.     // else don't copy either
  214.  
  215.     if (GroupCount[i] > 0)
  216.       thisOffset += GroupCount[i];
  217.   }
  218.   return true;
  219. }
  220.  
  221. #endif
  222. #if !defined(SECTION) || SECTION == 2
  223.  
  224. ipstream& _OWLFUNC
  225. operator >>(ipstream& is, TMenuDescr& m)
  226. {
  227.   is >> m.Id;
  228.   is >> m.Module;
  229.   for (int i = 0; i < TMenuDescr::NumGroups; i++)
  230.     is >> m.GroupCount[i];
  231.   return is;
  232. }
  233.  
  234. opstream& _OWLFUNC
  235. operator <<(opstream& os, const TMenuDescr& m)
  236. {
  237.   os << m.Id;
  238.   os << m.Module;
  239.   for (int i = 0; i < TMenuDescr::NumGroups; i++)
  240.     os << m.GroupCount[i];
  241.   return os;
  242. }
  243.  
  244.  
  245. #endif
  246.