menu.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:9k
- /*
- * menu.cxx
- *
- * Menu handling classes.
- *
- * Portable Windows Library
- *
- * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Portable Windows Library.
- *
- * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
- *
- * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
- * All Rights Reserved.
- *
- * Contributor(s): ______________________________________.
- *
- * $Log: menu.cxx,v $
- * Revision 1.26 1999/08/17 03:46:42 robertj
- * Fixed usage of inlines in optimised version.
- *
- * Revision 1.25 1999/08/07 06:51:49 robertj
- * Fixed problem with menu item stopping working on calling SetString().
- *
- * Revision 1.24 1998/12/16 13:00:35 robertj
- * Moved function from common code.
- *
- * Revision 1.23 1998/11/30 05:38:54 robertj
- * Added missing implementation of RedrawMenu().
- *
- * Revision 1.22 1998/10/16 02:08:07 robertj
- * Fixed problem with changing first tier menus when have maximised MDI child.
- *
- * Revision 1.21 1998/09/24 03:42:50 robertj
- * Added open software license.
- *
- * Revision 1.20 1997/04/27 05:50:33 robertj
- * DLL support.
- *
- * Revision 1.19 1996/08/08 10:10:59 robertj
- * Directory structure changes for common files.
- *
- * Revision 1.18 1995/01/27 11:29:27 robertj
- * Fixed numerous bugs.
- * Fixed bug in nested messages.
- * Underscored library variables.
- *
- * Revision 1.17 1994/11/19 00:06:08 robertj
- * Removed variable argument list binding for menus and controls.
- *
- // Revision 1.16 1994/10/30 11:47:39 robertj
- // Changed mechanism for doing notification callback functions.
- //
- // Revision 1.15 1994/10/23 06:04:12 robertj
- // Shortened OS error assert.
- // Fixed problem when changing menus - help menu being splattered.
- //
- // Revision 1.14 1994/07/27 05:58:07 robertj
- // Synchronisation.
- //
- // Revision 1.13 1994/07/17 10:46:06 robertj
- // Enhancements, bug fixes etc.
- //
- // Revision 1.12 1994/06/25 11:55:15 robertj
- // Unix version synchronisation.
- //
- // Revision 1.11 1994/04/20 12:17:44 robertj
- // assert changes
- //
- */
- #include <pwlib.h>
- #if !P_USE_INLINES
- #include <pwlib/interact.inl>
- #endif
- //////////////////////////////////////////////////////////////////////////////
- // PMenuEntry
- PMenuEntry::~PMenuEntry()
- {
- if (itsMenu != NULL) {
- PINDEX pos = GetPosition();
- if (pos != P_MAX_INDEX) {
- if (itsMenu->hMenu != NULL)
- PAssertOS(RemoveMenu(itsMenu->GetHMENU(), pos, MF_BYPOSITION));
- itsMenu->entries.DisallowDeleteObjects();
- itsMenu->entries.Remove(this);
- itsMenu->entries.AllowDeleteObjects();
- }
- }
- }
- PINDEX PMenuEntry::GetPosition() const
- {
- if (itsMenu == NULL)
- return -1;
- PINDEX pos = itsMenu->entries.GetObjectsIndex(this);
- if (pos == P_MAX_INDEX)
- return pos;
- if (!itsMenu->IsDescendant(PRootMenu::Class()))
- return pos;
- // Jump through hoops to allow for a maximised MDI child window.
- PSubMenu & firstEntry = (PSubMenu &)(*itsMenu)[0];
- PAssert(firstEntry.IsDescendant(PSubMenu::Class()), PLogicError);
- if (firstEntry.GetHMENU() != GetSubMenu(itsMenu->GetHMENU(), 0))
- pos++;
- return pos;
- }
- //////////////////////////////////////////////////////////////////////////////
- // PMenuItem
- PMenuItem::PMenuItem(PRESOURCE_ID newID, PSubMenu & menu, const PString & str)
- : PMenuEntry(menu, NULL),
- name(str)
- {
- menuID = newID;
- Construct(TRUE);
- }
- void PMenuItem::Construct(BOOL setID)
- {
- PRootMenu * root = GetRootMenu();
- if (root != NULL) {
- if (setID) {
- menuID = 1;
- while (root->GetItemFromKey(menuID) != NULL)
- menuID++;
- }
- root->keyedItems.SetAt(menuID, this);
- }
- if (setID)
- PAssertOS(InsertMenu(itsMenu->GetHMENU(),
- GetPosition(), MF_BYPOSITION|MF_STRING, menuID, name));
- }
- void PMenuItem::SetString(const PString & str)
- {
- PAssert(!str.IsEmpty(), PInvalidParameter);
- name = str;
- ModifyMenu(itsMenu->GetHMENU(), menuID, MF_STRING, menuID, str);
- }
- void PMenuItem::SetAccelerator(const PKeyCode & accel)
- {
- accelerator = accel;
- }
- //////////////////////////////////////////////////////////////////////////////
- PMenuSeparator::PMenuSeparator(PSubMenu & menu, PMenuEntry * before)
- : PMenuEntry(menu, before)
- {
- PAssertOS(InsertMenu(itsMenu->GetHMENU(),
- GetPosition(), MF_BYPOSITION|MF_SEPARATOR, 0, NULL));
- }
- //////////////////////////////////////////////////////////////////////////////
- // PSubMenu
- PSubMenu::PSubMenu(PSubMenu & menu,
- const PString & menuTitle, PMenuEntry * before)
- : PMenuEntry(menu, before)
- {
- hMenu = CreatePopupMenu();
- PAssertNULL(hMenu);
- title = menuTitle;
- PAssertOS(InsertMenu(itsMenu->GetHMENU(),
- GetPosition(), MF_BYPOSITION|MF_POPUP|MF_STRING, (UINT)hMenu,title));
- }
- PSubMenu::PSubMenu(HMENU hSubMenu, PSubMenu & menu, const char * menuTitle)
- : PMenuEntry(menu, NULL)
- {
- title = menuTitle;
- hMenu = hSubMenu;
- LoadSubMenu();
- }
- PSubMenu::~PSubMenu()
- {
- entries.RemoveAll();
- DestroyMenu(hMenu);
- }
- void PSubMenu::SetString(const PString & str)
- {
- PAssert(!str.IsEmpty(), PInvalidParameter);
- title = str;
- ModifyMenu(itsMenu->GetHMENU(),
- GetPosition(), MF_BYPOSITION|MF_STRING, (UINT)hMenu, str);
- }
- void PSubMenu::LoadSubMenu()
- {
- for (int i = 0; i < GetMenuItemCount(hMenu); i++) {
- PRESOURCE_ID id = (PRESOURCE_ID)GetMenuItemID(hMenu, i);
- char mTitle[100];
- switch (id) {
- case -1 :
- GetMenuString(hMenu, i, mTitle, sizeof(mTitle), MF_BYPOSITION);
- new PSubMenu(GetSubMenu(hMenu, i), *this, mTitle);
- break;
- case 0 :
- new PMenuSeparator(id, *this);
- break;
- default:
- GetMenuString(hMenu, i, mTitle, sizeof(mTitle), MF_BYPOSITION);
- new PMenuItem(id, *this, mTitle, PKeyCode());
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- // PRootMenu
- POrphanSubMenu::POrphanSubMenu(const PString & menuTitle)
- {
- hMenu = CreatePopupMenu();
- PAssertNULL(hMenu);
- title = menuTitle;
- }
- //////////////////////////////////////////////////////////////////////////////
- // PRootMenu
- PRootMenu::PRootMenu()
- {
- keyedItems.DisallowDeleteObjects();
- hMenu = CreateMenu();
- PAssertNULL(hMenu);
- accelerators = NULL;
- }
-
- PRootMenu::PRootMenu(PRESOURCE_ID resID)
- {
- keyedItems.DisallowDeleteObjects();
- hMenu = LoadMenu(PApplication::Current().GetInstance(), MAKEINTRESOURCE(resID));
- PAssertNULL(hMenu);
- LoadSubMenu();
- accelerators = LoadAccelerators(PApplication::Current().GetInstance(),
- MAKEINTRESOURCE(resID));
- }
- //////////////////////////////////////////////////////////////////////////////
- void PTopLevelWindow::SetMenu(PRootMenu * newMenu, BOOL autoDelete)
- {
- PAssertOS(::SetMenu(GetHWND(), NULL));
- owner->hAccelerator = NULL;
- if (menu == NULL)
- GetSystemMenu(GetHWND(), TRUE);
- else {
- HMENU hMenu = menu->GetHMENU();
- PAssertOS(RemoveMenu(hMenu, GetMenuItemCount(hMenu)-1, MF_BYPOSITION));
- if (deleteMenu)
- delete menu;
- }
- menu = newMenu;
- deleteMenu = autoDelete;
- if (menu != NULL) {
- HMENU hMenu = menu->GetHMENU();
- PAssertOS(AppendMenu(hMenu,
- MF_POPUP, (UINT)helpMenu.GetHMENU(), helpMenu.GetString()));
- PAssertOS(::SetMenu(GetHWND(), hMenu));
- owner->hAccelerator = menu->GetHACCEL();
- }
- else {
- HMENU hMenu = GetSystemMenu(_hWnd, FALSE);
- PAssertOS(AppendMenu(hMenu, MF_SEPARATOR, 0, NULL));
- PAssertOS(AppendMenu(hMenu,
- MF_STRING, PSTD_ID_MENU_ABOUT, owner->GetAboutMenuItemString()));
- }
- DrawMenuBar(GetHWND());
- }
- void PTopLevelWindow::RedrawMenu()
- {
- DrawMenuBar(GetHWND());
- }
- void PMDIFrameWindow::SetMenu(PRootMenu * newMenu, BOOL autoDelete)
- {
- if (menu != NULL) {
- HMENU hMenu = menu->GetHMENU();
- PAssertOS(RemoveMenu(hMenu, GetMenuItemCount(hMenu)-2, MF_BYPOSITION));
- }
-
- if (newMenu != NULL)
- PAssertOS(AppendMenu(newMenu->GetHMENU(),
- MF_POPUP, (UINT)windowMenu.GetHMENU(), windowMenu.GetString()));
- PTopLevelWindow::SetMenu(newMenu, autoDelete);
- }
- // End Of File ///////////////////////////////////////////////////////////////