]>
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 
  55 USHORT                              
wxMenu::m_nextMenuId 
= 0; 
  57 // ---------------------------------------------------------------------------- 
  59 // ---------------------------------------------------------------------------- 
  61     IMPLEMENT_DYNAMIC_CLASS(wxMenu
, wxEvtHandler
) 
  62     IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
, wxEvtHandler
) 
  64 // ============================================================================ 
  66 // ============================================================================ 
  68 // --------------------------------------------------------------------------- 
  69 // wxMenu construction, adding and removing menu items 
  70 // --------------------------------------------------------------------------- 
  73 // Construct a menu with optional title (then use append) 
  78     m_nStartRadioGroup 
= -1; 
  81     // Create the menu (to be used as a submenu or a popup) 
  83     if ((m_hMenu 
=  ::WinCreateWindow( HWND_DESKTOP
 
  98         wxLogLastError("WinLoadMenu"); 
 100     m_vMenuData
.iPosition   
= 0; 
 101     m_vMenuData
.afStyle     
= MIS_SUBMENU 
| MIS_TEXT
; 
 102     m_vMenuData
.afAttribute 
= (USHORT
)0; 
 103     m_vMenuData
.id          
= m_nextMenuId
++; 
 104     m_vMenuData
.hwndSubMenu 
= m_hMenu
; 
 105     m_vMenuData
.hItem       
= NULLHANDLE
; 
 108     // If we have a title, insert it in the beginning of the menu 
 110     if (!m_title
.IsEmpty()) 
 119 } // end of wxMenu::Init 
 122 // The wxWindow destructor will take care of deleting the submenus. 
 127     // We should free PM resources only if PM doesn't do it for us 
 128     // which happens if we're attached to a menubar or a submenu of another 
 130     if (!IsAttached() && !GetParent()) 
 132         if (!::WinDestroyWindow((HWND
)GetHmenu()) ) 
 134             wxLogLastError("WinDestroyWindow"); 
 142     WX_CLEAR_ARRAY(m_vAccels
); 
 143 #endif // wxUSE_ACCEL 
 144 } // end of wxMenu::~wxMenu 
 148     // this will take effect during the next call to Append() 
 150 } // end of wxMenu::Break 
 153   wxMenuBarBase
*                    pMenubar
 
 156     wxMenuBase::Attach(pMenubar
); 
 158 } // end of wxMenu::Break; 
 162 int wxMenu::FindAccel( 
 167     size_t                          nCount 
= m_vAccels
.GetCount(); 
 169     for (n 
= 0; n 
< nCount
; n
++) 
 170         if (m_vAccels
[n
]->m_command 
== nId
) 
 173 } // end of wxMenu::FindAccel 
 175 void wxMenu::UpdateAccel( 
 179     if (pItem
->IsSubMenu()) 
 181         wxMenu
*                     pSubmenu 
= pItem
->GetSubMenu(); 
 182         wxMenuItemList::Node
*       pNode 
= pSubmenu
->GetMenuItems().GetFirst(); 
 186             UpdateAccel(pNode
->GetData()); 
 187             pNode 
= pNode
->GetNext(); 
 190     else if (!pItem
->IsSeparator()) 
 193         // Find the (new) accel for this item 
 195         wxAcceleratorEntry
*         pAccel 
= wxGetAccelFromString(pItem
->GetText()); 
 198             pAccel
->m_command 
= pItem
->GetId(); 
 203         size_t                      n 
= FindAccel(pItem
->GetId()); 
 205         if (n 
== (size_t)wxNOT_FOUND
) 
 208             // No old, add new if any 
 211                 m_vAccels
.Add(pAccel
); 
 218             // Replace old with new or just remove the old one if no new 
 222                 m_vAccels
[n
] = pAccel
; 
 224                 m_vAccels
.RemoveAt(n
); 
 229             GetMenuBar()->RebuildAccelTable(); 
 232 } // wxMenu::UpdateAccel 
 234 #endif // wxUSE_ACCEL 
 237 // Append a new item or submenu to the menu 
 239 bool wxMenu::DoInsertOrAppend( 
 244     wxMenu
*                         pSubmenu 
= pItem
->GetSubMenu(); 
 245     MENUITEM
&                       rItem 
= (pSubmenu 
!= NULL
)?pSubmenu
->m_vMenuData
: 
 253 #endif // wxUSE_ACCEL 
 256     // If "Break" has just been called, insert a menu break before this item 
 257     // (and don't forget to reset the flag) 
 261         rItem
.afStyle 
|= MIS_BREAK
; 
 266     // Id is the numeric id for normal menu items and HMENU for submenus as 
 267     // required by ::MM_INSERTITEM message API 
 269     if (pSubmenu 
!= NULL
) 
 271         wxASSERT_MSG(pSubmenu
->GetHMenu(), wxT("invalid submenu")); 
 272         pSubmenu
->SetParent(this); 
 274         rItem
.iPosition 
= 0; // submenus have a 0 position 
 275         rItem
.id        
= (USHORT
)pSubmenu
->GetHMenu(); 
 276         rItem
.afStyle  
|= MIS_SUBMENU 
| MIS_TEXT
; 
 280         rItem
.id 
= pItem
->GetId(); 
 285 #if wxUSE_OWNER_DRAWN 
 286     if (pItem
->IsOwnerDrawn()) 
 289         // Want to get {Measure|Draw}Item messages? 
 290         // item draws itself, passing pointer to data doesn't work in OS/2 
 291         // Will eventually need to set the image handle somewhere into vItem.hItem 
 293         rItem
.afStyle             
|= MIS_OWNERDRAW
; 
 295         rItem
.hItem                
= (HBITMAP
)pItem
->GetBitmap().GetHBITMAP(); 
 296         pItem
->m_vMenuData
.afStyle 
= rItem
.afStyle
; 
 297         pItem
->m_vMenuData
.hItem   
= rItem
.hItem
; 
 301     if (pItem
->IsSeparator()) 
 303         rItem
.afStyle 
= MIS_SEPARATOR
; 
 308         // Menu is just a normal string (passed in data parameter) 
 310         rItem
.afStyle 
|= MIS_TEXT
; 
 311         pData 
= (char*)pItem
->GetText().c_str(); 
 314     if (nPos 
== (size_t)-1) 
 316         rItem
.iPosition 
= MIT_END
; 
 320         rItem
.iPosition 
= nPos
; 
 325     rc 
= (APIRET
)::WinSendMsg( GetHmenu() 
 330 #if wxUSE_OWNER_DRAWN 
 331     if (pItem
->IsOwnerDrawn()) 
 335         ::WinSendMsg( GetHmenu() 
 337                      ,MPFROM2SHORT( (USHORT
)pItem
->GetId() 
 344     if (rc 
== (APIRET
)MIT_MEMERROR 
|| rc 
== (APIRET
)MIT_ERROR
) 
 346         vError 
= ::WinGetLastError(vHabmain
); 
 347         sError 
= wxPMErrorToStr(vError
); 
 348         wxLogError("Error inserting or appending a menuitem. Error: %s\n", sError
.c_str()); 
 349         wxLogLastError("Insert or AppendMenu"); 
 355         // If we're already attached to the menubar, we must update it 
 357         if (IsAttached() && GetMenuBar()->IsAttached()) 
 359             GetMenuBar()->Refresh(); 
 364 } // end of wxMenu::DoInsertOrAppend 
 366 void wxMenu::EndRadioGroup() 
 369     // We're not inside a radio group any longer 
 371     m_nStartRadioGroup 
= -1; 
 372 } // end of wxMenu::EndRadioGroup 
 374 wxMenuItem
* wxMenu::DoAppend( 
 378     wxCHECK_MSG( pItem
, NULL
, _T("NULL item in wxMenu::DoAppend") ); 
 382     if (pItem
->GetKind() == wxITEM_RADIO
) 
 384         int                         nCount 
= GetMenuItemCount(); 
 386         if (m_nStartRadioGroup 
== -1) 
 389             // Start a new radio group 
 391             m_nStartRadioGroup 
= nCount
; 
 394             // For now it has just one element 
 396             pItem
->SetAsRadioGroupStart(); 
 397             pItem
->SetRadioGroupEnd(m_nStartRadioGroup
); 
 400             // Ensure that we have a checked item in the radio group 
 404         else // extend the current radio group 
 407             // We need to update its end item 
 409             pItem
->SetRadioGroupStart(m_nStartRadioGroup
); 
 411             wxMenuItemList::Node
*   pNode 
= GetMenuItems().Item(m_nStartRadioGroup
); 
 415                 pNode
->GetData()->SetRadioGroupEnd(nCount
); 
 419                 wxFAIL_MSG( _T("where is the radio group start item?") ); 
 423     else // not a radio item 
 428     if (!wxMenuBase::DoAppend(pItem
) || !DoInsertOrAppend(pItem
)) 
 435         // Check the item initially 
 440 } // end of wxMenu::DoAppend 
 442 wxMenuItem
* wxMenu::DoInsert( 
 447     if ( wxMenuBase::DoInsert( nPos
 
 449              DoInsertOrAppend( pItem
 
 455 } // end of wxMenu::DoInsert 
 457 wxMenuItem
* wxMenu::DoRemove( 
 462     // We need to find the items position in the child list 
 465     wxMenuItemList::Node
*           pNode 
= GetMenuItems().GetFirst(); 
 467     for (nPos 
= 0; pNode
; nPos
++) 
 469         if (pNode
->GetData() == pItem
) 
 471         pNode 
= pNode
->GetNext(); 
 475     // DoRemove() (unlike Remove) can only be called for existing item! 
 477     wxCHECK_MSG(pNode
, NULL
, wxT("bug in wxMenu::Remove logic")); 
 481     // Remove the corresponding accel from the accel table 
 483     int                             n 
= FindAccel(pItem
->GetId()); 
 485     if (n 
!= wxNOT_FOUND
) 
 488         m_vAccels
.RemoveAt(n
); 
 491 #endif // wxUSE_ACCEL 
 493     // Remove the item from the menu 
 495     ::WinSendMsg( GetHmenu() 
 497                  ,MPFROM2SHORT(pItem
->GetId(), TRUE
) 
 500     if (IsAttached() && GetMenuBar()->IsAttached()) 
 503         // Otherwise, the chane won't be visible 
 505         GetMenuBar()->Refresh(); 
 509     // And from internal data structures 
 511     return wxMenuBase::DoRemove(pItem
); 
 512 } // end of wxMenu::DoRemove 
 514 // --------------------------------------------------------------------------- 
 515 // accelerator helpers 
 516 // --------------------------------------------------------------------------- 
 521 // Create the wxAcceleratorEntries for our accels and put them into provided 
 522 // array - return the number of accels we have 
 524 size_t wxMenu::CopyAccels( 
 525   wxAcceleratorEntry
*               pAccels
 
 528     size_t                          nCount 
= GetAccelCount(); 
 530     for (size_t n 
= 0; n 
< nCount
; n
++) 
 532         *pAccels
++ = *m_vAccels
[n
]; 
 535 } // end of wxMenu::CopyAccels 
 537 #endif // wxUSE_ACCEL 
 539 // --------------------------------------------------------------------------- 
 541 // --------------------------------------------------------------------------- 
 543 void wxMenu::SetTitle( 
 544   const wxString
&                   rLabel
 
 547     bool                            bHasNoTitle 
= m_title
.IsEmpty(); 
 548     HWND                            hMenu 
= GetHmenu(); 
 553         if (!rLabel
.IsEmpty()) 
 555             if (!::WinSetWindowText(hMenu
, rLabel
.c_str())) 
 557                 wxLogLastError("SetMenuTitle"); 
 563         if (rLabel
.IsEmpty() ) 
 565             ::WinSendMsg( GetHmenu() 
 567                          ,MPFROM2SHORT(hMenu
, TRUE
) 
 576             if (!::WinSetWindowText(hMenu
, rLabel
.c_str())) 
 578                 wxLogLastError("SetMenuTitle"); 
 582 } // end of wxMenu::SetTitle 
 584 // --------------------------------------------------------------------------- 
 586 // --------------------------------------------------------------------------- 
 588 bool wxMenu::OS2Command( 
 589   WXUINT                            
WXUNUSED(uParam
) 
 594     // Ignore commands from the menu title 
 597     if (vId 
!= (WXWORD
)idMenuTitle
) 
 600                   ,(int)::WinSendMsg( GetHmenu() 
 608 } // end of wxMenu::OS2Command 
 610 // --------------------------------------------------------------------------- 
 612 // --------------------------------------------------------------------------- 
 614 wxWindow
* wxMenu::GetWindow() const 
 616     if (m_invokingWindow 
!= NULL
) 
 617         return m_invokingWindow
; 
 618     else if ( GetMenuBar() != NULL
) 
 619         return GetMenuBar()->GetFrame(); 
 622 } // end of wxMenu::GetWindow 
 624 // recursive search for item by id 
 625 wxMenuItem
* wxMenu::FindItem( 
 628 , wxMenu
**                          ppItemMenu
 
 634     wxMenuItem
*                     pItem 
= NULL
; 
 636     for ( wxMenuItemList::Node 
*node 
= m_items
.GetFirst(); 
 638           node 
= node
->GetNext() ) 
 640         pItem 
= node
->GetData(); 
 642         if ( pItem
->GetId() == nItemId 
&& pItem
->m_vMenuData
.hItem 
== hItem
) 
 645                 *ppItemMenu 
= (wxMenu 
*)this; 
 647         else if ( pItem
->IsSubMenu() ) 
 649             pItem 
= pItem
->GetSubMenu()->FindItem( nItemId
 
 658             // don't exit the loop 
 663 } // end of wxMenu::FindItem 
 665 // --------------------------------------------------------------------------- 
 667 // --------------------------------------------------------------------------- 
 669 void wxMenuBar::Init() 
 671     m_eventHandler 
= this; 
 672     m_menuBarFrame 
= NULL
; 
 674 } // end of wxMenuBar::Init 
 676 wxMenuBar::wxMenuBar() 
 679 } // end of wxMenuBar::wxMenuBar 
 681 wxMenuBar::wxMenuBar( 
 682  long                               WXUNUSED(lStyle
) 
 686 } // end of wxMenuBar::wxMenuBar 
 688 wxMenuBar::wxMenuBar( 
 691 , const wxString                    sTitles
[] 
 696     m_titles
.Alloc(nCount
); 
 697     for ( int i 
= 0; i 
< nCount
; i
++ ) 
 699         m_menus
.Append(vMenus
[i
]); 
 700         m_titles
.Add(sTitles
[i
]); 
 701         vMenus
[i
]->Attach(this); 
 703 } // end of wxMenuBar::wxMenuBar 
 705 wxMenuBar::~wxMenuBar() 
 708     // We should free PM's resources only if PM doesn't do it for us 
 709     // which happens if we're attached to a frame 
 711     if (m_hMenu 
&& !IsAttached()) 
 713         ::WinDestroyWindow((HMENU
)m_hMenu
); 
 714         m_hMenu 
= (WXHMENU
)NULL
; 
 716 } // end of wxMenuBar::~wxMenuBar 
 718 // --------------------------------------------------------------------------- 
 720 // --------------------------------------------------------------------------- 
 722 void wxMenuBar::Refresh() 
 724     wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") ); 
 726     WinSendMsg(GetWinHwnd(m_menuBarFrame
), WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0); 
 727 } // end of wxMenuBar::Refresh 
 729 WXHMENU 
wxMenuBar::Create() 
 736     wxCHECK_MSG(!m_hMenu
, TRUE
, wxT("menubar already created")); 
 739     // Menubars should be associated with a frame otherwise they are popups 
 741     if (m_menuBarFrame 
!= NULL
) 
 742         hFrame 
= GetWinHwnd(m_menuBarFrame
); 
 744         hFrame 
= HWND_DESKTOP
; 
 746     // Create an empty menu and then fill it with insertions 
 748     if ((m_hMenu 
=  ::WinCreateWindow( hFrame
 
 751                                       ,MS_ACTIONBAR 
| WS_SYNCPAINT 
| WS_VISIBLE
 
 763         wxLogLastError("WinLoadMenu"); 
 767         size_t                      nCount 
= GetMenuCount(); 
 769         for (size_t i 
= 0; i 
< nCount
; i
++) 
 777             // Set the parent and owner of the submenues to be the menubar, not the desktop 
 779             hSubMenu 
= m_menus
[i
]->m_vMenuData
.hwndSubMenu
; 
 780             if (!::WinSetParent(m_menus
[i
]->m_vMenuData
.hwndSubMenu
, m_hMenu
, FALSE
)) 
 782                 vError 
= ::WinGetLastError(vHabmain
); 
 783                 sError 
= wxPMErrorToStr(vError
); 
 784                 wxLogError("Error setting parent for submenu. Error: %s\n", sError
.c_str()); 
 788             if (!::WinSetOwner(m_menus
[i
]->m_vMenuData
.hwndSubMenu
, m_hMenu
)) 
 790                 vError 
= ::WinGetLastError(vHabmain
); 
 791                 sError 
= wxPMErrorToStr(vError
); 
 792                 wxLogError("Error setting parent for submenu. Error: %s\n", sError
.c_str()); 
 796             m_menus
[i
]->m_vMenuData
.iPosition 
= i
; 
 798             rc 
= (APIRET
)::WinSendMsg(m_hMenu
, MM_INSERTITEM
, (MPARAM
)&m_menus
[i
]->m_vMenuData
, (MPARAM
)m_titles
[i
].c_str()); 
 799             if (rc 
== (APIRET
)MIT_MEMERROR 
|| rc 
== (APIRET
)MIT_ERROR
) 
 801                 vError 
= ::WinGetLastError(vHabmain
); 
 802                 sError 
= wxPMErrorToStr(vError
); 
 803                 wxLogError("Error inserting or appending a menuitem. Error: %s\n", sError
.c_str()); 
 809 } // end of wxMenuBar::Create 
 811 // --------------------------------------------------------------------------- 
 812 // wxMenuBar functions to work with the top level submenus 
 813 // --------------------------------------------------------------------------- 
 816 // NB: we don't support owner drawn top level items for now, if we do these 
 817 //     functions would have to be changed to use wxMenuItem as well 
 819 void wxMenuBar::EnableTop( 
 824     wxCHECK_RET(IsAttached(), wxT("doesn't work with unattached menubars")); 
 829        uFlag 
= MIA_DISABLED
; 
 831     nId 
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0)); 
 832     if (nId 
== MIT_ERROR
) 
 834         wxLogLastError("LogLastError"); 
 837     ::WinSendMsg((HWND
)m_hMenu
, MM_SETITEMATTR
, MPFROM2SHORT(nId
, TRUE
), MPFROM2SHORT(MIA_DISABLED
, uFlag
)); 
 839 } // end of wxMenuBar::EnableTop 
 841 void wxMenuBar::SetLabelTop( 
 843 , const wxString
&                   rLabel
 
 849     wxCHECK_RET(nPos 
< GetMenuCount(), wxT("invalid menu index")); 
 850     m_titles
[nPos
] = rLabel
; 
 857     nId 
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0)); 
 858     if (nId 
== MIT_ERROR
) 
 860         wxLogLastError("LogLastError"); 
 863     if(!::WinSendMsg( (HWND
)m_hMenu
 
 865                      ,MPFROM2SHORT(nId
, TRUE
) 
 869         wxLogLastError("QueryItem"); 
 873     if (::WinSendMsg(GetHmenu(), MM_SETITEMTEXT
, MPFROMSHORT(nId
), (MPARAM
)rLabel
.c_str())); 
 875         wxLogLastError("ModifyMenu"); 
 878 } // end of wxMenuBar::SetLabelTop 
 880 wxString 
wxMenuBar::GetLabelTop( 
 884     wxCHECK_MSG( nPos 
< GetMenuCount(), wxEmptyString
, 
 885                  wxT("invalid menu index in wxMenuBar::GetLabelTop") ); 
 886     return m_titles
[nPos
]; 
 887 } // end of wxMenuBar::GetLabelTop 
 889 // --------------------------------------------------------------------------- 
 890 // wxMenuBar construction 
 891 // --------------------------------------------------------------------------- 
 893 wxMenu
* wxMenuBar::Replace( 
 896 , const wxString
&                    rTitle
 
 900     wxString                         sTitle 
= wxPMTextToLabel(rTitle
); 
 901     wxMenu
*                          pMenuOld 
= wxMenuBarBase::Replace( nPos
 
 907     nId 
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0)); 
 908     if (nId 
== MIT_ERROR
) 
 910         wxLogLastError("LogLastError"); 
 915     m_titles
[nPos
] = sTitle
; 
 918         ::WinSendMsg((HWND
)m_hMenu
, MM_REMOVEITEM
, MPFROM2SHORT(nId
, TRUE
), (MPARAM
)0); 
 919         ::WinSendMsg((HWND
)m_hMenu
, MM_INSERTITEM
, (MPARAM
)&pMenu
->m_vMenuData
, (MPARAM
)sTitle
.c_str()); 
 922         if (pMenuOld
->HasAccels() || pMenu
->HasAccels()) 
 925             // Need to rebuild accell table 
 929 #endif // wxUSE_ACCEL 
 933 } // end of wxMenuBar::Replace 
 935 bool wxMenuBar::Insert( 
 938 , const wxString
&                   rTitle
 
 941     wxString                        sTitle 
= wxPMTextToLabel(rTitle
); 
 943     if (!wxMenuBarBase::Insert( nPos
 
 949     m_titles
.Insert( sTitle
 
 955         pMenu
->m_vMenuData
.iPosition 
= nPos
; 
 956         ::WinSendMsg( (HWND
)m_hMenu
 
 958                      ,(MPARAM
)&pMenu
->m_vMenuData
 
 959                      ,(MPARAM
)sTitle
.c_str() 
 962         if (pMenu
->HasAccels()) 
 964             // need to rebuild accell table 
 967 #endif // wxUSE_ACCEL 
 971 } // end of wxMenuBar::Insert 
 973 bool wxMenuBar::Append( 
 975 , const wxString
&                   rsTitle
 
 978     WXHMENU                         hSubmenu 
= pMenu 
? pMenu
->GetHMenu() : 0; 
 980     wxCHECK_MSG(hSubmenu
, FALSE
, wxT("can't append invalid menu to menubar")); 
 982     wxString                        sTitle 
= wxPMTextToLabel(rsTitle
); 
 984     if (!wxMenuBarBase::Append(pMenu
, sTitle
)) 
 987     m_titles
.Add(sTitle
); 
 991         pMenu
->m_vMenuData
.iPosition 
= MIT_END
; 
 992         ::WinSendMsg((HWND
)m_hMenu
, MM_INSERTITEM
, (MPARAM
)&pMenu
->m_vMenuData
, (MPARAM
)sTitle
.c_str()); 
 994         if (pMenu
->HasAccels()) 
 997             // Need to rebuild accell table 
1001 #endif // wxUSE_ACCEL 
1005 } // end of wxMenuBar::Append 
1007 wxMenu
* wxMenuBar::Remove( 
1011     wxMenu
*                         pMenu 
= wxMenuBarBase::Remove(nPos
); 
1017     nId 
= SHORT1FROMMR(::WinSendMsg( (HWND
)GetHmenu() 
1018                                     ,MM_ITEMIDFROMPOSITION
 
1022     if (nId 
== MIT_ERROR
) 
1024         wxLogLastError("LogLastError"); 
1029         ::WinSendMsg( (HWND
)GetHmenu() 
1031                      ,MPFROM2SHORT(nId
, TRUE
) 
1036         if (pMenu
->HasAccels()) 
1039             // Need to rebuild accell table 
1041             RebuildAccelTable(); 
1043 #endif // wxUSE_ACCEL 
1046     m_titles
.Remove(nPos
); 
1048 } // end of wxMenuBar::Remove 
1052 void wxMenuBar::RebuildAccelTable() 
1055     // Merge the accelerators of all menus into one accel table 
1057     size_t                          nAccelCount 
= 0; 
1059     size_t                          nCount 
= GetMenuCount(); 
1061     for (i 
= 0; i 
< nCount
; i
++) 
1063         nAccelCount 
+= m_menus
[i
]->GetAccelCount(); 
1068         wxAcceleratorEntry
*         pAccelEntries 
= new wxAcceleratorEntry
[nAccelCount
]; 
1071         for (i 
= 0; i 
< nCount
; i
++) 
1073             nAccelCount 
+= m_menus
[i
]->CopyAccels(&pAccelEntries
[nAccelCount
]); 
1075         m_vAccelTable 
= wxAcceleratorTable( nAccelCount
 
1078         delete [] pAccelEntries
; 
1080 } // end of wxMenuBar::RebuildAccelTable 
1082 #endif // wxUSE_ACCEL 
1084 void wxMenuBar::Attach( 
1088     wxMenuBarBase::Attach(pFrame
); 
1091     RebuildAccelTable(); 
1093     // Ensure the accelerator table is set to the frame (not the client!) 
1095     if (!::WinSetAccelTable( vHabmain
 
1096                             ,m_vAccelTable
.GetHACCEL() 
1097                             ,(HWND
)pFrame
->GetFrame() 
1099         wxLogLastError("WinSetAccelTable"); 
1100 #endif // wxUSE_ACCEL 
1101 } // end of wxMenuBar::Attach 
1103 void wxMenuBar::Detach() 
1105     ::WinDestroyWindow((HWND
)m_hMenu
); 
1106     m_hMenu 
= (WXHMENU
)NULL
; 
1107     m_menuBarFrame 
= NULL
; 
1108 } // end of wxMenuBar::Detach 
1110 // --------------------------------------------------------------------------- 
1111 // wxMenuBar searching for menu items 
1112 // --------------------------------------------------------------------------- 
1115 // Find the itemString in menuString, and return the item id or wxNOT_FOUND 
1117 int wxMenuBar::FindMenuItem( 
1118   const wxString
&                   rMenuString
 
1119 , const wxString
&                   rItemString
 
1122     wxString                        sMenuLabel 
= wxStripMenuCodes(rMenuString
); 
1123     size_t                          nCount 
= GetMenuCount(); 
1125     for (size_t i 
= 0; i 
< nCount
; i
++) 
1127         wxString                    sTitle 
= wxStripMenuCodes(m_titles
[i
]); 
1129         if (rMenuString 
== sTitle
) 
1130             return m_menus
[i
]->FindItem(rItemString
); 
1133 } // end of wxMenuBar::FindMenuItem 
1135 wxMenuItem
* wxMenuBar::FindItem( 
1137 , wxMenu
**                          ppItemMenu
 
1143     wxMenuItem
*                     pItem 
= NULL
; 
1144     size_t                          nCount 
= GetMenuCount(); 
1146     for (size_t i 
= 0; !pItem 
&& (i 
< nCount
); i
++) 
1148         pItem 
= m_menus
[i
]->FindItem( nId
 
1153 } // end of wxMenuBar::FindItem 
1155 wxMenuItem
* wxMenuBar::FindItem( 
1158 , wxMenu
**                          ppItemMenu
 
1164     wxMenuItem
*                     pItem 
= NULL
; 
1165     size_t                          nCount 
= GetMenuCount(); 
1167     for (size_t i 
= 0; !pItem 
&& (i 
< nCount
); i
++) 
1169         pItem 
= m_menus
[i
]->FindItem( nId
 
1175 } // end of wxMenuBar::FindItem