⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 menu.cxx

📁 windows mobile phone source code
💻 CXX
字号:
/*
 * 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 ///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -