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
= -3;
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(wxT("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(wxT("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::compatibility_iterator node
= pSubmenu
->GetMenuItems().GetFirst();
186 UpdateAccel(node
->GetData());
187 node
= node
->GetNext();
190 else if (!pItem
->IsSeparator())
193 // Recurse upwards: we should only modify m_accels of the top level
194 // menus, not of the submenus as wxMenuBar doesn't look at them
195 // (alternative and arguable cleaner solution would be to recurse
196 // downwards in GetAccelCount() and CopyAccels())
200 GetParent()->UpdateAccel(pItem
);
205 // Find the (new) accel for this item
207 wxAcceleratorEntry
* pAccel
= wxGetAccelFromString(pItem
->GetText());
210 pAccel
->m_command
= pItem
->GetId();
215 size_t n
= FindAccel(pItem
->GetId());
217 if (n
== (size_t)wxNOT_FOUND
)
220 // No old, add new if any
223 m_vAccels
.Add(pAccel
);
230 // Replace old with new or just remove the old one if no new
234 m_vAccels
[n
] = pAccel
;
236 m_vAccels
.RemoveAt(n
);
241 GetMenuBar()->RebuildAccelTable();
244 } // wxMenu::UpdateAccel
246 #endif // wxUSE_ACCEL
249 // Append a new item or submenu to the menu
251 bool wxMenu::DoInsertOrAppend(
256 wxMenu
* pSubmenu
= pItem
->GetSubMenu();
257 MENUITEM
& rItem
= (pSubmenu
!= NULL
)?pSubmenu
->m_vMenuData
:
265 #endif // wxUSE_ACCEL
268 // If "Break" has just been called, insert a menu break before this item
269 // (and don't forget to reset the flag)
273 rItem
.afStyle
|= MIS_BREAK
;
278 // Id is the numeric id for normal menu items and HMENU for submenus as
279 // required by ::MM_INSERTITEM message API
281 if (pSubmenu
!= NULL
)
283 wxASSERT_MSG(pSubmenu
->GetHMenu(), wxT("invalid submenu"));
284 pSubmenu
->SetParent(this);
286 rItem
.iPosition
= 0; // submenus have a 0 position
287 rItem
.id
= (USHORT
)pSubmenu
->GetHMenu();
288 rItem
.afStyle
|= MIS_SUBMENU
| MIS_TEXT
;
292 rItem
.id
= pItem
->GetId();
297 #if wxUSE_OWNER_DRAWN
298 if (pItem
->IsOwnerDrawn())
301 // Want to get {Measure|Draw}Item messages?
302 // item draws itself, passing pointer to data doesn't work in OS/2
303 // Will eventually need to set the image handle somewhere into vItem.hItem
305 rItem
.afStyle
|= MIS_OWNERDRAW
;
307 rItem
.hItem
= (HBITMAP
)pItem
->GetBitmap().GetHBITMAP();
308 pItem
->m_vMenuData
.afStyle
= rItem
.afStyle
;
309 pItem
->m_vMenuData
.hItem
= rItem
.hItem
;
313 if (pItem
->IsSeparator())
315 rItem
.afStyle
= MIS_SEPARATOR
;
319 if (pItem
->GetId() == idMenuTitle
)
321 // Item is an unselectable title to be passed via pData
322 rItem
.afStyle
= MIS_STATIC
;
327 // Menu is just a normal string (passed in data parameter)
329 rItem
.afStyle
|= MIS_TEXT
;
331 pData
= (char*)pItem
->GetText().c_str();
334 if (nPos
== (size_t)-1)
336 rItem
.iPosition
= MIT_END
;
340 rItem
.iPosition
= nPos
;
345 rc
= (APIRET
)::WinSendMsg( GetHmenu()
350 #if wxUSE_OWNER_DRAWN
351 if (pItem
->IsOwnerDrawn())
355 ::WinSendMsg( GetHmenu()
357 ,MPFROM2SHORT( (USHORT
)pItem
->GetId()
364 if (rc
== (APIRET
)MIT_MEMERROR
|| rc
== (APIRET
)MIT_ERROR
)
366 vError
= ::WinGetLastError(vHabmain
);
367 sError
= wxPMErrorToStr(vError
);
368 wxLogError(wxT("Error inserting or appending a menuitem. Error: %s\n"), sError
.c_str());
369 wxLogLastError(wxT("Insert or AppendMenu"));
375 // If we're already attached to the menubar, we must update it
377 if (IsAttached() && GetMenuBar()->IsAttached())
379 GetMenuBar()->Refresh();
384 } // end of wxMenu::DoInsertOrAppend
386 void wxMenu::EndRadioGroup()
389 // We're not inside a radio group any longer
391 m_nStartRadioGroup
= -1;
392 } // end of wxMenu::EndRadioGroup
394 wxMenuItem
* wxMenu::DoAppend(
398 wxCHECK_MSG( pItem
, NULL
, _T("NULL item in wxMenu::DoAppend") );
402 if (pItem
->GetKind() == wxITEM_RADIO
)
404 int nCount
= GetMenuItemCount();
406 if (m_nStartRadioGroup
== -1)
409 // Start a new radio group
411 m_nStartRadioGroup
= nCount
;
414 // For now it has just one element
416 pItem
->SetAsRadioGroupStart();
417 pItem
->SetRadioGroupEnd(m_nStartRadioGroup
);
420 // Ensure that we have a checked item in the radio group
424 else // extend the current radio group
427 // We need to update its end item
429 pItem
->SetRadioGroupStart(m_nStartRadioGroup
);
431 wxMenuItemList::compatibility_iterator node
= GetMenuItems().Item(m_nStartRadioGroup
);
435 node
->GetData()->SetRadioGroupEnd(nCount
);
439 wxFAIL_MSG( _T("where is the radio group start item?") );
443 else // not a radio item
448 if (!wxMenuBase::DoAppend(pItem
) || !DoInsertOrAppend(pItem
))
455 // Check the item initially
460 } // end of wxMenu::DoAppend
462 wxMenuItem
* wxMenu::DoInsert(
467 if ( wxMenuBase::DoInsert( nPos
469 DoInsertOrAppend( pItem
475 } // end of wxMenu::DoInsert
477 wxMenuItem
* wxMenu::DoRemove(
482 // We need to find the items position in the child list
485 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
487 for (nPos
= 0; node
; nPos
++)
489 if (node
->GetData() == pItem
)
491 node
= node
->GetNext();
495 // DoRemove() (unlike Remove) can only be called for existing item!
497 wxCHECK_MSG(node
, NULL
, wxT("bug in wxMenu::Remove logic"));
501 // Remove the corresponding accel from the accel table
503 int n
= FindAccel(pItem
->GetId());
505 if (n
!= wxNOT_FOUND
)
508 m_vAccels
.RemoveAt(n
);
511 #endif // wxUSE_ACCEL
513 // Remove the item from the menu
515 ::WinSendMsg( GetHmenu()
517 ,MPFROM2SHORT(pItem
->GetId(), TRUE
)
520 if (IsAttached() && GetMenuBar()->IsAttached())
523 // Otherwise, the chane won't be visible
525 GetMenuBar()->Refresh();
529 // And from internal data structures
531 return wxMenuBase::DoRemove(pItem
);
532 } // end of wxMenu::DoRemove
534 // ---------------------------------------------------------------------------
535 // accelerator helpers
536 // ---------------------------------------------------------------------------
541 // Create the wxAcceleratorEntries for our accels and put them into provided
542 // array - return the number of accels we have
544 size_t wxMenu::CopyAccels(
545 wxAcceleratorEntry
* pAccels
548 size_t nCount
= GetAccelCount();
550 for (size_t n
= 0; n
< nCount
; n
++)
552 *pAccels
++ = *m_vAccels
[n
];
555 } // end of wxMenu::CopyAccels
557 #endif // wxUSE_ACCEL
559 // ---------------------------------------------------------------------------
561 // ---------------------------------------------------------------------------
563 void wxMenu::SetTitle(
564 const wxString
& rLabel
567 bool bHasNoTitle
= m_title
.IsEmpty();
568 HWND hMenu
= GetHmenu();
573 if (!rLabel
.IsEmpty())
575 if (!::WinSetWindowText(hMenu
, (PSZ
)rLabel
.c_str()))
577 wxLogLastError(wxT("SetMenuTitle"));
583 if (rLabel
.IsEmpty() )
585 ::WinSendMsg( GetHmenu()
587 ,MPFROM2SHORT(hMenu
, TRUE
)
596 if (!::WinSetWindowText(hMenu
, (PSZ
)rLabel
.c_str()))
598 wxLogLastError(wxT("SetMenuTitle"));
602 } // end of wxMenu::SetTitle
604 // ---------------------------------------------------------------------------
606 // ---------------------------------------------------------------------------
608 bool wxMenu::OS2Command(
609 WXUINT
WXUNUSED(uParam
)
614 // Ignore commands from the menu title
617 if (vId
!= (WXWORD
)idMenuTitle
)
620 ,(int)::WinSendMsg( GetHmenu()
628 } // end of wxMenu::OS2Command
630 // ---------------------------------------------------------------------------
632 // ---------------------------------------------------------------------------
634 wxWindow
* wxMenu::GetWindow() const
636 if (m_invokingWindow
!= NULL
)
637 return m_invokingWindow
;
638 else if ( GetMenuBar() != NULL
)
639 return GetMenuBar()->GetFrame();
642 } // end of wxMenu::GetWindow
644 // recursive search for item by id
645 wxMenuItem
* wxMenu::FindItem(
648 , wxMenu
** ppItemMenu
654 wxMenuItem
* pItem
= NULL
;
656 for ( wxMenuItemList::compatibility_iterator node
= m_items
.GetFirst();
658 node
= node
->GetNext() )
660 pItem
= node
->GetData();
662 if ( pItem
->GetId() == nItemId
&& pItem
->m_vMenuData
.hItem
== hItem
)
665 *ppItemMenu
= (wxMenu
*)this;
667 else if ( pItem
->IsSubMenu() )
669 pItem
= pItem
->GetSubMenu()->FindItem( nItemId
678 // don't exit the loop
683 } // end of wxMenu::FindItem
685 // ---------------------------------------------------------------------------
687 // ---------------------------------------------------------------------------
689 void wxMenuBar::Init()
691 m_eventHandler
= this;
692 m_menuBarFrame
= NULL
;
694 } // end of wxMenuBar::Init
696 wxMenuBar::wxMenuBar()
699 } // end of wxMenuBar::wxMenuBar
701 wxMenuBar::wxMenuBar(
702 long WXUNUSED(lStyle
)
706 } // end of wxMenuBar::wxMenuBar
708 wxMenuBar::wxMenuBar(
711 , const wxString sTitles
[]
712 , long WXUNUSED(lStyle
)
717 m_titles
.Alloc(nCount
);
718 for ( int i
= 0; i
< nCount
; i
++ )
720 m_menus
.Append(vMenus
[i
]);
721 m_titles
.Add(sTitles
[i
]);
722 vMenus
[i
]->Attach(this);
724 } // end of wxMenuBar::wxMenuBar
726 wxMenuBar::~wxMenuBar()
729 // We should free PM's resources only if PM doesn't do it for us
730 // which happens if we're attached to a frame
732 if (m_hMenu
&& !IsAttached())
734 ::WinDestroyWindow((HMENU
)m_hMenu
);
735 m_hMenu
= (WXHMENU
)NULL
;
737 } // end of wxMenuBar::~wxMenuBar
739 // ---------------------------------------------------------------------------
741 // ---------------------------------------------------------------------------
743 void wxMenuBar::Refresh()
745 wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
747 WinSendMsg(GetWinHwnd(m_menuBarFrame
), WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
748 } // end of wxMenuBar::Refresh
750 WXHMENU
wxMenuBar::Create()
757 wxCHECK_MSG(!m_hMenu
, TRUE
, wxT("menubar already created"));
760 // Menubars should be associated with a frame otherwise they are popups
762 if (m_menuBarFrame
!= NULL
)
763 hFrame
= GetWinHwnd(m_menuBarFrame
);
765 hFrame
= HWND_DESKTOP
;
767 // Create an empty menu and then fill it with insertions
769 if ((m_hMenu
= ::WinCreateWindow( hFrame
772 ,MS_ACTIONBAR
| WS_SYNCPAINT
| WS_VISIBLE
784 wxLogLastError(wxT("WinLoadMenu"));
788 size_t nCount
= GetMenuCount(), i
;
789 wxMenuList::iterator it
;
790 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
798 // Set the parent and owner of the submenues to be the menubar, not the desktop
800 hSubMenu
= (*it
)->m_vMenuData
.hwndSubMenu
;
801 if (!::WinSetParent((*it
)->m_vMenuData
.hwndSubMenu
, m_hMenu
, FALSE
))
803 vError
= ::WinGetLastError(vHabmain
);
804 sError
= wxPMErrorToStr(vError
);
805 wxLogError(wxT("Error setting parent for submenu. Error: %s\n"), sError
.c_str());
809 if (!::WinSetOwner((*it
)->m_vMenuData
.hwndSubMenu
, m_hMenu
))
811 vError
= ::WinGetLastError(vHabmain
);
812 sError
= wxPMErrorToStr(vError
);
813 wxLogError(wxT("Error setting parent for submenu. Error: %s\n"), sError
.c_str());
817 (*it
)->m_vMenuData
.iPosition
= i
;
819 rc
= (APIRET
)::WinSendMsg(m_hMenu
, MM_INSERTITEM
, (MPARAM
)&(*it
)->m_vMenuData
, (MPARAM
)m_titles
[i
].c_str());
820 if (rc
== (APIRET
)MIT_MEMERROR
|| rc
== (APIRET
)MIT_ERROR
)
822 vError
= ::WinGetLastError(vHabmain
);
823 sError
= wxPMErrorToStr(vError
);
824 wxLogError(wxT("Error inserting or appending a menuitem. Error: %s\n"), sError
.c_str());
830 } // end of wxMenuBar::Create
832 // ---------------------------------------------------------------------------
833 // wxMenuBar functions to work with the top level submenus
834 // ---------------------------------------------------------------------------
837 // NB: we don't support owner drawn top level items for now, if we do these
838 // functions would have to be changed to use wxMenuItem as well
840 void wxMenuBar::EnableTop(
845 wxCHECK_RET(IsAttached(), wxT("doesn't work with unattached menubars"));
850 uFlag
= MIA_DISABLED
;
852 nId
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0));
853 if (nId
== MIT_ERROR
)
855 wxLogLastError(wxT("LogLastError"));
858 ::WinSendMsg((HWND
)m_hMenu
, MM_SETITEMATTR
, MPFROM2SHORT(nId
, TRUE
), MPFROM2SHORT(MIA_DISABLED
, uFlag
));
860 } // end of wxMenuBar::EnableTop
862 void wxMenuBar::SetLabelTop(
864 , const wxString
& rLabel
870 wxCHECK_RET(nPos
< GetMenuCount(), wxT("invalid menu index"));
871 m_titles
[nPos
] = rLabel
;
878 nId
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0));
879 if (nId
== MIT_ERROR
)
881 wxLogLastError(wxT("LogLastError"));
884 if(!::WinSendMsg( (HWND
)m_hMenu
886 ,MPFROM2SHORT(nId
, TRUE
)
890 wxLogLastError(wxT("QueryItem"));
894 if (::WinSendMsg(GetHmenu(), MM_SETITEMTEXT
, MPFROMSHORT(nId
), (MPARAM
)rLabel
.c_str()));
896 wxLogLastError(wxT("ModifyMenu"));
899 } // end of wxMenuBar::SetLabelTop
901 wxString
wxMenuBar::GetLabelTop(
905 wxCHECK_MSG( nPos
< GetMenuCount(), wxEmptyString
,
906 wxT("invalid menu index in wxMenuBar::GetLabelTop") );
907 return m_titles
[nPos
];
908 } // end of wxMenuBar::GetLabelTop
910 // ---------------------------------------------------------------------------
911 // wxMenuBar construction
912 // ---------------------------------------------------------------------------
914 wxMenu
* wxMenuBar::Replace(
917 , const wxString
& rTitle
921 wxString sTitle
= wxPMTextToLabel(rTitle
);
922 wxMenu
* pMenuOld
= wxMenuBarBase::Replace( nPos
928 nId
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0));
929 if (nId
== MIT_ERROR
)
931 wxLogLastError(wxT("LogLastError"));
936 m_titles
[nPos
] = sTitle
;
939 ::WinSendMsg((HWND
)m_hMenu
, MM_REMOVEITEM
, MPFROM2SHORT(nId
, TRUE
), (MPARAM
)0);
940 ::WinSendMsg((HWND
)m_hMenu
, MM_INSERTITEM
, (MPARAM
)&pMenu
->m_vMenuData
, (MPARAM
)sTitle
.c_str());
943 if (pMenuOld
->HasAccels() || pMenu
->HasAccels())
946 // Need to rebuild accell table
950 #endif // wxUSE_ACCEL
954 } // end of wxMenuBar::Replace
956 bool wxMenuBar::Insert(
959 , const wxString
& rTitle
962 wxString sTitle
= wxPMTextToLabel(rTitle
);
964 if (!wxMenuBarBase::Insert( nPos
970 m_titles
.Insert( sTitle
976 pMenu
->m_vMenuData
.iPosition
= nPos
;
977 ::WinSendMsg( (HWND
)m_hMenu
979 ,(MPARAM
)&pMenu
->m_vMenuData
980 ,(MPARAM
)sTitle
.c_str()
983 if (pMenu
->HasAccels())
985 // need to rebuild accell table
988 #endif // wxUSE_ACCEL
992 } // end of wxMenuBar::Insert
994 bool wxMenuBar::Append(
996 , const wxString
& rsTitle
999 WXHMENU hSubmenu
= pMenu
? pMenu
->GetHMenu() : 0;
1001 wxCHECK_MSG(hSubmenu
, FALSE
, wxT("can't append invalid menu to menubar"));
1003 wxString sTitle
= wxPMTextToLabel(rsTitle
);
1005 if (!wxMenuBarBase::Append(pMenu
, sTitle
))
1008 m_titles
.Add(sTitle
);
1012 pMenu
->m_vMenuData
.iPosition
= MIT_END
;
1013 ::WinSendMsg((HWND
)m_hMenu
, MM_INSERTITEM
, (MPARAM
)&pMenu
->m_vMenuData
, (MPARAM
)sTitle
.c_str());
1015 if (pMenu
->HasAccels())
1018 // Need to rebuild accell table
1020 RebuildAccelTable();
1022 #endif // wxUSE_ACCEL
1026 } // end of wxMenuBar::Append
1028 wxMenu
* wxMenuBar::Remove(
1032 wxMenu
* pMenu
= wxMenuBarBase::Remove(nPos
);
1038 nId
= SHORT1FROMMR(::WinSendMsg( (HWND
)GetHmenu()
1039 ,MM_ITEMIDFROMPOSITION
1043 if (nId
== MIT_ERROR
)
1045 wxLogLastError(wxT("LogLastError"));
1050 ::WinSendMsg( (HWND
)GetHmenu()
1052 ,MPFROM2SHORT(nId
, TRUE
)
1057 if (pMenu
->HasAccels())
1060 // Need to rebuild accell table
1062 RebuildAccelTable();
1064 #endif // wxUSE_ACCEL
1067 m_titles
.RemoveAt(nPos
);
1069 } // end of wxMenuBar::Remove
1073 void wxMenuBar::RebuildAccelTable()
1076 // Merge the accelerators of all menus into one accel table
1078 size_t nAccelCount
= 0;
1080 size_t nCount
= GetMenuCount();
1081 wxMenuList::iterator it
;
1082 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
1084 nAccelCount
+= (*it
)->GetAccelCount();
1089 wxAcceleratorEntry
* pAccelEntries
= new wxAcceleratorEntry
[nAccelCount
];
1092 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
1094 nAccelCount
+= (*it
)->CopyAccels(&pAccelEntries
[nAccelCount
]);
1096 m_vAccelTable
= wxAcceleratorTable( nAccelCount
1099 delete [] pAccelEntries
;
1101 } // end of wxMenuBar::RebuildAccelTable
1103 #endif // wxUSE_ACCEL
1105 void wxMenuBar::Attach(
1109 wxMenuBarBase::Attach(pFrame
);
1112 RebuildAccelTable();
1114 // Ensure the accelerator table is set to the frame (not the client!)
1116 if (!::WinSetAccelTable( vHabmain
1117 ,m_vAccelTable
.GetHACCEL()
1118 ,(HWND
)pFrame
->GetFrame()
1120 wxLogLastError(wxT("WinSetAccelTable"));
1121 #endif // wxUSE_ACCEL
1122 } // end of wxMenuBar::Attach
1124 void wxMenuBar::Detach()
1126 ::WinDestroyWindow((HWND
)m_hMenu
);
1127 m_hMenu
= (WXHMENU
)NULL
;
1128 m_menuBarFrame
= NULL
;
1129 } // end of wxMenuBar::Detach
1131 // ---------------------------------------------------------------------------
1132 // wxMenuBar searching for menu items
1133 // ---------------------------------------------------------------------------
1136 // Find the itemString in menuString, and return the item id or wxNOT_FOUND
1138 int wxMenuBar::FindMenuItem(
1139 const wxString
& rMenuString
1140 , const wxString
& rItemString
1143 wxString sMenuLabel
= wxStripMenuCodes(rMenuString
);
1144 size_t nCount
= GetMenuCount(), i
;
1145 wxMenuList::const_iterator it
;
1146 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
1148 wxString sTitle
= wxStripMenuCodes(m_titles
[i
]);
1150 if (rMenuString
== sTitle
)
1151 return (*it
)->FindItem(rItemString
);
1154 } // end of wxMenuBar::FindMenuItem
1156 wxMenuItem
* wxMenuBar::FindItem(
1158 , wxMenu
** ppItemMenu
1164 wxMenuItem
* pItem
= NULL
;
1165 size_t nCount
= GetMenuCount(), i
;
1166 wxMenuList::const_iterator it
;
1167 for (i
= 0, it
= m_menus
.begin(); !pItem
&& (i
< nCount
); i
++, it
++)
1169 pItem
= (*it
)->FindItem( nId
1174 } // end of wxMenuBar::FindItem
1176 wxMenuItem
* wxMenuBar::FindItem(
1179 , wxMenu
** ppItemMenu
1185 wxMenuItem
* pItem
= NULL
;
1186 size_t nCount
= GetMenuCount(), i
;
1187 wxMenuList::const_iterator it
;
1188 for (i
= 0, it
= m_menus
.begin(); !pItem
&& (i
< nCount
); i
++, it
++)
1190 pItem
= (*it
)->FindItem( nId
1196 } // end of wxMenuBar::FindItem