home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / OWLSRC.PAK / MENUDESC.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  6.1 KB  |  272 lines

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