]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/menu.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxMenu, wxMenuBar, wxMenuItem 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13     #pragma implementation "menu.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  29     #include "wx/ownerdrw.h" 
  32 #include "wx/os2/private.h" 
  34 // other standard headers 
  37 // ---------------------------------------------------------------------------- 
  39 // ---------------------------------------------------------------------------- 
  41 extern wxMenu
*                      wxCurrentPopupMenu
; 
  43 // ---------------------------------------------------------------------------- 
  45 // ---------------------------------------------------------------------------- 
  48 // The (popup) menu title has this special id 
  50 static const int                    idMenuTitle 
= -2; 
  53 // The unique ID for Menus 
  56 USHORT                              
wxMenu::m_nextMenuId 
= 0; 
  58 static USHORT                       
wxMenu::m_nextMenuId 
= 0; 
  61 // ---------------------------------------------------------------------------- 
  63 // ---------------------------------------------------------------------------- 
  65     IMPLEMENT_DYNAMIC_CLASS(wxMenu
, wxEvtHandler
) 
  66     IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
, wxEvtHandler
) 
  68 // ---------------------------------------------------------------------------- 
  69 // static function for translating menu labels 
  70 // ---------------------------------------------------------------------------- 
  72 static wxString 
TextToLabel(const wxString
& rTitle
) 
  76     for (pc 
= rTitle
; *pc 
!= wxT('\0'); pc
++ ) 
  80             if (*(pc
+1) == wxT('&')) 
  88 //         else if (*pc == wxT('/')) 
  90 //             Title << wxT('\\'); 
  94             if ( *pc 
== wxT('~') ) 
  96                 // tildes must be doubled to prevent them from being 
  97                 // interpreted as accelerator character prefix by PM ??? 
 106 // ============================================================================ 
 108 // ============================================================================ 
 110 // --------------------------------------------------------------------------- 
 111 // wxMenu construction, adding and removing menu items 
 112 // --------------------------------------------------------------------------- 
 115 // Construct a menu with optional title (then use append) 
 122     // Create the menu (to be used as a submenu or a popup) 
 124     if ((m_hMenu 
=  ::WinCreateWindow( HWND_DESKTOP
 
 139         wxLogLastError("WinLoadMenu"); 
 141     m_vMenuData
.iPosition   
= 0; 
 142     m_vMenuData
.afStyle     
= MIS_SUBMENU 
| MIS_TEXT
; 
 143     m_vMenuData
.afAttribute 
= (USHORT
)0; 
 144     m_vMenuData
.id          
= m_nextMenuId
++; 
 145     m_vMenuData
.hwndSubMenu 
= m_hMenu
; 
 146     m_vMenuData
.hItem       
= NULLHANDLE
; 
 149     // If we have a title, insert it in the beginning of the menu 
 151     if (!m_title
.IsEmpty()) 
 158 } // end of wxMenu::Init 
 161 // The wxWindow destructor will take care of deleting the submenus. 
 166     // We should free PM resources only if PM doesn't do it for us 
 167     // which happens if we're attached to a menubar or a submenu of another 
 169     if (!IsAttached() && !GetParent()) 
 171         if (!::WinDestroyWindow((HWND
)GetHmenu()) ) 
 173             wxLogLastError("WinDestroyWindow"); 
 181 #if (!(defined(__VISAGECPP__) && (__IBMCPP__ < 400 || __IBMC__ < 400 ))) 
 182     WX_CLEAR_ARRAY(m_vAccels
); 
 184 #endif // wxUSE_ACCEL 
 185 } // end of wxMenu::~wxMenu 
 189     // this will take effect during the next call to Append() 
 191 } // end of wxMenu::Break 
 195 int wxMenu::FindAccel( 
 200     size_t                          nCount 
= m_vAccels
.GetCount(); 
 202     for (n 
= 0; n 
< nCount
; n
++) 
 204         if (m_vAccels
[n
]->m_command 
== nId
) 
 208 } // end of wxMenu::FindAccel 
 210 void wxMenu::UpdateAccel( 
 215     // Find the (new) accel for this item 
 217     wxAcceleratorEntry
*             pAccel 
= wxGetAccelFromString(pItem
->GetText()); 
 220         pAccel
->m_command 
= pItem
->GetId(); 
 225     int                             n 
= FindAccel(pItem
->GetId()); 
 227     if (n 
== wxNOT_FOUND
) 
 230         // No old, add new if any 
 233             m_vAccels
.Add(pAccel
); 
 235             return;     // skipping RebuildAccelTable() below 
 240         // Replace old with new or just remove the old one if no new 
 245             m_vAccels
[n
] = pAccel
; 
 247             m_vAccels
.RemoveAt(n
); 
 252         m_menuBar
->RebuildAccelTable(); 
 254 } // wxMenu::UpdateAccel 
 256 #endif // wxUSE_ACCEL 
 259 // Append a new item or submenu to the menu 
 261 bool wxMenu::DoInsertOrAppend( 
 271 #endif // wxUSE_ACCEL 
 274     // rItem is the member MENUITEM for the  menu items and the submenu's 
 275     // MENUITEM for submenus as required by ::MM_INSERTITEM message API 
 278     wxMenu
*                         pSubmenu 
= pItem
->GetSubMenu(); 
 279     MENUITEM
&                       rItem 
= (pSubmenu 
!= NULL
)?pSubmenu
->m_vMenuData
: 
 283         wxASSERT_MSG(pSubmenu
->GetHMenu(), wxT("invalid submenu")); 
 284         pSubmenu
->SetParent(this); 
 285         rItem
.afStyle 
|= MIS_SUBMENU 
| MIS_TEXT
; 
 289     // If "Break" has just been called, insert a menu break before this item 
 290     // (and don't forget to reset the flag) 
 294         rItem
.afStyle 
|= MIS_BREAK
; 
 298     if (pItem
->IsSeparator()) 
 300         rItem
.afStyle 
|= MIS_SEPARATOR
; 
 304     // Id is the numeric id for normal menu items and HMENU for submenus as 
 305     // required by ::MM_INSERTITEM message API 
 308     if (pSubmenu 
!= NULL
) 
 310         wxASSERT_MSG(pSubmenu
->GetHMenu(), wxT("invalid submenu")); 
 311         pSubmenu
->SetParent(this); 
 313         rItem
.iPosition 
= 0; // submenus have a 0 position 
 314         rItem
.id 
= (USHORT
)pSubmenu
->GetHMenu(); 
 315         rItem
.afStyle 
|= MIS_SUBMENU 
| MIS_TEXT
; 
 319         rItem
.id 
= pItem
->GetId(); 
 324 #if wxUSE_OWNER_DRAWN 
 325     if (pItem
->IsOwnerDrawn()) 
 328         // Want to get {Measure|Draw}Item messages? 
 329         // item draws itself, passing pointer to data doesn't work in OS/2 
 330         // Will eventually need to set the image handle somewhere into vItem.hItem 
 332         rItem
.afStyle 
|= MIS_OWNERDRAW
; 
 334         rItem
.hItem 
= (HBITMAP
)pItem
->GetBitmap().GetHBITMAP(); 
 335         pItem
->m_vMenuData
.afStyle 
= rItem
.afStyle
; 
 336         pItem
->m_vMenuData
.hItem 
= rItem
.hItem
; 
 342         // Menu is just a normal string (passed in data parameter) 
 344         rItem
.afStyle 
|= MIS_TEXT
; 
 345         pData 
= (char*)pItem
->GetText().c_str(); 
 348     if (nPos 
== (size_t)-1) 
 350         rItem
.iPosition 
= MIT_END
; 
 354         rItem
.iPosition 
= nPos
; 
 359     rc 
= (APIRET
)::WinSendMsg( GetHmenu() 
 364 #if wxUSE_OWNER_DRAWN 
 365     if (pItem
->IsOwnerDrawn()) 
 370         ::WinSendMsg( GetHmenu() 
 372                      ,MPFROM2SHORT( (USHORT
)pItem
->GetId() 
 379     if (rc 
== MIT_MEMERROR 
|| rc 
== MIT_ERROR
) 
 381         vError 
= ::WinGetLastError(vHabmain
); 
 382         sError 
= wxPMErrorToStr(vError
); 
 383         wxLogError("Error inserting or appending a menuitem. Error: %s\n", sError
); 
 384         wxLogLastError("Insert or AppendMenu"); 
 390         // If we're already attached to the menubar, we must update it 
 392         if (IsAttached() && m_menuBar
->IsAttached()) 
 394             m_menuBar
->Refresh(); 
 399 } // end of wxMenu::DoInsertOrAppend 
 401 bool wxMenu::DoAppend( 
 405     return wxMenuBase::DoAppend(pItem
) && DoInsertOrAppend(pItem
); 
 408 bool wxMenu::DoInsert( 
 413     return ( wxMenuBase::DoInsert( nPos
 
 415              DoInsertOrAppend( pItem
 
 418 } // end of wxMenu::DoInsert 
 420 wxMenuItem
* wxMenu::DoRemove( 
 425     // We need to find the items position in the child list 
 428     wxMenuItemList::Node
*           pNode 
= GetMenuItems().GetFirst(); 
 430     for (nPos 
= 0; pNode
; nPos
++) 
 432         if (pNode
->GetData() == pItem
) 
 434         pNode 
= pNode
->GetNext(); 
 438     // DoRemove() (unlike Remove) can only be called for existing item! 
 440     wxCHECK_MSG(pNode
, NULL
, wxT("bug in wxMenu::Remove logic")); 
 444     // Remove the corresponding accel from the accel table 
 446     int                             n 
= FindAccel(pItem
->GetId()); 
 448     if (n 
!= wxNOT_FOUND
) 
 451         m_vAccels
.RemoveAt(n
); 
 454 #endif // wxUSE_ACCEL 
 456     // Remove the item from the menu 
 458     ::WinSendMsg( GetHmenu() 
 460                  ,MPFROM2SHORT(pItem
->GetId(), TRUE
) 
 463     if (IsAttached() && m_menuBar
->IsAttached()) 
 466         // Otherwise, the chane won't be visible 
 468         m_menuBar
->Refresh(); 
 472     // And from internal data structures 
 474     return wxMenuBase::DoRemove(pItem
); 
 475 } // end of wxMenu::DoRemove 
 477 // --------------------------------------------------------------------------- 
 478 // accelerator helpers 
 479 // --------------------------------------------------------------------------- 
 484 // Create the wxAcceleratorEntries for our accels and put them into provided 
 485 // array - return the number of accels we have 
 487 size_t wxMenu::CopyAccels( 
 488   wxAcceleratorEntry
*               pAccels
 
 491     size_t                          nCount 
= GetAccelCount(); 
 493     for (size_t n 
= 0; n 
< nCount
; n
++) 
 495         *pAccels
++ = *m_vAccels
[n
]; 
 498 } // end of wxMenu::CopyAccels 
 500 #endif // wxUSE_ACCEL 
 502 // --------------------------------------------------------------------------- 
 504 // --------------------------------------------------------------------------- 
 506 void wxMenu::SetTitle( 
 507   const wxString
&                   rLabel
 
 510     bool                            bHasNoTitle 
= m_title
.IsEmpty(); 
 511     HWND                            hMenu 
= GetHmenu(); 
 516         if (!rLabel
.IsEmpty()) 
 518             if (!::WinSetWindowText(hMenu
, rLabel
.c_str())) 
 520                 wxLogLastError("SetMenuTitle"); 
 526         if (rLabel
.IsEmpty() ) 
 528             ::WinSendMsg( GetHmenu() 
 530                          ,MPFROM2SHORT(hMenu
, TRUE
) 
 539             if (!::WinSetWindowText(hMenu
, rLabel
.c_str())) 
 541                 wxLogLastError("SetMenuTitle"); 
 545 } // end of wxMenu::SetTitle 
 547 // --------------------------------------------------------------------------- 
 549 // --------------------------------------------------------------------------- 
 551 bool wxMenu::OS2Command( 
 552   WXUINT                            
WXUNUSED(uParam
) 
 557     // Ignore commands from the menu title 
 560     if (vId 
!= (WXWORD
)idMenuTitle
) 
 563                   ,(int)::WinSendMsg( GetHmenu() 
 571 } // end of wxMenu::OS2Command 
 573 // --------------------------------------------------------------------------- 
 575 // --------------------------------------------------------------------------- 
 577 wxWindow
* wxMenu::GetWindow() const 
 579     if (m_invokingWindow 
!= NULL
) 
 580         return m_invokingWindow
; 
 581     else if ( m_menuBar 
!= NULL
) 
 582         return m_menuBar
->GetFrame(); 
 585 } // end of wxMenu::GetWindow 
 587 // recursive search for item by id 
 588 wxMenuItem
* wxMenu::FindItem( 
 591 , wxMenu
**                          ppItemMenu
 
 597     wxMenuItem
*                     pItem 
= NULL
; 
 599     for ( wxMenuItemList::Node 
*node 
= m_items
.GetFirst(); 
 601           node 
= node
->GetNext() ) 
 603         pItem 
= node
->GetData(); 
 605         if ( pItem
->GetId() == nItemId 
&& pItem
->m_vMenuData
.hItem 
== hItem
) 
 608                 *ppItemMenu 
= (wxMenu 
*)this; 
 610         else if ( pItem
->IsSubMenu() ) 
 612             pItem 
= pItem
->GetSubMenu()->FindItem(nItemId
, hItem
, ppItemMenu
); 
 616             // don't exit the loop 
 621 } // end of wxMenu::FindItem 
 623 // --------------------------------------------------------------------------- 
 625 // --------------------------------------------------------------------------- 
 627 void wxMenuBar::Init() 
 629     m_eventHandler 
= this; 
 630     m_pMenuBarFrame 
= NULL
; 
 632 } // end of wxMenuBar::Init 
 634 wxMenuBar::wxMenuBar() 
 637 } // end of wxMenuBar::wxMenuBar 
 639 wxMenuBar::wxMenuBar( 
 640  long                               WXUNUSED(lStyle
) 
 644 } // end of wxMenuBar::wxMenuBar 
 646 wxMenuBar::wxMenuBar( 
 649 , const wxString                    sTitles
[] 
 654     m_titles
.Alloc(nCount
); 
 655     for ( int i 
= 0; i 
< nCount
; i
++ ) 
 657         m_menus
.Append(vMenus
[i
]); 
 658         m_titles
.Add(sTitles
[i
]); 
 659         vMenus
[i
]->Attach(this); 
 661 } // end of wxMenuBar::wxMenuBar 
 663 wxMenuBar::~wxMenuBar() 
 665 } // end of wxMenuBar::~wxMenuBar 
 667 // --------------------------------------------------------------------------- 
 669 // --------------------------------------------------------------------------- 
 671 void wxMenuBar::Refresh() 
 673     wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") ); 
 675     WinSendMsg(GetWinHwnd(m_pMenuBarFrame
), WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0); 
 676 } // end of wxMenuBar::Refresh 
 678 WXHMENU 
wxMenuBar::Create() 
 686     wxCHECK_MSG(!m_hMenu
, TRUE
, wxT("menubar already created")); 
 689     // Menubars should be associated with a frame otherwise they are popups 
 691     if (m_pMenuBarFrame 
!= NULL
) 
 692         hFrame 
= GetWinHwnd(m_pMenuBarFrame
); 
 694         hFrame 
= HWND_DESKTOP
; 
 696     // Create an empty menu and then fill it with insertions 
 698     if ((m_hMenu 
=  ::WinCreateWindow( hFrame
 
 701                                       ,MS_ACTIONBAR 
| WS_SYNCPAINT 
| WS_VISIBLE
 
 713         wxLogLastError("WinLoadMenu"); 
 717         size_t                      nCount 
= GetMenuCount(); 
 719         for (size_t i 
= 0; i 
< nCount
; i
++) 
 727             // Set the parent and owner of the submenues to be the menubar, not the desktop 
 729             hSubMenu 
= m_menus
[i
]->m_vMenuData
.hwndSubMenu
; 
 730             if (!::WinSetParent(m_menus
[i
]->m_vMenuData
.hwndSubMenu
, m_hMenu
, FALSE
)) 
 732                 vError 
= ::WinGetLastError(vHabmain
); 
 733                 sError 
= wxPMErrorToStr(vError
); 
 734                 wxLogError("Error setting parent for submenu. Error: %s\n", sError
); 
 738             if (!::WinSetOwner(m_menus
[i
]->m_vMenuData
.hwndSubMenu
, m_hMenu
)) 
 740                 vError 
= ::WinGetLastError(vHabmain
); 
 741                 sError 
= wxPMErrorToStr(vError
); 
 742                 wxLogError("Error setting parent for submenu. Error: %s\n", sError
); 
 746             m_menus
[i
]->m_vMenuData
.iPosition 
= i
; 
 748             rc 
= (APIRET
)::WinSendMsg(m_hMenu
, MM_INSERTITEM
, (MPARAM
)&m_menus
[i
]->m_vMenuData
, (MPARAM
)m_titles
[i
].c_str()); 
 749             if (rc 
== MIT_MEMERROR 
|| rc 
== MIT_ERROR
) 
 751                 vError 
= ::WinGetLastError(vHabmain
); 
 752                 sError 
= wxPMErrorToStr(vError
); 
 753                 wxLogError("Error inserting or appending a menuitem. Error: %s\n", sError
); 
 759 } // end of wxMenuBar::Create 
 761 // --------------------------------------------------------------------------- 
 762 // wxMenuBar functions to work with the top level submenus 
 763 // --------------------------------------------------------------------------- 
 766 // NB: we don't support owner drawn top level items for now, if we do these 
 767 //     functions would have to be changed to use wxMenuItem as well 
 769 void wxMenuBar::EnableTop( 
 774     wxCHECK_RET(IsAttached(), wxT("doesn't work with unattached menubars")); 
 779        uFlag 
= MIA_DISABLED
; 
 781     nId 
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0)); 
 782     if (nId 
== MIT_ERROR
) 
 784         wxLogLastError("LogLastError"); 
 787     ::WinSendMsg((HWND
)m_hMenu
, MM_SETITEMATTR
, MPFROM2SHORT(nId
, TRUE
), MPFROM2SHORT(MIA_DISABLED
, uFlag
)); 
 789 } // end of wxMenuBar::EnableTop 
 791 void wxMenuBar::SetLabelTop( 
 793 , const wxString
&                   rLabel
 
 799     wxCHECK_RET(nPos 
< GetMenuCount(), wxT("invalid menu index")); 
 800     m_titles
[nPos
] = rLabel
; 
 807     nId 
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0)); 
 808     if (nId 
== MIT_ERROR
) 
 810         wxLogLastError("LogLastError"); 
 813     if(!::WinSendMsg( (HWND
)m_hMenu
 
 815                      ,MPFROM2SHORT(nId
, TRUE
) 
 819         wxLogLastError("QueryItem"); 
 823     if (::WinSendMsg(GetHmenu(), MM_SETITEMTEXT
, MPFROMSHORT(nId
), (MPARAM
)rLabel
.c_str())); 
 825         wxLogLastError("ModifyMenu"); 
 828 } // end of wxMenuBar::SetLabelTop 
 830 wxString 
wxMenuBar::GetLabelTop( 
 834     wxCHECK_MSG( nPos 
< GetMenuCount(), wxEmptyString
, 
 835                  wxT("invalid menu index in wxMenuBar::GetLabelTop") ); 
 836     return m_titles
[nPos
]; 
 837 } // end of wxMenuBar::GetLabelTop 
 839 // --------------------------------------------------------------------------- 
 840 // wxMenuBar construction 
 841 // --------------------------------------------------------------------------- 
 843 wxMenu
* wxMenuBar::Replace( 
 846 , const wxString
&                    rTitle
 
 850     wxString                         Title 
= TextToLabel(rTitle
); 
 851     wxMenu
*                          pMenuOld 
= wxMenuBarBase::Replace( nPos
 
 857     nId 
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0)); 
 858     if (nId 
== MIT_ERROR
) 
 860         wxLogLastError("LogLastError"); 
 865     m_titles
[nPos
] = Title
; 
 868         ::WinSendMsg((HWND
)m_hMenu
, MM_REMOVEITEM
, MPFROM2SHORT(nId
, TRUE
), (MPARAM
)0); 
 869         ::WinSendMsg((HWND
)m_hMenu
, MM_INSERTITEM
, (MPARAM
)&pMenu
->m_vMenuData
, (MPARAM
)Title
.c_str()); 
 872         if (pMenuOld
->HasAccels() || pMenu
->HasAccels()) 
 875             // Need to rebuild accell table 
 879 #endif // wxUSE_ACCEL 
 883 } // end of wxMenuBar::Replace 
 885 bool wxMenuBar::Insert( 
 888 , const wxString
&                   rTitle
 
 891     wxString Title 
= TextToLabel(rTitle
); 
 892     if (!wxMenuBarBase::Insert( nPos
 
 898     m_titles
.Insert( Title
 
 906         ::WinSendMsg((HWND
)m_hMenu
, MM_INSERTITEM
, (MPARAM
)&pMenu
->m_vMenuData
, (MPARAM
)Title
.c_str()); 
 908         if (pMenu
->HasAccels()) 
 910             // need to rebuild accell table 
 913 #endif // wxUSE_ACCEL 
 917 } // end of wxMenuBar::Insert 
 919 bool wxMenuBar::Append( 
 921 , const wxString
&                   rTitle
 
 924     WXHMENU                         hSubmenu 
= pMenu 
? pMenu
->GetHMenu() : 0; 
 926     wxCHECK_MSG(hSubmenu
, FALSE
, wxT("can't append invalid menu to menubar")); 
 928     wxString Title 
= TextToLabel(rTitle
); 
 929     if (!wxMenuBarBase::Append(pMenu
, Title
)) 
 937         pMenu
->m_vMenuData
.iPosition 
= MIT_END
; 
 938         ::WinSendMsg((HWND
)m_hMenu
, MM_INSERTITEM
, (MPARAM
)&pMenu
->m_vMenuData
, (MPARAM
)Title
.c_str()); 
 940         if (pMenu
->HasAccels()) 
 943             // Need to rebuild accell table 
 947 #endif // wxUSE_ACCEL 
 951 } // end of wxMenuBar::Append 
 953 wxMenu
* wxMenuBar::Remove( 
 957     wxMenu
*                         pMenu 
= wxMenuBarBase::Remove(nPos
); 
 963     nId 
= SHORT1FROMMR(::WinSendMsg((HWND
)GetHmenu(), MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0)); 
 964     if (nId 
== MIT_ERROR
) 
 966         wxLogLastError("LogLastError"); 
 971         ::WinSendMsg((HWND
)GetHmenu(), MM_REMOVEITEM
, MPFROM2SHORT(nId
, TRUE
), (MPARAM
)0); 
 975         if (pMenu
->HasAccels()) 
 978             // Need to rebuild accell table 
 982 #endif // wxUSE_ACCEL 
 985     m_titles
.Remove(nPos
); 
 987 } // end of wxMenuBar::Remove 
 991 void wxMenuBar::RebuildAccelTable() 
 994     // Merge the accelerators of all menus into one accel table 
 996     size_t                          nAccelCount 
= 0; 
 998     size_t                          nCount 
= GetMenuCount(); 
1000     for (i 
= 0; i 
< nCount
; i
++) 
1002         nAccelCount 
+= m_menus
[i
]->GetAccelCount(); 
1007         wxAcceleratorEntry
*         pAccelEntries 
= new wxAcceleratorEntry
[nAccelCount
]; 
1010         for (i 
= 0; i 
< nCount
; i
++) 
1012             nAccelCount 
+= m_menus
[i
]->CopyAccels(&pAccelEntries
[nAccelCount
]); 
1014         m_vAccelTable 
= wxAcceleratorTable( nAccelCount
 
1017         delete [] pAccelEntries
; 
1019 } // end of wxMenuBar::RebuildAccelTable 
1021 #endif // wxUSE_ACCEL 
1023 void wxMenuBar::Attach( 
1027     wxASSERT_MSG( !IsAttached(), wxT("menubar already attached!") ); 
1028     m_pMenuBarFrame 
= pFrame
; 
1031     RebuildAccelTable(); 
1033     // Ensure the accelerator table is set to the frame (not the client!) 
1035     if (!::WinSetAccelTable( vHabmain
 
1036                             ,(HWND
)pFrame
->GetHWND() 
1037                             ,m_vAccelTable
.GetHACCEL() 
1039         wxLogLastError("WinSetAccelTable"); 
1040 #endif // wxUSE_ACCEL 
1041 } // end of wxMenuBar::Attach 
1043 void wxMenuBar::Detach() 
1045     ::WinDestroyWindow((HWND
)m_hMenu
); 
1046     m_hMenu 
= (WXHMENU
)NULL
; 
1047     m_pMenuBarFrame 
= NULL
; 
1048 } // end of wxMenuBar::Detach 
1050 // --------------------------------------------------------------------------- 
1051 // wxMenuBar searching for menu items 
1052 // --------------------------------------------------------------------------- 
1055 // Find the itemString in menuString, and return the item id or wxNOT_FOUND 
1057 int wxMenuBar::FindMenuItem( 
1058   const wxString
&                   rMenuString
 
1059 , const wxString
&                   rItemString
 
1062     wxString                        sMenuLabel 
= wxStripMenuCodes(rMenuString
); 
1063     size_t                          nCount 
= GetMenuCount(); 
1065     for (size_t i 
= 0; i 
< nCount
; i
++) 
1067         wxString                    sTitle 
= wxStripMenuCodes(m_titles
[i
]); 
1069         if (rMenuString 
== sTitle
) 
1070             return m_menus
[i
]->FindItem(rItemString
); 
1073 } // end of wxMenuBar::FindMenuItem 
1075 wxMenuItem
* wxMenuBar::FindItem( 
1077 , wxMenu
**                          ppItemMenu
 
1083     wxMenuItem
*                     pItem 
= NULL
; 
1084     size_t                          nCount 
= GetMenuCount(); 
1086     for (size_t i 
= 0; !pItem 
&& (i 
< nCount
); i
++) 
1088         pItem 
= m_menus
[i
]->FindItem( nId
 
1093 } // end of wxMenuBar::FindItem 
1095 wxMenuItem
* wxMenuBar::FindItem( 
1098 , wxMenu
**                          ppItemMenu
 
1104     wxMenuItem
*                     pItem 
= NULL
; 
1105     size_t                          nCount 
= GetMenuCount(); 
1107     for (size_t i 
= 0; !pItem 
&& (i 
< nCount
); i
++) 
1109         pItem 
= m_menus
[i
]->FindItem( nId
 
1115 } // end of wxMenuBar::FindItem