home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / owlsrc.pak / MENU.CPP < prev    next >
C/C++ Source or Header  |  1997-07-23  |  6KB  |  256 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // (C) Copyright 1991, 1994 by Borland International, All Rights Reserved
  4. //
  5. //   Implementation of Window Menu encapsulation class
  6. //----------------------------------------------------------------------------
  7. #include <owl/owlpch.h>
  8. #include <owl/menu.h>
  9.  
  10. DIAG_DECLARE_GROUP(OwlWin);        // General window diagnostic group
  11.  
  12. //
  13. // Construct a menu using CreateMenu()
  14. //
  15. TMenu::TMenu(TAutoDelete autoDelete)
  16. :
  17.   Handle(::CreateMenu()),
  18.   ShouldDelete(autoDelete)
  19. {
  20.   WARNX(OwlWin, !Handle, 0, "Cannot Create Menu");
  21.   CheckValid();
  22. }
  23.  
  24. //
  25. // Construct a menu as a deep copy of an exisiting menu
  26. //
  27. TMenu::TMenu(const TMenu& original, TAutoDelete autoDelete)
  28. :
  29.   Handle(::CreateMenu()),
  30.   ShouldDelete(autoDelete)
  31. {
  32.   WARNX(OwlWin, !Handle, 0, "Cannot Create Menu for Copy");
  33.   CheckValid();
  34.   DeepCopy(*this, original);
  35. }
  36.  
  37. //
  38. // Construct a menu as an alias for an existing handle
  39. //
  40. TMenu::TMenu(HMENU handle, TAutoDelete autoDelete)
  41. :
  42.   Handle(handle),
  43.   ShouldDelete(autoDelete)
  44. {
  45. }
  46.  
  47. //
  48. // Construct a menu alias for a given window's menu
  49. //
  50. TMenu::TMenu(HWND hWnd, TAutoDelete autoDelete)
  51. :
  52.   Handle(::GetMenu(hWnd)),
  53.   ShouldDelete(autoDelete)
  54. {
  55.   PRECONDITION(hWnd);
  56.   WARNX(OwlWin, !Handle, 0, "Cannot Get Menu from " << hex << (uint)hWnd);
  57.   CheckValid();
  58. }
  59.  
  60. //
  61. // Construct a menu from a menu template struct
  62. //
  63. TMenu::TMenu(const void far* menuTemplate)
  64. {
  65.   PRECONDITION(menuTemplate);
  66.   Handle = ::LoadMenuIndirect(menuTemplate);
  67.   WARNX(OwlWin, !Handle, 0, "Cannot Load Menu Indirect " << hex <<
  68.         uint32(menuTemplate));
  69.   CheckValid();
  70.   ShouldDelete = true;
  71. }
  72.  
  73. //
  74. // Construct a menu by loading it from resource
  75. //
  76. TMenu::TMenu(HINSTANCE resInstance, TResId resId)
  77. {
  78.   PRECONDITION(resInstance && resId);
  79.   Handle = ::LoadMenu(resInstance, resId);
  80.   WARNX(OwlWin, !Handle, 0, "Cannot Load Menu " << hex << (uint)resInstance <<
  81.                             " " << resId);
  82.   CheckValid();
  83.   ShouldDelete = true;
  84. }
  85.  
  86. //
  87. // Copy an existing menu onto this menu, using DeepCopy
  88. //
  89. TMenu&
  90. TMenu::operator =(const TMenu& original)
  91. {
  92.   // Delete all items and submenus
  93.   // Look at possible alternatives for !ShouldDelete menus? Maybe use Remove
  94.   // then?
  95.   //
  96.   while (GetMenuItemCount())
  97.     DeleteMenu(0, MF_BYPOSITION);
  98.   DeepCopy(*this, original);
  99.   return *this;
  100. }
  101.  
  102. //
  103. // Destruct the menu by destroying the handle if appropriate.
  104. //
  105. TMenu::~TMenu()
  106. {
  107.   if (ShouldDelete && Handle)
  108.     ::DestroyMenu(Handle);
  109. }
  110.  
  111. //
  112. // Get the menu ID. If it's a regular menu item just returns its id.
  113. // Otherwise if it's a popup menu use id of the first item in the popup menu.
  114. //
  115. uint
  116. TMenu::GetMenuItemID(int pos) const
  117. {
  118.   uint  id = ::GetMenuItemID(Handle, pos);
  119.   if (id != uint(-1))
  120.     return id;
  121.  
  122.   // Maybe a submenu
  123.   //
  124.   TMenu subMenu(GetSubMenu(pos));
  125.   if (subMenu.Handle == 0)
  126.     return 0;
  127.  
  128.   return subMenu.GetMenuItemID(0) - 1;
  129. }
  130.  
  131. #pragma warn -par  // resId param is never used in small model
  132. void
  133. TMenu::CheckValid(uint resId)
  134. {
  135.   if (!Handle)
  136.     THROW( TXMenu(resId) );
  137. }
  138. #pragma warn .par
  139.  
  140. void
  141. TMenu::MeasureItem(MEASUREITEMSTRUCT far&)
  142. {
  143. }
  144.  
  145. void
  146. TMenu::DrawItem(DRAWITEMSTRUCT far&)
  147. {
  148. }
  149.  
  150. //
  151. // Deep copy 'count' popup-menus or items from 'src' _appending_ to 'dst'
  152. // menu starting at 'offset' position in this menu
  153. //
  154. void
  155. TMenu::DeepCopy(TMenu& dst, const TMenu& src, int srcOff, int count)
  156. {
  157.   if (count < 0)
  158.     count = src.GetMenuItemCount() - srcOff;
  159.  
  160.   for (int i = 0; i < count; i++) {
  161.     uint  state = src.GetMenuState(srcOff+i, MF_BYPOSITION);
  162.     if (state == uint(-1))
  163.       return;
  164.  
  165.     char   str[256];
  166.     src.GetMenuString(srcOff+i, str, sizeof(str), MF_BYPOSITION);
  167.  
  168.     // Currently does NOT support MF_BITMAP or MF_OWNERDRAW
  169.     //
  170.     if (state & MF_POPUP) {
  171.       state &= (MF_STRING | MF_POPUP);  // strip off breaks, separators, etc
  172.       TMenu subMenu(src.GetSubMenu(srcOff+i));
  173.       TMenu newSubMenu(NoAutoDelete);
  174.       DeepCopy(newSubMenu, subMenu);
  175.       dst.AppendMenu(state, newSubMenu, str);
  176.     }
  177.     else {
  178.       dst.AppendMenu(state, src.GetMenuItemID(srcOff+i), str);
  179.     }
  180.   }
  181. }
  182.  
  183. //
  184. // Deep copy 'count' popup-menus or items from 'src' to 'dst' menu
  185. // starting at 'srcOff' position in src and inserting at 'dstOff' in the
  186. // destination
  187. //
  188. void
  189. TMenu::DeepCopy(TMenu& dst, int dstOff, const TMenu& src, int srcOff, int count)
  190. {
  191.   if (count < 0)
  192.     count = src.GetMenuItemCount() - srcOff;
  193.  
  194.   for (int i = 0; i < count; i++) {
  195.     uint  state = src.GetMenuState(srcOff+i, MF_BYPOSITION);
  196.     if (state == uint(-1))
  197.       return;
  198.  
  199.     char   str[256];
  200.     src.GetMenuString(srcOff+i, str, sizeof(str), MF_BYPOSITION);
  201.  
  202.     // Currently does NOT support MF_BITMAP or MF_OWNERDRAW
  203.     //
  204.     if (state & MF_POPUP) {
  205.       state &= (MF_STRING | MF_POPUP);  // strip off breaks, separators, etc
  206.       TMenu subMenu(src.GetSubMenu(srcOff+i));
  207.       TMenu newSubMenu(NoAutoDelete);
  208.       DeepCopy(newSubMenu, subMenu);
  209.       if (dstOff >= 0)
  210.         dst.InsertMenu(dstOff, state|MF_BYPOSITION, newSubMenu, str);
  211.       else
  212.         dst.AppendMenu(state, newSubMenu, str);
  213.     }
  214.     else {
  215.       if (dstOff >= 0)
  216.         dst.InsertMenu(dstOff, state|MF_BYPOSITION, src.GetMenuItemID(srcOff+i), str);
  217.       else
  218.         dst.AppendMenu(state, src.GetMenuItemID(srcOff+i), str);
  219.     }
  220.   }
  221. }
  222.  
  223. TSystemMenu::TSystemMenu(HWND wnd, bool revert)
  224. :
  225.   TMenu(::GetSystemMenu(wnd, revert), NoAutoDelete)
  226. {
  227. }
  228.  
  229. TPopupMenu::TPopupMenu(TAutoDelete autoDelete)
  230. :
  231.   TMenu(::CreatePopupMenu(), autoDelete)
  232. {
  233. }
  234.  
  235. TPopupMenu::TPopupMenu(HMENU handle, TAutoDelete autoDelete)
  236. :
  237.   TMenu(handle, autoDelete)
  238. {
  239. }
  240.  
  241. TMenu::TXMenu::TXMenu(unsigned resId) : TXOwl(resId)
  242. {
  243. }
  244.  
  245. TXOwl*
  246. TMenu::TXMenu::Clone()
  247. {
  248.   return new TXMenu(*this);
  249. }
  250.  
  251. void
  252. TMenu::TXMenu::Throw()
  253. {
  254.   THROW( *this );
  255. }
  256.