1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxMenu, wxMenuBar, wxMenuItem 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:       wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "menu.h" 
  14 #pragma implementation "menuitem.h" 
  17 // ============================================================================ 
  18 // headers & declarations 
  19 // ============================================================================ 
  26 #include "wx/menuitem.h" 
  27 #include "wx/window.h" 
  32 #include "wx/mac/uma.h" 
  34 // other standard headers 
  35 // ---------------------- 
  38 #if !USE_SHARED_LIBRARY 
  39 IMPLEMENT_DYNAMIC_CLASS(wxMenu
, wxEvtHandler
) 
  40 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
, wxEvtHandler
) 
  43 // the (popup) menu title has this special id 
  44 static const int idMenuTitle 
= -2; 
  45 static MenuItemIndex firstUserHelpMenuItem 
= 0 ; 
  47 const short kwxMacMenuBarResource 
= 1 ; 
  48 const short kwxMacAppleMenuId 
= 1 ; 
  50 // ============================================================================ 
  52 // ============================================================================ 
  53 static void wxMenubarUnsetInvokingWindow( wxMenu 
*menu 
) ; 
  54 static void wxMenubarSetInvokingWindow( wxMenu 
*menu
, wxWindow 
*win 
); 
  58 // Construct a menu with optional title (then use append) 
  61 short wxMenu::s_macNextMenuId 
= 3 ; 
  63 short wxMenu::s_macNextMenuId 
= 2 ; 
  69     m_startRadioGroup 
= -1; 
  72     m_macMenuId 
= s_macNextMenuId
++; 
  73     m_hMenu 
= UMANewMenu(m_macMenuId
, m_title
); 
  77         wxLogLastError("UMANewMenu failed"); 
  80     // if we have a title, insert it in the beginning of the menu 
  83         Append(idMenuTitle
, m_title
) ; 
  90     if (MAC_WXHMENU(m_hMenu
)) 
  91         ::DisposeMenu(MAC_WXHMENU(m_hMenu
)); 
  96     // not available on the mac platform 
  99 void wxMenu::Attach(wxMenuBarBase 
*menubar
) 
 101     wxMenuBase::Attach(menubar
); 
 106 // function appends a new item or submenu to the menu 
 107 // append a new item or submenu to the menu 
 108 bool wxMenu::DoInsertOrAppend(wxMenuItem 
*pItem
, size_t pos
) 
 110     wxASSERT_MSG( pItem 
!= NULL
, wxT("can't append NULL item to the menu") ); 
 112     if ( pItem
->IsSeparator() ) 
 114         if ( pos 
== (size_t)-1 ) 
 115             MacAppendMenu(MAC_WXHMENU(m_hMenu
), "\p-"); 
 117             MacInsertMenuItem(MAC_WXHMENU(m_hMenu
), "\p-" , pos
); 
 121         wxMenu 
*pSubMenu 
= pItem
->GetSubMenu() ; 
 122         if ( pSubMenu 
!= NULL 
) 
 124                wxASSERT_MSG( pSubMenu
->m_hMenu 
!= NULL 
, wxT("invalid submenu added")); 
 125             pSubMenu
->m_menuParent 
= this ; 
 127             if (wxMenuBar::MacGetInstalledMenuBar() == m_menuBar
) 
 129                 pSubMenu
->MacBeforeDisplay( true ) ; 
 132             if ( pos 
== (size_t)-1 ) 
 133                 UMAAppendSubMenuItem(MAC_WXHMENU(m_hMenu
), pItem
->GetText(), pSubMenu
->m_macMenuId
); 
 135                 UMAInsertSubMenuItem(MAC_WXHMENU(m_hMenu
), pItem
->GetText() , pos
, pSubMenu
->m_macMenuId
); 
 136             pItem
->UpdateItemBitmap() ; 
 137             pItem
->UpdateItemStatus() ; 
 141             if ( pos 
== (size_t)-1 ) 
 143                 UMAAppendMenuItem(MAC_WXHMENU(m_hMenu
), wxT("a") ); 
 144                 pos 
= CountMenuItems(MAC_WXHMENU(m_hMenu
)) ; 
 148                 // MacOS counts menu items from 1 and inserts after, therefore having the 
 149                 // same effect as wx 0 based and inserting before, we must correct pos 
 150                 // after however for updates to be correct 
 151                 UMAInsertMenuItem(MAC_WXHMENU(m_hMenu
), wxT("a") , pos
); 
 155             SetMenuItemCommandID( MAC_WXHMENU(m_hMenu
) , pos 
, pItem
->GetId() ) ; 
 156             pItem
->UpdateItemText() ; 
 157             pItem
->UpdateItemBitmap() ; 
 158             pItem
->UpdateItemStatus() ; 
 160               if ( pItem
->GetId() == idMenuTitle 
) 
 162                 UMAEnableMenuItem(MAC_WXHMENU(m_hMenu
) , pos 
, false ) ; 
 166     // if we're already attached to the menubar, we must update it 
 169         m_menuBar
->Refresh(); 
 174 void wxMenu::EndRadioGroup() 
 176     // we're not inside a radio group any longer 
 177     m_startRadioGroup 
= -1; 
 180 bool wxMenu::DoAppend(wxMenuItem 
*item
) 
 182     wxCHECK_MSG( item
, FALSE
, _T("NULL item in wxMenu::DoAppend") ); 
 186     if ( item
->GetKind() == wxITEM_RADIO 
) 
 188         int count 
= GetMenuItemCount(); 
 190         if ( m_startRadioGroup 
== -1 ) 
 192             // start a new radio group 
 193             m_startRadioGroup 
= count
; 
 195             // for now it has just one element 
 196             item
->SetAsRadioGroupStart(); 
 197             item
->SetRadioGroupEnd(m_startRadioGroup
); 
 199             // ensure that we have a checked item in the radio group 
 202         else // extend the current radio group 
 204             // we need to update its end item 
 205             item
->SetRadioGroupStart(m_startRadioGroup
); 
 206             wxMenuItemList::Node 
*node 
= GetMenuItems().Item(m_startRadioGroup
); 
 210                 node
->GetData()->SetRadioGroupEnd(count
); 
 214                 wxFAIL_MSG( _T("where is the radio group start item?") ); 
 218     else // not a radio item 
 223     if ( !wxMenuBase::DoAppend(item
) || !DoInsertOrAppend(item
) ) 
 230         // check the item initially 
 237 bool wxMenu::DoInsert(size_t pos
, wxMenuItem 
*item
) 
 239     return wxMenuBase::DoInsert(pos
, item
) && DoInsertOrAppend(item
, pos
); 
 242 wxMenuItem 
*wxMenu::DoRemove(wxMenuItem 
*item
) 
 244     // we need to find the items position in the child list 
 246     wxMenuItemList::Node 
*node 
= GetMenuItems().GetFirst(); 
 247     for ( pos 
= 0; node
; pos
++ ) 
 249         if ( node
->GetData() == item 
) 
 252         node 
= node
->GetNext(); 
 255     // DoRemove() (unlike Remove) can only be called for existing item! 
 256     wxCHECK_MSG( node
, NULL
, wxT("bug in wxMenu::Remove logic") ); 
 258     ::DeleteMenuItem(MAC_WXHMENU(m_hMenu
) , pos 
+ 1); 
 262         // otherwise, the change won't be visible 
 263         m_menuBar
->Refresh(); 
 266     // and from internal data structures 
 267     return wxMenuBase::DoRemove(item
); 
 270 void wxMenu::SetTitle(const wxString
& label
) 
 273     UMASetMenuTitle(MAC_WXHMENU(m_hMenu
) , label 
) ; 
 275 bool wxMenu::ProcessCommand(wxCommandEvent 
& event
) 
 277     bool processed 
= FALSE
; 
 279 #if WXWIN_COMPATIBILITY 
 283         (void)(*(m_callback
))(*this, event
); 
 286 #endif WXWIN_COMPATIBILITY 
 288     // Try the menu's event handler 
 289     if ( !processed 
&& GetEventHandler()) 
 291         processed 
= GetEventHandler()->ProcessEvent(event
); 
 294     // Try the window the menu was popped up from (and up through the 
 296     wxWindow 
*win 
= GetInvokingWindow(); 
 297     if ( !processed 
&& win 
) 
 298         processed 
= win
->GetEventHandler()->ProcessEvent(event
); 
 304 // --------------------------------------------------------------------------- 
 306 // --------------------------------------------------------------------------- 
 308 wxWindow 
*wxMenu::GetWindow() const 
 310     if ( m_invokingWindow 
!= NULL 
) 
 311         return m_invokingWindow
; 
 312     else if ( m_menuBar 
!= NULL
) 
 313         return (wxWindow 
*) m_menuBar
->GetFrame(); 
 318 // helper functions returning the mac menu position for a certain item, note that this is 
 319 // mac-wise 1 - based, i.e. the first item has index 1 whereas on MSWin it has pos 0 
 321 int wxMenu::MacGetIndexFromId( int id 
) 
 324     wxMenuItemList::Node 
*node 
= GetMenuItems().GetFirst(); 
 325     for ( pos 
= 0; node
; pos
++ ) 
 327         if ( node
->GetData()->GetId() == id 
) 
 330         node 
= node
->GetNext(); 
 339 int wxMenu::MacGetIndexFromItem( wxMenuItem 
*pItem 
) 
 342     wxMenuItemList::Node 
*node 
= GetMenuItems().GetFirst(); 
 343     for ( pos 
= 0; node
; pos
++ ) 
 345         if ( node
->GetData() == pItem 
) 
 348         node 
= node
->GetNext(); 
 357 void wxMenu::MacEnableMenu( bool bDoEnable 
) 
 359     UMAEnableMenuItem(MAC_WXHMENU(m_hMenu
) , 0 , bDoEnable 
) ; 
 364 // MacOS needs to know about submenus somewhere within this menu 
 365 // before it can be displayed , also hide special menu items like preferences 
 366 // that are handled by the OS 
 367 void wxMenu::MacBeforeDisplay( bool isSubMenu 
) 
 369     wxMenuItem
* previousItem 
= NULL 
; 
 371     wxMenuItemList::Node 
*node
; 
 373     for (pos 
= 0, node 
= GetMenuItems().GetFirst(); node
; node 
= node
->GetNext(), pos
++) 
 375         item 
= (wxMenuItem 
*)node
->GetData(); 
 376         wxMenu
* subMenu 
= item
->GetSubMenu() ; 
 379             subMenu
->MacBeforeDisplay( true ) ; 
 384             if ( UMAGetSystemVersion() >= 0x1000 ) 
 386                 if ( item
->GetId() == wxApp::s_macPreferencesMenuItemId 
|| item
->GetId() == wxApp::s_macExitMenuItemId
) 
 388                     ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ) , pos 
+ 1, kMenuItemAttrHidden
, 0 ); 
 389                     if ( GetMenuItems().GetCount() == pos 
+ 1 && 
 390                             previousItem 
!= NULL 
&& 
 391                                 previousItem
->IsSeparator() ) 
 393                         ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ) , pos 
, kMenuItemAttrHidden
, 0 ); 
 399         previousItem 
= item 
; 
 403         ::InsertMenu(MAC_WXHMENU( GetHMenu()), -1); 
 406 // undo all changes from the MacBeforeDisplay call 
 407 void wxMenu::MacAfterDisplay( bool isSubMenu 
) 
 410         ::DeleteMenu(MacGetMenuId()); 
 412     wxMenuItem
* previousItem 
= NULL 
; 
 414     wxMenuItemList::Node 
*node
; 
 416     for (pos 
= 0, node 
= GetMenuItems().GetFirst(); node
; node 
= node
->GetNext(), pos
++) 
 418         item 
= (wxMenuItem 
*)node
->GetData(); 
 419         wxMenu
* subMenu 
= item
->GetSubMenu() ; 
 422             subMenu
->MacAfterDisplay( true ) ; 
 426             // no need to undo hidings 
 428         previousItem 
= item 
; 
 436 Mac Implementation note : 
 438 The Mac has only one global menubar, so we attempt to install the currently 
 439 active menubar from a frame, we currently don't take into account mdi-frames 
 440 which would ask for menu-merging 
 442 Secondly there is no mac api for changing a menubar that is not the current 
 443 menubar, so we have to wait for preparing the actual menubar until the 
 444 wxMenubar is to be used 
 446 We can in subsequent versions use MacInstallMenuBar to provide some sort of 
 447 auto-merge for MDI in case this will be necessary 
 451 wxMenuBar
* wxMenuBar::s_macInstalledMenuBar 
= NULL 
; 
 452 wxMenuBar
* wxMenuBar::s_macCommonMenuBar 
= NULL 
; 
 454 void wxMenuBar::Init() 
 456     m_eventHandler 
= this; 
 457     m_menuBarFrame 
= NULL
; 
 458     m_invokingWindow 
= (wxWindow
*) NULL
; 
 461 wxMenuBar::wxMenuBar() 
 466 wxMenuBar::wxMenuBar( long WXUNUSED(style
) ) 
 472 wxMenuBar::wxMenuBar(int count
, wxMenu 
*menus
[], const wxString titles
[]) 
 476     m_titles
.Alloc(count
); 
 478     for ( int i 
= 0; i 
< count
; i
++ ) 
 480         m_menus
.Append(menus
[i
]); 
 481         m_titles
.Add(titles
[i
]); 
 483         menus
[i
]->Attach(this); 
 487 wxMenuBar::~wxMenuBar() 
 489     if (s_macCommonMenuBar 
== this) 
 490         s_macCommonMenuBar 
= NULL
; 
 491     if (s_macInstalledMenuBar 
== this) 
 494         s_macInstalledMenuBar 
= NULL
; 
 499 void wxMenuBar::Refresh(bool WXUNUSED(eraseBackground
), const wxRect 
*WXUNUSED(rect
)) 
 501     wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") ); 
 506 void wxMenuBar::MacInstallMenuBar() 
 508     if ( s_macInstalledMenuBar 
== this ) 
 511     wxStAppResource resload 
; 
 513     Handle menubar 
= ::GetNewMBar( kwxMacMenuBarResource 
) ; 
 515     wxCHECK_RET( menubar 
!= NULL
, wxT("can't read MBAR resource") ); 
 516     ::SetMenuBar( menubar 
) ; 
 517 #if TARGET_API_MAC_CARBON 
 518     ::DisposeMenuBar( menubar 
) ; 
 520     ::DisposeHandle( menubar 
) ; 
 523 #if TARGET_API_MAC_OS8 
 524     MenuHandle menu 
= ::GetMenuHandle( kwxMacAppleMenuId 
) ; 
 525     if ( CountMenuItems( menu 
) == 2 ) 
 527         ::AppendResMenu(menu
, 'DRVR'); 
 531     // clean-up the help menu before adding new items 
 532     MenuHandle mh 
= NULL 
; 
 533     if ( UMAGetHelpMenu( &mh 
, &firstUserHelpMenuItem
) == noErr 
) 
 535         for ( int i 
= CountMenuItems( mh 
) ; i 
>= firstUserHelpMenuItem 
; --i 
) 
 537             DeleteMenuItem( mh 
, i 
) ; 
 545     if ( UMAGetSystemVersion() >= 0x1000 && wxApp::s_macPreferencesMenuItemId
) 
 547         wxMenuItem 
*item 
= FindItem( wxApp::s_macPreferencesMenuItemId 
, NULL 
) ; 
 548         if ( item 
== NULL 
|| !(item
->IsEnabled()) ) 
 549             DisableMenuCommand( NULL 
, kHICommandPreferences 
) ; 
 551             EnableMenuCommand( NULL 
, kHICommandPreferences 
) ; 
 554        for (size_t i 
= 0; i 
< m_menus
.GetCount(); i
++) 
 556         wxMenuItemList::Node 
*node
; 
 559         wxMenu
* menu 
= m_menus
[i
] , *subMenu 
= NULL 
; 
 561         if( m_titles
[i
] == wxT("?") || m_titles
[i
] == wxT("&?")  || m_titles
[i
] == wxApp::s_macHelpMenuTitleName 
) 
 568               for (pos 
= 0 , node 
= menu
->GetMenuItems().GetFirst(); node
; node 
= node
->GetNext(), pos
++) 
 570                  item 
= (wxMenuItem 
*)node
->GetData(); 
 571                  subMenu 
= item
->GetSubMenu() ; 
 574                     // we don't support hierarchical menus in the help menu yet 
 578                     if ( item
->IsSeparator() ) 
 581                             MacAppendMenu(mh
, "\p-" ); 
 585                         wxAcceleratorEntry
* entry 
= wxGetAccelFromString( item
->GetText() ) ; 
 587                         if ( item
->GetId() == wxApp::s_macAboutMenuItemId 
) 
 589                                 UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId 
) , 1 , item
->GetText()  ); 
 590                                 UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId 
) , 1 , true ); 
 591                                 SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId 
) , 1 , item
->GetId() ) ; 
 592                                 UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId 
) , 1 , entry 
) ; 
 598                                 UMAAppendMenuItem(mh
, item
->GetText()  , entry 
); 
 599                                 SetMenuItemCommandID( mh 
, CountMenuItems(mh
) , item
->GetId() ) ; 
 610             UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , m_titles
[i
] ) ; 
 611             m_menus
[i
]->MacBeforeDisplay(false) ; 
 612             ::InsertMenu(MAC_WXHMENU(m_menus
[i
]->GetHMenu()), 0); 
 616     s_macInstalledMenuBar 
= this; 
 619 void wxMenuBar::EnableTop(size_t pos
, bool enable
) 
 621     wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") ); 
 622     m_menus
[pos
]->MacEnableMenu( enable 
) ; 
 626 void wxMenuBar::SetLabelTop(size_t pos
, const wxString
& label
) 
 628     wxCHECK_RET( pos 
< GetMenuCount(), wxT("invalid menu index") ); 
 630     m_titles
[pos
] = label
; 
 637     m_menus
[pos
]->SetTitle( label 
) ; 
 638     if (wxMenuBar::s_macInstalledMenuBar 
== this) // are we currently installed ? 
 640         ::SetMenuBar( GetMenuBar() ) ; 
 645 wxString 
wxMenuBar::GetLabelTop(size_t pos
) const 
 647     wxCHECK_MSG( pos 
< GetMenuCount(), wxEmptyString
, 
 648                  wxT("invalid menu index in wxMenuBar::GetLabelTop") ); 
 650     return m_titles
[pos
]; 
 653 int wxMenuBar::FindMenu(const wxString
& title
) 
 655     wxString menuTitle 
= wxStripMenuCodes(title
); 
 657     size_t count 
= GetMenuCount(); 
 658     for ( size_t i 
= 0; i 
< count
; i
++ ) 
 660         wxString title 
= wxStripMenuCodes(m_titles
[i
]); 
 661         if ( menuTitle 
== title 
) 
 670 // --------------------------------------------------------------------------- 
 671 // wxMenuBar construction 
 672 // --------------------------------------------------------------------------- 
 674 // --------------------------------------------------------------------------- 
 675 // wxMenuBar construction 
 676 // --------------------------------------------------------------------------- 
 678 wxMenu 
*wxMenuBar::Replace(size_t pos
, wxMenu 
*menu
, const wxString
& title
) 
 680     wxMenu 
*menuOld 
= wxMenuBarBase::Replace(pos
, menu
, title
); 
 683     m_titles
[pos
] = title
; 
 687         if (s_macInstalledMenuBar 
== this) 
 689             menuOld
->MacAfterDisplay( false ) ; 
 690             ::DeleteMenu( menuOld
->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ; 
 692                 menu
->MacBeforeDisplay( false ) ; 
 693                 UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , title 
) ; 
 694                 if ( pos 
== m_menus
.GetCount() - 1) 
 696                     ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , 0 ) ; 
 700                     ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , m_menus
[pos
+1]->MacGetMenuId() ) ; 
 711 bool wxMenuBar::Insert(size_t pos
, wxMenu 
*menu
, const wxString
& title
) 
 713     if ( !wxMenuBarBase::Insert(pos
, menu
, title
) ) 
 716     m_titles
.Insert(title
, pos
); 
 718     UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , title 
) ; 
 720     if ( IsAttached() && s_macInstalledMenuBar 
== this ) 
 722         if (s_macInstalledMenuBar 
== this) 
 724             menu
->MacBeforeDisplay( false ) ; 
 725             if ( pos 
== (size_t) -1  || pos 
+ 1 == m_menus
.GetCount() ) 
 727                 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , 0 ) ; 
 731                 ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , m_menus
[pos
+1]->MacGetMenuId() ) ; 
 740 wxMenu 
*wxMenuBar::Remove(size_t pos
) 
 742     wxMenu 
*menu 
= wxMenuBarBase::Remove(pos
); 
 748         if (s_macInstalledMenuBar 
== this) 
 750             ::DeleteMenu( menu
->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ; 
 758     m_titles
.RemoveAt(pos
); 
 763 bool wxMenuBar::Append(wxMenu 
*menu
, const wxString
& title
) 
 765     WXHMENU submenu 
= menu 
? menu
->GetHMenu() : 0; 
 766     wxCHECK_MSG( submenu
, FALSE
, wxT("can't append invalid menu to menubar") ); 
 768     if ( !wxMenuBarBase::Append(menu
, title
) ) 
 773     UMASetMenuTitle( MAC_WXHMENU(menu
->GetHMenu()) , title 
) ; 
 777         if (s_macInstalledMenuBar 
== this) 
 779             ::InsertMenu( MAC_WXHMENU(menu
->GetHMenu()) , 0 ) ; 
 785    // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables 
 786     // adding menu later on. 
 787     if (m_invokingWindow
) 
 788         wxMenubarSetInvokingWindow( menu
, m_invokingWindow 
); 
 793 static void wxMenubarUnsetInvokingWindow( wxMenu 
*menu 
) 
 795     menu
->SetInvokingWindow( (wxWindow
*) NULL 
); 
 797     wxMenuItemList::Node 
*node 
= menu
->GetMenuItems().GetFirst(); 
 800         wxMenuItem 
*menuitem 
= node
->GetData(); 
 801         if (menuitem
->IsSubMenu()) 
 802             wxMenubarUnsetInvokingWindow( menuitem
->GetSubMenu() ); 
 803         node 
= node
->GetNext(); 
 807 static void wxMenubarSetInvokingWindow( wxMenu 
*menu
, wxWindow 
*win 
) 
 809     menu
->SetInvokingWindow( win 
); 
 811     wxMenuItemList::Node 
*node 
= menu
->GetMenuItems().GetFirst(); 
 814         wxMenuItem 
*menuitem 
= node
->GetData(); 
 815         if (menuitem
->IsSubMenu()) 
 816             wxMenubarSetInvokingWindow( menuitem
->GetSubMenu() , win 
); 
 817         node 
= node
->GetNext(); 
 821 void wxMenuBar::UnsetInvokingWindow() 
 823     m_invokingWindow 
= (wxWindow
*) NULL
; 
 824     wxMenuList::Node 
*node 
= m_menus
.GetFirst(); 
 827         wxMenu 
*menu 
= node
->GetData(); 
 828         wxMenubarUnsetInvokingWindow( menu 
); 
 829         node 
= node
->GetNext(); 
 833 void wxMenuBar::SetInvokingWindow(wxFrame 
*frame
) 
 835     m_invokingWindow 
= frame
; 
 836     wxMenuList::Node 
*node 
= m_menus
.GetFirst(); 
 839         wxMenu 
*menu 
= node
->GetData(); 
 840         wxMenubarSetInvokingWindow( menu
, frame 
); 
 841         node 
= node
->GetNext(); 
 845 void wxMenuBar::Detach() 
 847     wxMenuBarBase::Detach() ; 
 850 void wxMenuBar::Attach(wxFrame 
*frame
) 
 852     wxMenuBarBase::Attach( frame 
) ; 
 854 // --------------------------------------------------------------------------- 
 855 // wxMenuBar searching for menu items 
 856 // --------------------------------------------------------------------------- 
 858 // Find the itemString in menuString, and return the item id or wxNOT_FOUND 
 859 int wxMenuBar::FindMenuItem(const wxString
& menuString
, 
 860                             const wxString
& itemString
) const 
 862     wxString menuLabel 
= wxStripMenuCodes(menuString
); 
 863     size_t count 
= GetMenuCount(); 
 864     for ( size_t i 
= 0; i 
< count
; i
++ ) 
 866         wxString title 
= wxStripMenuCodes(m_titles
[i
]); 
 867         if ( menuString 
== title 
) 
 868             return m_menus
[i
]->FindItem(itemString
); 
 874 wxMenuItem 
*wxMenuBar::FindItem(int id
, wxMenu 
**itemMenu
) const 
 879     wxMenuItem 
*item 
= NULL
; 
 880     size_t count 
= GetMenuCount(); 
 881     for ( size_t i 
= 0; !item 
&& (i 
< count
); i
++ ) 
 883         item 
= m_menus
[i
]->FindItem(id
, itemMenu
);