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

📄 menu.cpp

📁 很牛的GUI源码wxWidgets-2.8.0.zip 可在多种平台下运行.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////// Name:        src/mac/classic/menu.cpp// Purpose:     wxMenu, wxMenuBar, wxMenuItem// Author:      Stefan Csomor// Modified by:// Created:     1998-01-01// RCS-ID:      $Id: menu.cpp,v 1.15 2006/09/04 23:56:56 VZ Exp $// Copyright:   (c) Stefan Csomor// Licence:     wxWindows licence/////////////////////////////////////////////////////////////////////////////// ============================================================================// headers & declarations// ============================================================================// wxWidgets headers// -----------------#include "wx/wxprec.h"#include "wx/menu.h"#ifndef WX_PRECOMP    #include "wx/log.h"    #include "wx/app.h"    #include "wx/utils.h"    #include "wx/window.h"    #include "wx/frame.h"    #include "wx/menuitem.h"#endif#include "wx/mac/uma.h"// other standard headers// ----------------------#include <string.h>IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler)IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler)// the (popup) menu title has this special idstatic const int idMenuTitle = -2;static MenuItemIndex firstUserHelpMenuItem = 0 ;const short kwxMacMenuBarResource = 1 ;const short kwxMacAppleMenuId = 1 ;// ============================================================================// implementation// ============================================================================static void wxMenubarUnsetInvokingWindow( wxMenu *menu ) ;static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win );// Menus// Construct a menu with optional title (then use append)#ifdef __DARWIN__short wxMenu::s_macNextMenuId = 3 ;#elseshort wxMenu::s_macNextMenuId = 2 ;#endifvoid wxMenu::Init(){    m_doBreak = false;    m_startRadioGroup = -1;    // create the menu    m_macMenuId = s_macNextMenuId++;    m_hMenu = UMANewMenu(m_macMenuId, m_title, wxFont::GetDefaultEncoding() );    if ( !m_hMenu )    {        wxLogLastError(wxT("UMANewMenu failed"));    }    // if we have a title, insert it in the beginning of the menu    if ( !m_title.empty() )    {        Append(idMenuTitle, m_title) ;        AppendSeparator() ;    }}wxMenu::~wxMenu(){    if (MAC_WXHMENU(m_hMenu))        ::DisposeMenu(MAC_WXHMENU(m_hMenu));}void wxMenu::Break(){    // not available on the mac platform}void wxMenu::Attach(wxMenuBarBase *menubar){    wxMenuBase::Attach(menubar);    EndRadioGroup();}// function appends a new item or submenu to the menu// append a new item or submenu to the menubool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos){    wxASSERT_MSG( pItem != NULL, wxT("can't append NULL item to the menu") );    if ( pItem->IsSeparator() )    {        if ( pos == (size_t)-1 )            MacAppendMenu(MAC_WXHMENU(m_hMenu), "\p-");        else            MacInsertMenuItem(MAC_WXHMENU(m_hMenu), "\p-" , pos);    }    else    {        wxMenu *pSubMenu = pItem->GetSubMenu() ;        if ( pSubMenu != NULL )        {               wxASSERT_MSG( pSubMenu->m_hMenu != NULL , wxT("invalid submenu added"));            pSubMenu->m_menuParent = this ;            if (wxMenuBar::MacGetInstalledMenuBar() == GetMenuBar())            {                pSubMenu->MacBeforeDisplay( true ) ;             }            if ( pos == (size_t)-1 )                UMAAppendSubMenuItem(MAC_WXHMENU(m_hMenu), pItem->GetText(), wxFont::GetDefaultEncoding() , pSubMenu->m_macMenuId);            else                UMAInsertSubMenuItem(MAC_WXHMENU(m_hMenu), pItem->GetText(), wxFont::GetDefaultEncoding()  , pos, pSubMenu->m_macMenuId);            pItem->UpdateItemBitmap() ;            pItem->UpdateItemStatus() ;        }        else        {            if ( pos == (size_t)-1 )            {                UMAAppendMenuItem(MAC_WXHMENU(m_hMenu), wxT("a") , wxFont::GetDefaultEncoding() );                pos = CountMenuItems(MAC_WXHMENU(m_hMenu)) ;            }            else            {                // MacOS counts menu items from 1 and inserts after, therefore having the                // same effect as wx 0 based and inserting before, we must correct pos                // after however for updates to be correct                UMAInsertMenuItem(MAC_WXHMENU(m_hMenu), wxT("a"), wxFont::GetDefaultEncoding(), pos);                pos += 1 ;            }            SetMenuItemCommandID( MAC_WXHMENU(m_hMenu) , pos , pItem->GetId() ) ;            pItem->UpdateItemText() ;            pItem->UpdateItemBitmap() ;            pItem->UpdateItemStatus() ;              if ( pItem->GetId() == idMenuTitle )              {                UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , pos , false ) ;              }        }    }    // if we're already attached to the menubar, we must update it    if ( IsAttached() )    {        GetMenuBar()->Refresh();    }    return true ;}void wxMenu::EndRadioGroup(){    // we're not inside a radio group any longer    m_startRadioGroup = -1;}wxMenuItem* wxMenu::DoAppend(wxMenuItem *item){    wxCHECK_MSG( item, NULL, _T("NULL item in wxMenu::DoAppend") );    bool check = false;    if ( item->GetKind() == wxITEM_RADIO )    {        int count = GetMenuItemCount();        if ( m_startRadioGroup == -1 )        {            // start a new radio group            m_startRadioGroup = count;            // for now it has just one element            item->SetAsRadioGroupStart();            item->SetRadioGroupEnd(m_startRadioGroup);            // ensure that we have a checked item in the radio group            check = true;        }        else // extend the current radio group        {            // we need to update its end item            item->SetRadioGroupStart(m_startRadioGroup);            wxMenuItemList::Node *node = GetMenuItems().Item(m_startRadioGroup);            if ( node )            {                node->GetData()->SetRadioGroupEnd(count);            }            else            {                wxFAIL_MSG( _T("where is the radio group start item?") );            }        }    }    else // not a radio item    {        EndRadioGroup();    }    if ( !wxMenuBase::DoAppend(item) || !DoInsertOrAppend(item) )    {        return NULL;    }    if ( check )    {        // check the item initially        item->Check(true);    }    return item;}wxMenuItem* wxMenu::DoInsert(size_t pos, wxMenuItem *item){    if (wxMenuBase::DoInsert(pos, item) && DoInsertOrAppend(item, pos))        return item;    else        return NULL;}wxMenuItem *wxMenu::DoRemove(wxMenuItem *item){    // we need to find the items position in the child list    size_t pos;    wxMenuItemList::Node *node = GetMenuItems().GetFirst();    for ( pos = 0; node; pos++ )    {        if ( node->GetData() == item )            break;        node = node->GetNext();    }    // DoRemove() (unlike Remove) can only be called for existing item!    wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );    ::DeleteMenuItem(MAC_WXHMENU(m_hMenu) , pos + 1);    if ( IsAttached() )    {        // otherwise, the change won't be visible        GetMenuBar()->Refresh();    }    // and from internal data structures    return wxMenuBase::DoRemove(item);}void wxMenu::SetTitle(const wxString& label){       m_title = label ;    UMASetMenuTitle(MAC_WXHMENU(m_hMenu) , label , wxFont::GetDefaultEncoding() ) ;}bool wxMenu::ProcessCommand(wxCommandEvent & event){    bool processed = false;    // Try the menu's event handler    if ( !processed && GetEventHandler())    {        processed = GetEventHandler()->ProcessEvent(event);    }    // Try the window the menu was popped up from (and up through the    // hierarchy)    wxWindow *win = GetInvokingWindow();    if ( !processed && win )        processed = win->GetEventHandler()->ProcessEvent(event);    return processed;}// ---------------------------------------------------------------------------// other// ---------------------------------------------------------------------------wxWindow *wxMenu::GetWindow() const{    if ( m_invokingWindow != NULL )        return m_invokingWindow;    else if ( GetMenuBar() != NULL)        return (wxWindow *) GetMenuBar()->GetFrame();    return NULL;}// helper functions returning the mac menu position for a certain item, note that this is// mac-wise 1 - based, i.e. the first item has index 1 whereas on MSWin it has pos 0int wxMenu::MacGetIndexFromId( int id ){    size_t pos;    wxMenuItemList::Node *node = GetMenuItems().GetFirst();    for ( pos = 0; node; pos++ )    {        if ( node->GetData()->GetId() == id )            break;        node = node->GetNext();    }    if (!node)        return 0;    return pos + 1 ;}int wxMenu::MacGetIndexFromItem( wxMenuItem *pItem ){    size_t pos;    wxMenuItemList::Node *node = GetMenuItems().GetFirst();    for ( pos = 0; node; pos++ )    {        if ( node->GetData() == pItem )            break;        node = node->GetNext();    }    if (!node)        return 0;    return pos + 1 ;}void wxMenu::MacEnableMenu( bool bDoEnable ){    UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , 0 , bDoEnable ) ;    ::DrawMenuBar() ;}// MacOS needs to know about submenus somewhere within this menu// before it can be displayed , also hide special menu items like preferences// that are handled by the OSvoid wxMenu::MacBeforeDisplay( bool isSubMenu ){    wxMenuItem* previousItem = NULL ;    size_t pos ;    wxMenuItemList::Node *node;    wxMenuItem *item;    for (pos = 0, node = GetMenuItems().GetFirst(); node; node = node->GetNext(), pos++)    {        item = (wxMenuItem *)node->GetData();        wxMenu* subMenu = item->GetSubMenu() ;        if (subMenu)        {            subMenu->MacBeforeDisplay( true ) ;        }        else        {            #if TARGET_CARBON            if ( UMAGetSystemVersion() >= 0x1000 )            {                if ( item->GetId() == wxApp::s_macPreferencesMenuItemId || item->GetId() == wxApp::s_macExitMenuItemId)                {                    ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ) , pos + 1, kMenuItemAttrHidden, 0 );                    if ( GetMenuItems().GetCount() == pos + 1 &&                            previousItem != NULL &&                                previousItem->IsSeparator() )                    {                        ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ) , pos , kMenuItemAttrHidden, 0 );                    }                }            }            #endif        }        previousItem = item ;    }    if ( isSubMenu )        ::InsertMenu(MAC_WXHMENU( GetHMenu()), -1);}// undo all changes from the MacBeforeDisplay callvoid wxMenu::MacAfterDisplay( bool isSubMenu ){    if ( isSubMenu )        ::DeleteMenu(MacGetMenuId());    wxMenuItem* previousItem = NULL ;    int pos ;    wxMenuItemList::Node *node;    wxMenuItem *item;    for (pos = 0, node = GetMenuItems().GetFirst(); node; node = node->GetNext(), pos++)    {        item = (wxMenuItem *)node->GetData();        wxMenu* subMenu = item->GetSubMenu() ;        if (subMenu)        {            subMenu->MacAfterDisplay( true ) ;        }        else        {            // no need to undo hidings        }        previousItem = item ;    }}// Menu Bar/*Mac Implementation note :The Mac has only one global menubar, so we attempt to install the currentlyactive menubar from a frame, we currently don't take into account mdi-frameswhich would ask for menu-mergingSecondly there is no mac api for changing a menubar that is not the currentmenubar, so we have to wait for preparing the actual menubar until thewxMenubar is to be usedWe can in subsequent versions use MacInstallMenuBar to provide some sort ofauto-merge for MDI in case this will be necessary

⌨️ 快捷键说明

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