1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/menu.cpp
3 // Purpose: wxMenu, wxMenuBar, wxMenuItem
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
26 #include "wx/ownerdrw.h"
29 #include "wx/os2/private.h"
31 // other standard headers
34 // ----------------------------------------------------------------------------
36 // ----------------------------------------------------------------------------
38 extern wxMenu
* wxCurrentPopupMenu
;
40 // ----------------------------------------------------------------------------
42 // ----------------------------------------------------------------------------
45 // The (popup) menu title has this special id
47 static const int idMenuTitle
= -3;
50 // The unique ID for Menus
52 USHORT
wxMenu::m_nextMenuId
= 0;
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 // ============================================================================
60 // ============================================================================
62 // ---------------------------------------------------------------------------
63 // wxMenu construction, adding and removing menu items
64 // ---------------------------------------------------------------------------
67 // Construct a menu with optional title (then use append)
72 m_nStartRadioGroup
= -1;
75 // Create the menu (to be used as a submenu or a popup)
77 if ((m_hMenu
= ::WinCreateWindow( HWND_DESKTOP
92 wxLogLastError(wxT("WinLoadMenu"));
94 m_vMenuData
.iPosition
= 0;
95 m_vMenuData
.afStyle
= MIS_SUBMENU
| MIS_TEXT
;
96 m_vMenuData
.afAttribute
= (USHORT
)0;
97 m_vMenuData
.id
= m_nextMenuId
++;
98 m_vMenuData
.hwndSubMenu
= m_hMenu
;
99 m_vMenuData
.hItem
= NULLHANDLE
;
102 // If we have a title, insert it in the beginning of the menu
104 if (!m_title
.empty())
113 } // end of wxMenu::Init
116 // The wxWindow destructor will take care of deleting the submenus.
121 // We should free PM resources only if PM doesn't do it for us
122 // which happens if we're attached to a menubar or a submenu of another
124 if (!IsAttached() && !GetParent())
126 if (!::WinDestroyWindow((HWND
)GetHmenu()) )
128 wxLogLastError(wxT("WinDestroyWindow"));
136 WX_CLEAR_ARRAY(m_vAccels
);
137 #endif // wxUSE_ACCEL
138 } // end of wxMenu::~wxMenu
142 // this will take effect during the next call to Append()
144 } // end of wxMenu::Break
147 wxMenuBarBase
* pMenubar
150 wxMenuBase::Attach(pMenubar
);
152 } // end of wxMenu::Break;
156 int wxMenu::FindAccel(
161 size_t nCount
= m_vAccels
.GetCount();
163 for (n
= 0; n
< nCount
; n
++)
164 if (m_vAccels
[n
]->m_command
== nId
)
167 } // end of wxMenu::FindAccel
169 void wxMenu::UpdateAccel(
173 if (pItem
->IsSubMenu())
175 wxMenu
* pSubmenu
= pItem
->GetSubMenu();
176 wxMenuItemList::compatibility_iterator node
= pSubmenu
->GetMenuItems().GetFirst();
180 UpdateAccel(node
->GetData());
181 node
= node
->GetNext();
184 else if (!pItem
->IsSeparator())
187 // Recurse upwards: we should only modify m_accels of the top level
188 // menus, not of the submenus as wxMenuBar doesn't look at them
189 // (alternative and arguable cleaner solution would be to recurse
190 // downwards in GetAccelCount() and CopyAccels())
194 GetParent()->UpdateAccel(pItem
);
199 // Find the (new) accel for this item
201 wxAcceleratorEntry
* pAccel
= wxAcceleratorEntry::Create(pItem
->GetItemLabel());
204 pAccel
->m_command
= pItem
->GetId();
209 size_t n
= FindAccel(pItem
->GetId());
211 if (n
== (size_t)wxNOT_FOUND
)
214 // No old, add new if any
217 m_vAccels
.Add(pAccel
);
224 // Replace old with new or just remove the old one if no new
228 m_vAccels
[n
] = pAccel
;
230 m_vAccels
.RemoveAt(n
);
235 GetMenuBar()->RebuildAccelTable();
238 } // wxMenu::UpdateAccel
240 #endif // wxUSE_ACCEL
243 // Append a new item or submenu to the menu
245 bool wxMenu::DoInsertOrAppend( wxMenuItem
* pItem
,
248 wxMenu
* pSubmenu
= pItem
->GetSubMenu();
249 MENUITEM
& rItem
= (pSubmenu
!= NULL
)?pSubmenu
->m_vMenuData
:
257 #endif // wxUSE_ACCEL
260 // If "Break" has just been called, insert a menu break before this item
261 // (and don't forget to reset the flag)
265 rItem
.afStyle
|= MIS_BREAK
;
270 // Id is the numeric id for normal menu items and HMENU for submenus as
271 // required by ::MM_INSERTITEM message API
273 if (pSubmenu
!= NULL
)
275 wxASSERT_MSG(pSubmenu
->GetHMenu(), wxT("invalid submenu"));
276 pSubmenu
->SetParent(this);
278 rItem
.iPosition
= 0; // submenus have a 0 position
279 rItem
.id
= (USHORT
)pSubmenu
->GetHMenu();
280 rItem
.afStyle
|= MIS_SUBMENU
| MIS_TEXT
;
284 rItem
.id
= (USHORT
)pItem
->GetId();
289 #if wxUSE_OWNER_DRAWN
290 if (pItem
->IsOwnerDrawn())
293 // Want to get {Measure|Draw}Item messages?
294 // item draws itself, passing pointer to data doesn't work in OS/2
295 // Will eventually need to set the image handle somewhere into vItem.hItem
297 rItem
.afStyle
|= MIS_OWNERDRAW
;
299 rItem
.hItem
= (HBITMAP
)pItem
->GetBitmap().GetHBITMAP();
300 pItem
->m_vMenuData
.afStyle
= rItem
.afStyle
;
301 pItem
->m_vMenuData
.hItem
= rItem
.hItem
;
305 if (pItem
->IsSeparator())
307 rItem
.afStyle
= MIS_SEPARATOR
;
311 if (pItem
->GetId() == idMenuTitle
)
313 // Item is an unselectable title to be passed via pData
314 rItem
.afStyle
= MIS_STATIC
;
319 // Menu is just a normal string (passed in data parameter)
321 rItem
.afStyle
|= MIS_TEXT
;
323 pData
= (char*) pItem
->GetItemLabel().wx_str();
326 if (nPos
== (size_t)-1)
328 rItem
.iPosition
= MIT_END
;
332 rItem
.iPosition
= (SHORT
)nPos
;
337 rc
= (APIRET
)::WinSendMsg( GetHmenu()
342 #if wxUSE_OWNER_DRAWN
343 if (pItem
->IsOwnerDrawn())
347 ::WinSendMsg( GetHmenu()
349 ,MPFROM2SHORT( (USHORT
)pItem
->GetId()
357 if (rc
== (APIRET
)MIT_MEMERROR
|| rc
== (APIRET
)MIT_ERROR
)
359 vError
= ::WinGetLastError(vHabmain
);
360 sError
= wxPMErrorToStr(vError
);
361 wxLogError(wxT("Error inserting or appending a menuitem. Error: %s\n"), sError
.c_str());
362 wxLogLastError(wxT("Insert or AppendMenu"));
367 // If we're already attached to the menubar, we must update it
369 if (IsAttached() && GetMenuBar()->IsAttached())
371 GetMenuBar()->Refresh();
375 } // end of wxMenu::DoInsertOrAppend
377 void wxMenu::EndRadioGroup()
380 // We're not inside a radio group any longer
382 m_nStartRadioGroup
= -1;
383 } // end of wxMenu::EndRadioGroup
385 wxMenuItem
* wxMenu::DoAppend( wxMenuItem
* pItem
)
387 wxCHECK_MSG( pItem
, NULL
, wxT("NULL item in wxMenu::DoAppend") );
391 if (pItem
->GetKind() == wxITEM_RADIO
)
393 int nCount
= GetMenuItemCount();
395 if (m_nStartRadioGroup
== -1)
398 // Start a new radio group
400 m_nStartRadioGroup
= nCount
;
403 // For now it has just one element
405 pItem
->SetAsRadioGroupStart();
406 pItem
->SetRadioGroupEnd(m_nStartRadioGroup
);
409 // Ensure that we have a checked item in the radio group
413 else // extend the current radio group
416 // We need to update its end item
418 pItem
->SetRadioGroupStart(m_nStartRadioGroup
);
420 wxMenuItemList::compatibility_iterator node
= GetMenuItems().Item(m_nStartRadioGroup
);
424 node
->GetData()->SetRadioGroupEnd(nCount
);
428 wxFAIL_MSG( wxT("where is the radio group start item?") );
432 else // not a radio item
437 if (!wxMenuBase::DoAppend(pItem
) || !DoInsertOrAppend(pItem
))
444 // Check the item initially
449 } // end of wxMenu::DoAppend
451 wxMenuItem
* wxMenu::DoInsert(
456 if ( wxMenuBase::DoInsert( nPos
458 DoInsertOrAppend( pItem
464 } // end of wxMenu::DoInsert
466 wxMenuItem
* wxMenu::DoRemove(
471 // We need to find the items position in the child list
474 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
476 for (nPos
= 0; node
; nPos
++)
478 if (node
->GetData() == pItem
)
480 node
= node
->GetNext();
484 // DoRemove() (unlike Remove) can only be called for existing item!
486 wxCHECK_MSG(node
, NULL
, wxT("bug in wxMenu::Remove logic"));
490 // Remove the corresponding accel from the accel table
492 int n
= FindAccel(pItem
->GetId());
494 if (n
!= wxNOT_FOUND
)
497 m_vAccels
.RemoveAt(n
);
500 #endif // wxUSE_ACCEL
502 // Remove the item from the menu
504 ::WinSendMsg( GetHmenu()
506 ,MPFROM2SHORT(pItem
->GetId(), TRUE
)
509 if (IsAttached() && GetMenuBar()->IsAttached())
512 // Otherwise, the chane won't be visible
514 GetMenuBar()->Refresh();
518 // And from internal data structures
520 return wxMenuBase::DoRemove(pItem
);
521 } // end of wxMenu::DoRemove
523 // ---------------------------------------------------------------------------
524 // accelerator helpers
525 // ---------------------------------------------------------------------------
530 // Create the wxAcceleratorEntries for our accels and put them into provided
531 // array - return the number of accels we have
533 size_t wxMenu::CopyAccels(
534 wxAcceleratorEntry
* pAccels
537 size_t nCount
= GetAccelCount();
539 for (size_t n
= 0; n
< nCount
; n
++)
541 *pAccels
++ = *m_vAccels
[n
];
544 } // end of wxMenu::CopyAccels
546 #endif // wxUSE_ACCEL
548 // ---------------------------------------------------------------------------
550 // ---------------------------------------------------------------------------
552 void wxMenu::SetTitle( const wxString
& rLabel
)
554 bool bHasNoTitle
= m_title
.empty();
555 HWND hMenu
= GetHmenu();
562 if (!::WinSetWindowText(hMenu
, rLabel
.c_str()))
564 wxLogLastError(wxT("SetMenuTitle"));
572 ::WinSendMsg( GetHmenu()
574 ,MPFROM2SHORT(hMenu
, TRUE
)
583 if (!::WinSetWindowText(hMenu
, rLabel
.c_str()))
585 wxLogLastError(wxT("SetMenuTitle"));
589 } // end of wxMenu::SetTitle
591 // ---------------------------------------------------------------------------
593 // ---------------------------------------------------------------------------
595 bool wxMenu::OS2Command( WXUINT
WXUNUSED(uParam
),
599 // Ignore commands from the menu title
602 if (vId
!= (WXWORD
)idMenuTitle
)
605 ,(int)::WinSendMsg( GetHmenu()
613 } // end of wxMenu::OS2Command
615 // ---------------------------------------------------------------------------
617 // ---------------------------------------------------------------------------
619 wxWindow
* wxMenu::GetWindow() const
621 if (m_invokingWindow
!= NULL
)
622 return m_invokingWindow
;
623 else if ( GetMenuBar() != NULL
)
624 return GetMenuBar()->GetFrame();
627 } // end of wxMenu::GetWindow
629 // recursive search for item by id
630 wxMenuItem
* wxMenu::FindItem(
633 , wxMenu
** ppItemMenu
639 wxMenuItem
* pItem
= NULL
;
641 for ( wxMenuItemList::compatibility_iterator node
= m_items
.GetFirst();
643 node
= node
->GetNext() )
645 pItem
= node
->GetData();
647 if ( pItem
->GetId() == nItemId
&& pItem
->m_vMenuData
.hItem
== hItem
)
650 *ppItemMenu
= (wxMenu
*)this;
652 else if ( pItem
->IsSubMenu() )
654 pItem
= pItem
->GetSubMenu()->FindItem( nItemId
663 // don't exit the loop
668 } // end of wxMenu::FindItem
670 // ---------------------------------------------------------------------------
672 // ---------------------------------------------------------------------------
674 void wxMenuBar::Init()
676 m_eventHandler
= this;
677 m_menuBarFrame
= NULL
;
679 } // end of wxMenuBar::Init
681 wxMenuBar::wxMenuBar()
684 } // end of wxMenuBar::wxMenuBar
686 wxMenuBar::wxMenuBar(
687 long WXUNUSED(lStyle
)
691 } // end of wxMenuBar::wxMenuBar
693 wxMenuBar::wxMenuBar(
696 , const wxString sTitles
[]
697 , long WXUNUSED(lStyle
)
702 m_titles
.Alloc(nCount
);
703 for ( int i
= 0; i
< nCount
; i
++ )
705 m_menus
.Append(vMenus
[i
]);
706 m_titles
.Add(sTitles
[i
]);
707 vMenus
[i
]->Attach(this);
709 } // end of wxMenuBar::wxMenuBar
711 wxMenuBar::~wxMenuBar()
714 // We should free PM's resources only if PM doesn't do it for us
715 // which happens if we're attached to a frame
717 if (m_hMenu
&& !IsAttached())
719 ::WinDestroyWindow((HMENU
)m_hMenu
);
720 m_hMenu
= (WXHMENU
)NULL
;
722 } // end of wxMenuBar::~wxMenuBar
724 // ---------------------------------------------------------------------------
726 // ---------------------------------------------------------------------------
728 void wxMenuBar::Refresh()
730 wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
732 WinSendMsg(GetWinHwnd(m_menuBarFrame
), WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
733 } // end of wxMenuBar::Refresh
735 WXHMENU
wxMenuBar::Create()
742 wxCHECK_MSG(!m_hMenu
, TRUE
, wxT("menubar already created"));
745 // Menubars should be associated with a frame otherwise they are popups
747 if (m_menuBarFrame
!= NULL
)
748 hFrame
= GetWinHwnd(m_menuBarFrame
);
750 hFrame
= HWND_DESKTOP
;
752 // Create an empty menu and then fill it with insertions
754 if ((m_hMenu
= ::WinCreateWindow( hFrame
757 ,MS_ACTIONBAR
| WS_SYNCPAINT
| WS_VISIBLE
769 wxLogLastError(wxT("WinLoadMenu"));
773 size_t nCount
= GetMenuCount(), i
;
774 wxMenuList::iterator it
;
775 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
783 // Set the parent and owner of the submenues to be the menubar, not the desktop
785 hSubMenu
= (*it
)->m_vMenuData
.hwndSubMenu
;
786 if (!::WinSetParent((*it
)->m_vMenuData
.hwndSubMenu
, m_hMenu
, FALSE
))
788 vError
= ::WinGetLastError(vHabmain
);
789 sError
= wxPMErrorToStr(vError
);
790 wxLogError(wxT("Error setting parent for submenu. Error: %s\n"), sError
.c_str());
794 if (!::WinSetOwner((*it
)->m_vMenuData
.hwndSubMenu
, m_hMenu
))
796 vError
= ::WinGetLastError(vHabmain
);
797 sError
= wxPMErrorToStr(vError
);
798 wxLogError(wxT("Error setting parent for submenu. Error: %s\n"), sError
.c_str());
802 (*it
)->m_vMenuData
.iPosition
= (SHORT
)i
;
804 rc
= (APIRET
)::WinSendMsg(m_hMenu
, MM_INSERTITEM
, (MPARAM
)&(*it
)->m_vMenuData
, (MPARAM
)m_titles
[i
].wx_str());
805 if (rc
== (APIRET
)MIT_MEMERROR
|| rc
== (APIRET
)MIT_ERROR
)
807 vError
= ::WinGetLastError(vHabmain
);
808 sError
= wxPMErrorToStr(vError
);
809 wxLogError(wxT("Error inserting or appending a menuitem. Error: %s\n"), sError
.c_str());
815 } // end of wxMenuBar::Create
817 // ---------------------------------------------------------------------------
818 // wxMenuBar functions to work with the top level submenus
819 // ---------------------------------------------------------------------------
822 // NB: we don't support owner drawn top level items for now, if we do these
823 // functions would have to be changed to use wxMenuItem as well
825 void wxMenuBar::EnableTop(
830 wxCHECK_RET(IsAttached(), wxT("doesn't work with unattached menubars"));
835 uFlag
= MIA_DISABLED
;
837 nId
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0));
838 if (nId
== MIT_ERROR
)
840 wxLogLastError(wxT("LogLastError"));
843 ::WinSendMsg((HWND
)m_hMenu
, MM_SETITEMATTR
, MPFROM2SHORT(nId
, TRUE
), MPFROM2SHORT(MIA_DISABLED
, uFlag
));
845 } // end of wxMenuBar::EnableTop
847 void wxMenuBar::SetMenuLabel(
849 , const wxString
& rLabel
855 wxCHECK_RET(nPos
< GetMenuCount(), wxT("invalid menu index"));
856 m_titles
[nPos
] = rLabel
;
863 nId
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0));
864 if (nId
== MIT_ERROR
)
866 wxLogLastError(wxT("LogLastError"));
869 if(!::WinSendMsg( (HWND
)m_hMenu
871 ,MPFROM2SHORT(nId
, TRUE
)
875 wxLogLastError(wxT("QueryItem"));
879 if (::WinSendMsg(GetHmenu(), MM_SETITEMTEXT
, MPFROMSHORT(nId
), (MPARAM
)rLabel
.wx_str()));
881 wxLogLastError(wxT("ModifyMenu"));
884 } // end of wxMenuBar::SetMenuLabel
886 wxString
wxMenuBar::GetMenuLabel(
890 wxCHECK_MSG( nPos
< GetMenuCount(), wxEmptyString
,
891 wxT("invalid menu index in wxMenuBar::GetMenuLabel") );
892 return m_titles
[nPos
];
893 } // end of wxMenuBar::GetMenuLabel
895 // ---------------------------------------------------------------------------
896 // wxMenuBar construction
897 // ---------------------------------------------------------------------------
899 wxMenu
* wxMenuBar::Replace(
902 , const wxString
& rTitle
906 wxString sTitle
= wxPMTextToLabel(rTitle
);
907 wxMenu
* pMenuOld
= wxMenuBarBase::Replace( nPos
913 nId
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0));
914 if (nId
== MIT_ERROR
)
916 wxLogLastError(wxT("LogLastError"));
921 m_titles
[nPos
] = sTitle
;
924 ::WinSendMsg((HWND
)m_hMenu
, MM_REMOVEITEM
, MPFROM2SHORT(nId
, TRUE
), (MPARAM
)0);
925 ::WinSendMsg((HWND
)m_hMenu
, MM_INSERTITEM
, (MPARAM
)&pMenu
->m_vMenuData
, (MPARAM
)sTitle
.wx_str());
928 if (pMenuOld
->HasAccels() || pMenu
->HasAccels())
931 // Need to rebuild accell table
935 #endif // wxUSE_ACCEL
939 } // end of wxMenuBar::Replace
941 bool wxMenuBar::Insert( size_t nPos
,
943 const wxString
& rTitle
)
945 wxString sTitle
= wxPMTextToLabel(rTitle
);
947 if (!wxMenuBarBase::Insert( nPos
, pMenu
, sTitle
))
950 m_titles
.Insert( sTitle
, nPos
);
954 pMenu
->m_vMenuData
.iPosition
= (SHORT
)nPos
;
955 ::WinSendMsg( (HWND
)m_hMenu
957 ,(MPARAM
)&pMenu
->m_vMenuData
958 ,(MPARAM
)sTitle
.wx_str()
961 if (pMenu
->HasAccels())
963 // need to rebuild accell table
966 #endif // wxUSE_ACCEL
971 } // end of wxMenuBar::Insert
973 bool wxMenuBar::Append( wxMenu
* pMenu
,
974 const wxString
& rsTitle
)
976 WXHMENU hSubmenu
= pMenu
? pMenu
->GetHMenu() : 0;
978 wxCHECK_MSG(hSubmenu
, false, wxT("can't append invalid menu to menubar"));
980 wxString sTitle
= wxPMTextToLabel(rsTitle
);
982 if (!wxMenuBarBase::Append(pMenu
, sTitle
))
985 m_titles
.Add(sTitle
);
989 pMenu
->m_vMenuData
.iPosition
= MIT_END
;
990 ::WinSendMsg((HWND
)m_hMenu
, MM_INSERTITEM
, (MPARAM
)&pMenu
->m_vMenuData
, (MPARAM
)sTitle
.wx_str());
992 if (pMenu
->HasAccels())
995 // Need to rebuild accell table
999 #endif // wxUSE_ACCEL
1003 } // end of wxMenuBar::Append
1005 wxMenu
* wxMenuBar::Remove(
1009 wxMenu
* pMenu
= wxMenuBarBase::Remove(nPos
);
1015 nId
= SHORT1FROMMR(::WinSendMsg( (HWND
)GetHmenu()
1016 ,MM_ITEMIDFROMPOSITION
1020 if (nId
== MIT_ERROR
)
1022 wxLogLastError(wxT("LogLastError"));
1027 ::WinSendMsg( (HWND
)GetHmenu()
1029 ,MPFROM2SHORT(nId
, TRUE
)
1034 if (pMenu
->HasAccels())
1037 // Need to rebuild accell table
1039 RebuildAccelTable();
1041 #endif // wxUSE_ACCEL
1044 m_titles
.RemoveAt(nPos
);
1046 } // end of wxMenuBar::Remove
1050 void wxMenuBar::RebuildAccelTable()
1053 // Merge the accelerators of all menus into one accel table
1055 size_t nAccelCount
= 0;
1057 size_t nCount
= GetMenuCount();
1058 wxMenuList::iterator it
;
1059 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
1061 nAccelCount
+= (*it
)->GetAccelCount();
1066 wxAcceleratorEntry
* pAccelEntries
= new wxAcceleratorEntry
[nAccelCount
];
1069 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
1071 nAccelCount
+= (*it
)->CopyAccels(&pAccelEntries
[nAccelCount
]);
1073 m_vAccelTable
= wxAcceleratorTable( nAccelCount
1076 delete [] pAccelEntries
;
1078 } // end of wxMenuBar::RebuildAccelTable
1080 #endif // wxUSE_ACCEL
1082 void wxMenuBar::Attach(
1086 wxMenuBarBase::Attach(pFrame
);
1089 RebuildAccelTable();
1091 // Ensure the accelerator table is set to the frame (not the client!)
1093 if (!::WinSetAccelTable( vHabmain
1094 ,m_vAccelTable
.GetHACCEL()
1095 ,(HWND
)pFrame
->GetFrame()
1098 wxLogLastError(wxT("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(), i
;
1124 wxMenuList::const_iterator it
;
1125 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
1127 wxString sTitle
= wxStripMenuCodes(m_titles
[i
]);
1129 if (rMenuString
== sTitle
)
1130 return (*it
)->FindItem(rItemString
);
1133 } // end of wxMenuBar::FindMenuItem
1135 wxMenuItem
* wxMenuBar::FindItem(
1137 , wxMenu
** ppItemMenu
1143 wxMenuItem
* pItem
= NULL
;
1144 size_t nCount
= GetMenuCount(), i
;
1145 wxMenuList::const_iterator it
;
1146 for (i
= 0, it
= m_menus
.begin(); !pItem
&& (i
< nCount
); i
++, it
++)
1148 pItem
= (*it
)->FindItem( nId
1153 } // end of wxMenuBar::FindItem
1155 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
1175 } // end of wxMenuBar::FindItem