menu.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:9k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * menu.cxx
  3.  *
  4.  * Menu handling classes.
  5.  *
  6.  * Portable Windows Library
  7.  *
  8.  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
  9.  *
  10.  * The contents of this file are subject to the Mozilla Public License
  11.  * Version 1.0 (the "License"); you may not use this file except in
  12.  * compliance with the License. You may obtain a copy of the License at
  13.  * http://www.mozilla.org/MPL/
  14.  *
  15.  * Software distributed under the License is distributed on an "AS IS"
  16.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  17.  * the License for the specific language governing rights and limitations
  18.  * under the License.
  19.  *
  20.  * The Original Code is Portable Windows Library.
  21.  *
  22.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  23.  *
  24.  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
  25.  * All Rights Reserved.
  26.  *
  27.  * Contributor(s): ______________________________________.
  28.  *
  29.  * $Log: menu.cxx,v $
  30.  * Revision 1.26  1999/08/17 03:46:42  robertj
  31.  * Fixed usage of inlines in optimised version.
  32.  *
  33.  * Revision 1.25  1999/08/07 06:51:49  robertj
  34.  * Fixed problem with menu item stopping working on calling SetString().
  35.  *
  36.  * Revision 1.24  1998/12/16 13:00:35  robertj
  37.  * Moved function from common code.
  38.  *
  39.  * Revision 1.23  1998/11/30 05:38:54  robertj
  40.  * Added missing implementation of RedrawMenu().
  41.  *
  42.  * Revision 1.22  1998/10/16 02:08:07  robertj
  43.  * Fixed problem with changing first tier menus when have maximised MDI child.
  44.  *
  45.  * Revision 1.21  1998/09/24 03:42:50  robertj
  46.  * Added open software license.
  47.  *
  48.  * Revision 1.20  1997/04/27 05:50:33  robertj
  49.  * DLL support.
  50.  *
  51.  * Revision 1.19  1996/08/08 10:10:59  robertj
  52.  * Directory structure changes for common files.
  53.  *
  54.  * Revision 1.18  1995/01/27 11:29:27  robertj
  55.  * Fixed numerous bugs.
  56.  * Fixed bug in nested messages.
  57.  * Underscored library variables.
  58.  *
  59.  * Revision 1.17  1994/11/19  00:06:08  robertj
  60.  * Removed variable argument list binding for menus and controls.
  61.  *
  62. // Revision 1.16  1994/10/30  11:47:39  robertj
  63. // Changed mechanism for doing notification callback functions.
  64. //
  65. // Revision 1.15  1994/10/23  06:04:12  robertj
  66. // Shortened OS error assert.
  67. // Fixed problem when changing menus - help menu being splattered.
  68. //
  69. // Revision 1.14  1994/07/27  05:58:07  robertj
  70. // Synchronisation.
  71. //
  72. // Revision 1.13  1994/07/17  10:46:06  robertj
  73. // Enhancements, bug fixes etc.
  74. //
  75. // Revision 1.12  1994/06/25  11:55:15  robertj
  76. // Unix version synchronisation.
  77. //
  78. // Revision 1.11  1994/04/20  12:17:44  robertj
  79. // assert changes
  80. //
  81.  */
  82. #include <pwlib.h>
  83. #if !P_USE_INLINES
  84. #include <pwlib/interact.inl>
  85. #endif
  86. //////////////////////////////////////////////////////////////////////////////
  87. // PMenuEntry
  88. PMenuEntry::~PMenuEntry()
  89. {
  90.   if (itsMenu != NULL) {
  91.     PINDEX pos = GetPosition();
  92.     if (pos != P_MAX_INDEX) {
  93.       if (itsMenu->hMenu != NULL)
  94.         PAssertOS(RemoveMenu(itsMenu->GetHMENU(), pos, MF_BYPOSITION));
  95.       itsMenu->entries.DisallowDeleteObjects();
  96.       itsMenu->entries.Remove(this);
  97.       itsMenu->entries.AllowDeleteObjects();
  98.     }
  99.   }
  100. }
  101. PINDEX PMenuEntry::GetPosition() const
  102. {
  103.   if (itsMenu == NULL)
  104.     return -1;
  105.   PINDEX pos = itsMenu->entries.GetObjectsIndex(this);
  106.   if (pos == P_MAX_INDEX)
  107.     return pos;
  108.   if (!itsMenu->IsDescendant(PRootMenu::Class()))
  109.     return pos;
  110.   // Jump through hoops to allow for a maximised MDI child window.
  111.   PSubMenu & firstEntry = (PSubMenu &)(*itsMenu)[0];
  112.   PAssert(firstEntry.IsDescendant(PSubMenu::Class()), PLogicError);
  113.   if (firstEntry.GetHMENU() != GetSubMenu(itsMenu->GetHMENU(), 0))
  114.     pos++;
  115.   return pos;
  116. }
  117. //////////////////////////////////////////////////////////////////////////////
  118. // PMenuItem
  119. PMenuItem::PMenuItem(PRESOURCE_ID newID, PSubMenu & menu, const PString & str)
  120.   : PMenuEntry(menu, NULL),
  121.     name(str)
  122. {
  123.   menuID = newID;
  124.   Construct(TRUE);
  125. }
  126. void PMenuItem::Construct(BOOL setID)
  127. {
  128.   PRootMenu * root = GetRootMenu();
  129.   if (root != NULL) {
  130.     if (setID) {
  131.       menuID = 1;
  132.       while (root->GetItemFromKey(menuID) != NULL)
  133.         menuID++;
  134.     }
  135.     root->keyedItems.SetAt(menuID, this);
  136.   }
  137.   if (setID)
  138.     PAssertOS(InsertMenu(itsMenu->GetHMENU(),
  139.                         GetPosition(), MF_BYPOSITION|MF_STRING, menuID, name));
  140. }
  141. void PMenuItem::SetString(const PString & str)
  142. {
  143.   PAssert(!str.IsEmpty(), PInvalidParameter);
  144.   name = str;
  145.   ModifyMenu(itsMenu->GetHMENU(), menuID, MF_STRING, menuID, str);
  146. }
  147. void PMenuItem::SetAccelerator(const PKeyCode & accel)
  148. {
  149.   accelerator = accel;
  150. }
  151. //////////////////////////////////////////////////////////////////////////////
  152. PMenuSeparator::PMenuSeparator(PSubMenu & menu, PMenuEntry * before)
  153. : PMenuEntry(menu, before)
  154. {
  155.   PAssertOS(InsertMenu(itsMenu->GetHMENU(),
  156.                          GetPosition(), MF_BYPOSITION|MF_SEPARATOR, 0, NULL));
  157. }
  158. //////////////////////////////////////////////////////////////////////////////
  159. // PSubMenu
  160. PSubMenu::PSubMenu(PSubMenu & menu,
  161.                                const PString & menuTitle, PMenuEntry * before)
  162. : PMenuEntry(menu, before)
  163. {
  164.   hMenu = CreatePopupMenu();
  165.   PAssertNULL(hMenu);
  166.   title = menuTitle;
  167.   PAssertOS(InsertMenu(itsMenu->GetHMENU(),
  168.           GetPosition(), MF_BYPOSITION|MF_POPUP|MF_STRING, (UINT)hMenu,title));
  169. }
  170. PSubMenu::PSubMenu(HMENU hSubMenu, PSubMenu & menu, const char * menuTitle)
  171. : PMenuEntry(menu, NULL)
  172. {
  173.   title = menuTitle;
  174.   hMenu = hSubMenu;
  175.   LoadSubMenu();
  176. }
  177. PSubMenu::~PSubMenu()
  178. {
  179.   entries.RemoveAll();
  180.   DestroyMenu(hMenu);
  181. }
  182. void PSubMenu::SetString(const PString & str)
  183. {
  184.   PAssert(!str.IsEmpty(), PInvalidParameter);
  185.   title = str;
  186.   ModifyMenu(itsMenu->GetHMENU(),
  187.              GetPosition(), MF_BYPOSITION|MF_STRING, (UINT)hMenu, str);
  188. }
  189. void PSubMenu::LoadSubMenu()
  190. {
  191.   for (int i = 0; i < GetMenuItemCount(hMenu); i++) {
  192.     PRESOURCE_ID id = (PRESOURCE_ID)GetMenuItemID(hMenu, i);
  193.     char mTitle[100];
  194.     switch (id) {
  195.       case -1 :
  196.         GetMenuString(hMenu, i, mTitle, sizeof(mTitle), MF_BYPOSITION);
  197.         new PSubMenu(GetSubMenu(hMenu, i), *this, mTitle);
  198.         break;
  199.       case 0 :
  200.         new PMenuSeparator(id, *this);
  201.         break;
  202.       default:
  203.         GetMenuString(hMenu, i, mTitle, sizeof(mTitle), MF_BYPOSITION);
  204.         new PMenuItem(id, *this, mTitle, PKeyCode());
  205.     }
  206.   }
  207. }
  208. //////////////////////////////////////////////////////////////////////////////
  209. // PRootMenu
  210. POrphanSubMenu::POrphanSubMenu(const PString & menuTitle)
  211. {
  212.   hMenu = CreatePopupMenu();
  213.   PAssertNULL(hMenu);
  214.   title = menuTitle;
  215. }
  216. //////////////////////////////////////////////////////////////////////////////
  217. // PRootMenu
  218. PRootMenu::PRootMenu()
  219. {
  220.   keyedItems.DisallowDeleteObjects();
  221.   hMenu = CreateMenu();
  222.   PAssertNULL(hMenu);
  223.   accelerators = NULL;
  224. }
  225.  
  226. PRootMenu::PRootMenu(PRESOURCE_ID resID)
  227. {
  228.   keyedItems.DisallowDeleteObjects();
  229.   hMenu = LoadMenu(PApplication::Current().GetInstance(), MAKEINTRESOURCE(resID));
  230.   PAssertNULL(hMenu);
  231.   LoadSubMenu();
  232.   accelerators = LoadAccelerators(PApplication::Current().GetInstance(),
  233.                                                       MAKEINTRESOURCE(resID));
  234. }
  235. //////////////////////////////////////////////////////////////////////////////
  236. void PTopLevelWindow::SetMenu(PRootMenu * newMenu, BOOL autoDelete)
  237. {
  238.   PAssertOS(::SetMenu(GetHWND(), NULL));
  239.   owner->hAccelerator = NULL;
  240.   if (menu == NULL)
  241.     GetSystemMenu(GetHWND(), TRUE);
  242.   else {
  243.     HMENU hMenu = menu->GetHMENU();
  244.     PAssertOS(RemoveMenu(hMenu, GetMenuItemCount(hMenu)-1, MF_BYPOSITION));
  245.     if (deleteMenu)
  246.       delete menu;
  247.   }
  248.   menu = newMenu;
  249.   deleteMenu = autoDelete;
  250.   if (menu != NULL) {
  251.     HMENU hMenu = menu->GetHMENU();
  252.     PAssertOS(AppendMenu(hMenu,
  253.                   MF_POPUP, (UINT)helpMenu.GetHMENU(), helpMenu.GetString()));
  254.     PAssertOS(::SetMenu(GetHWND(), hMenu));
  255.     owner->hAccelerator = menu->GetHACCEL();
  256.   }
  257.   else {
  258.     HMENU hMenu = GetSystemMenu(_hWnd, FALSE);
  259.     PAssertOS(AppendMenu(hMenu, MF_SEPARATOR, 0, NULL));
  260.     PAssertOS(AppendMenu(hMenu,
  261.               MF_STRING, PSTD_ID_MENU_ABOUT, owner->GetAboutMenuItemString()));
  262.   }
  263.   DrawMenuBar(GetHWND());
  264. }
  265. void PTopLevelWindow::RedrawMenu()
  266. {
  267.   DrawMenuBar(GetHWND());
  268. }
  269. void PMDIFrameWindow::SetMenu(PRootMenu * newMenu, BOOL autoDelete)
  270. {
  271.   if (menu != NULL) {
  272.     HMENU hMenu = menu->GetHMENU();
  273.     PAssertOS(RemoveMenu(hMenu, GetMenuItemCount(hMenu)-2, MF_BYPOSITION));
  274.   }
  275.   
  276.   if (newMenu != NULL)
  277.     PAssertOS(AppendMenu(newMenu->GetHMENU(),
  278.               MF_POPUP, (UINT)windowMenu.GetHMENU(), windowMenu.GetString()));
  279.   PTopLevelWindow::SetMenu(newMenu, autoDelete);
  280. }
  281. // End Of File ///////////////////////////////////////////////////////////////