1 /////////////////////////////////////////////////////////////////////////////
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"
25 #include "wx/ownerdrw.h"
28 #include "wx/os2/private.h"
30 // other standard headers
33 // ----------------------------------------------------------------------------
35 // ----------------------------------------------------------------------------
37 extern wxMenu
* wxCurrentPopupMenu
;
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
44 // The (popup) menu title has this special id
46 static const int idMenuTitle
= -3;
49 // The unique ID for Menus
51 USHORT
wxMenu::m_nextMenuId
= 0;
53 // ----------------------------------------------------------------------------
55 // ----------------------------------------------------------------------------
57 IMPLEMENT_DYNAMIC_CLASS(wxMenu
, wxEvtHandler
)
58 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
, wxEvtHandler
)
60 // ============================================================================
62 // ============================================================================
64 // ---------------------------------------------------------------------------
65 // wxMenu construction, adding and removing menu items
66 // ---------------------------------------------------------------------------
69 // Construct a menu with optional title (then use append)
74 m_nStartRadioGroup
= -1;
77 // Create the menu (to be used as a submenu or a popup)
79 if ((m_hMenu
= ::WinCreateWindow( HWND_DESKTOP
94 wxLogLastError(wxT("WinLoadMenu"));
96 m_vMenuData
.iPosition
= 0;
97 m_vMenuData
.afStyle
= MIS_SUBMENU
| MIS_TEXT
;
98 m_vMenuData
.afAttribute
= (USHORT
)0;
99 m_vMenuData
.id
= m_nextMenuId
++;
100 m_vMenuData
.hwndSubMenu
= m_hMenu
;
101 m_vMenuData
.hItem
= NULLHANDLE
;
104 // If we have a title, insert it in the beginning of the menu
106 if (!m_title
.empty())
115 } // end of wxMenu::Init
118 // The wxWindow destructor will take care of deleting the submenus.
123 // We should free PM resources only if PM doesn't do it for us
124 // which happens if we're attached to a menubar or a submenu of another
126 if (!IsAttached() && !GetParent())
128 if (!::WinDestroyWindow((HWND
)GetHmenu()) )
130 wxLogLastError(wxT("WinDestroyWindow"));
138 WX_CLEAR_ARRAY(m_vAccels
);
139 #endif // wxUSE_ACCEL
140 } // end of wxMenu::~wxMenu
144 // this will take effect during the next call to Append()
146 } // end of wxMenu::Break
149 wxMenuBarBase
* pMenubar
152 wxMenuBase::Attach(pMenubar
);
154 } // end of wxMenu::Break;
158 int wxMenu::FindAccel(
163 size_t nCount
= m_vAccels
.GetCount();
165 for (n
= 0; n
< nCount
; n
++)
166 if (m_vAccels
[n
]->m_command
== nId
)
169 } // end of wxMenu::FindAccel
171 void wxMenu::UpdateAccel(
175 if (pItem
->IsSubMenu())
177 wxMenu
* pSubmenu
= pItem
->GetSubMenu();
178 wxMenuItemList::compatibility_iterator node
= pSubmenu
->GetMenuItems().GetFirst();
182 UpdateAccel(node
->GetData());
183 node
= node
->GetNext();
186 else if (!pItem
->IsSeparator())
189 // Recurse upwards: we should only modify m_accels of the top level
190 // menus, not of the submenus as wxMenuBar doesn't look at them
191 // (alternative and arguable cleaner solution would be to recurse
192 // downwards in GetAccelCount() and CopyAccels())
196 GetParent()->UpdateAccel(pItem
);
201 // Find the (new) accel for this item
203 wxAcceleratorEntry
* pAccel
= wxGetAccelFromString(pItem
->GetText());
206 pAccel
->m_command
= pItem
->GetId();
211 size_t n
= FindAccel(pItem
->GetId());
213 if (n
== (size_t)wxNOT_FOUND
)
216 // No old, add new if any
219 m_vAccels
.Add(pAccel
);
226 // Replace old with new or just remove the old one if no new
230 m_vAccels
[n
] = pAccel
;
232 m_vAccels
.RemoveAt(n
);
237 GetMenuBar()->RebuildAccelTable();
240 } // wxMenu::UpdateAccel
242 #endif // wxUSE_ACCEL
245 // Append a new item or submenu to the menu
247 bool wxMenu::DoInsertOrAppend( wxMenuItem
* pItem
,
250 wxMenu
* pSubmenu
= pItem
->GetSubMenu();
251 MENUITEM
& rItem
= (pSubmenu
!= NULL
)?pSubmenu
->m_vMenuData
:
259 #endif // wxUSE_ACCEL
262 // If "Break" has just been called, insert a menu break before this item
263 // (and don't forget to reset the flag)
267 rItem
.afStyle
|= MIS_BREAK
;
272 // Id is the numeric id for normal menu items and HMENU for submenus as
273 // required by ::MM_INSERTITEM message API
275 if (pSubmenu
!= NULL
)
277 wxASSERT_MSG(pSubmenu
->GetHMenu(), wxT("invalid submenu"));
278 pSubmenu
->SetParent(this);
280 rItem
.iPosition
= 0; // submenus have a 0 position
281 rItem
.id
= (USHORT
)pSubmenu
->GetHMenu();
282 rItem
.afStyle
|= MIS_SUBMENU
| MIS_TEXT
;
286 rItem
.id
= (USHORT
)pItem
->GetId();
291 #if wxUSE_OWNER_DRAWN
292 if (pItem
->IsOwnerDrawn())
295 // Want to get {Measure|Draw}Item messages?
296 // item draws itself, passing pointer to data doesn't work in OS/2
297 // Will eventually need to set the image handle somewhere into vItem.hItem
299 rItem
.afStyle
|= MIS_OWNERDRAW
;
301 rItem
.hItem
= (HBITMAP
)pItem
->GetBitmap().GetHBITMAP();
302 pItem
->m_vMenuData
.afStyle
= rItem
.afStyle
;
303 pItem
->m_vMenuData
.hItem
= rItem
.hItem
;
307 if (pItem
->IsSeparator())
309 rItem
.afStyle
= MIS_SEPARATOR
;
313 if (pItem
->GetId() == idMenuTitle
)
315 // Item is an unselectable title to be passed via pData
316 rItem
.afStyle
= MIS_STATIC
;
321 // Menu is just a normal string (passed in data parameter)
323 rItem
.afStyle
|= MIS_TEXT
;
325 pData
= (char*)pItem
->GetText().c_str();
328 if (nPos
== (size_t)-1)
330 rItem
.iPosition
= MIT_END
;
334 rItem
.iPosition
= (SHORT
)nPos
;
339 rc
= (APIRET
)::WinSendMsg( GetHmenu()
344 #if wxUSE_OWNER_DRAWN
345 if (pItem
->IsOwnerDrawn())
349 ::WinSendMsg( GetHmenu()
351 ,MPFROM2SHORT( (USHORT
)pItem
->GetId()
359 if (rc
== (APIRET
)MIT_MEMERROR
|| rc
== (APIRET
)MIT_ERROR
)
361 vError
= ::WinGetLastError(vHabmain
);
362 sError
= wxPMErrorToStr(vError
);
363 wxLogError(wxT("Error inserting or appending a menuitem. Error: %s\n"), sError
.c_str());
364 wxLogLastError(wxT("Insert or AppendMenu"));
369 // If we're already attached to the menubar, we must update it
371 if (IsAttached() && GetMenuBar()->IsAttached())
373 GetMenuBar()->Refresh();
377 } // end of wxMenu::DoInsertOrAppend
379 void wxMenu::EndRadioGroup()
382 // We're not inside a radio group any longer
384 m_nStartRadioGroup
= -1;
385 } // end of wxMenu::EndRadioGroup
387 wxMenuItem
* wxMenu::DoAppend( wxMenuItem
* pItem
)
389 wxCHECK_MSG( pItem
, NULL
, _T("NULL item in wxMenu::DoAppend") );
393 if (pItem
->GetKind() == wxITEM_RADIO
)
395 int nCount
= GetMenuItemCount();
397 if (m_nStartRadioGroup
== -1)
400 // Start a new radio group
402 m_nStartRadioGroup
= nCount
;
405 // For now it has just one element
407 pItem
->SetAsRadioGroupStart();
408 pItem
->SetRadioGroupEnd(m_nStartRadioGroup
);
411 // Ensure that we have a checked item in the radio group
415 else // extend the current radio group
418 // We need to update its end item
420 pItem
->SetRadioGroupStart(m_nStartRadioGroup
);
422 wxMenuItemList::compatibility_iterator node
= GetMenuItems().Item(m_nStartRadioGroup
);
426 node
->GetData()->SetRadioGroupEnd(nCount
);
430 wxFAIL_MSG( _T("where is the radio group start item?") );
434 else // not a radio item
439 if (!wxMenuBase::DoAppend(pItem
) || !DoInsertOrAppend(pItem
))
446 // Check the item initially
451 } // end of wxMenu::DoAppend
453 wxMenuItem
* wxMenu::DoInsert(
458 if ( wxMenuBase::DoInsert( nPos
460 DoInsertOrAppend( pItem
466 } // end of wxMenu::DoInsert
468 wxMenuItem
* wxMenu::DoRemove(
473 // We need to find the items position in the child list
476 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
478 for (nPos
= 0; node
; nPos
++)
480 if (node
->GetData() == pItem
)
482 node
= node
->GetNext();
486 // DoRemove() (unlike Remove) can only be called for existing item!
488 wxCHECK_MSG(node
, NULL
, wxT("bug in wxMenu::Remove logic"));
492 // Remove the corresponding accel from the accel table
494 int n
= FindAccel(pItem
->GetId());
496 if (n
!= wxNOT_FOUND
)
499 m_vAccels
.RemoveAt(n
);
502 #endif // wxUSE_ACCEL
504 // Remove the item from the menu
506 ::WinSendMsg( GetHmenu()
508 ,MPFROM2SHORT(pItem
->GetId(), TRUE
)
511 if (IsAttached() && GetMenuBar()->IsAttached())
514 // Otherwise, the chane won't be visible
516 GetMenuBar()->Refresh();
520 // And from internal data structures
522 return wxMenuBase::DoRemove(pItem
);
523 } // end of wxMenu::DoRemove
525 // ---------------------------------------------------------------------------
526 // accelerator helpers
527 // ---------------------------------------------------------------------------
532 // Create the wxAcceleratorEntries for our accels and put them into provided
533 // array - return the number of accels we have
535 size_t wxMenu::CopyAccels(
536 wxAcceleratorEntry
* pAccels
539 size_t nCount
= GetAccelCount();
541 for (size_t n
= 0; n
< nCount
; n
++)
543 *pAccels
++ = *m_vAccels
[n
];
546 } // end of wxMenu::CopyAccels
548 #endif // wxUSE_ACCEL
550 // ---------------------------------------------------------------------------
552 // ---------------------------------------------------------------------------
554 void wxMenu::SetTitle( const wxString
& rLabel
)
556 bool bHasNoTitle
= m_title
.empty();
557 HWND hMenu
= GetHmenu();
564 if (!::WinSetWindowText(hMenu
, (PSZ
)rLabel
.c_str()))
566 wxLogLastError(wxT("SetMenuTitle"));
574 ::WinSendMsg( GetHmenu()
576 ,MPFROM2SHORT(hMenu
, TRUE
)
585 if (!::WinSetWindowText(hMenu
, (PSZ
)rLabel
.c_str()))
587 wxLogLastError(wxT("SetMenuTitle"));
591 } // end of wxMenu::SetTitle
593 // ---------------------------------------------------------------------------
595 // ---------------------------------------------------------------------------
597 bool wxMenu::OS2Command(
598 WXUINT
WXUNUSED(uParam
)
603 // Ignore commands from the menu title
606 if (vId
!= (WXWORD
)idMenuTitle
)
609 ,(int)::WinSendMsg( GetHmenu()
617 } // end of wxMenu::OS2Command
619 // ---------------------------------------------------------------------------
621 // ---------------------------------------------------------------------------
623 wxWindow
* wxMenu::GetWindow() const
625 if (m_invokingWindow
!= NULL
)
626 return m_invokingWindow
;
627 else if ( GetMenuBar() != NULL
)
628 return GetMenuBar()->GetFrame();
631 } // end of wxMenu::GetWindow
633 // recursive search for item by id
634 wxMenuItem
* wxMenu::FindItem(
637 , wxMenu
** ppItemMenu
643 wxMenuItem
* pItem
= NULL
;
645 for ( wxMenuItemList::compatibility_iterator node
= m_items
.GetFirst();
647 node
= node
->GetNext() )
649 pItem
= node
->GetData();
651 if ( pItem
->GetId() == nItemId
&& pItem
->m_vMenuData
.hItem
== hItem
)
654 *ppItemMenu
= (wxMenu
*)this;
656 else if ( pItem
->IsSubMenu() )
658 pItem
= pItem
->GetSubMenu()->FindItem( nItemId
667 // don't exit the loop
672 } // end of wxMenu::FindItem
674 // ---------------------------------------------------------------------------
676 // ---------------------------------------------------------------------------
678 void wxMenuBar::Init()
680 m_eventHandler
= this;
681 m_menuBarFrame
= NULL
;
683 } // end of wxMenuBar::Init
685 wxMenuBar::wxMenuBar()
688 } // end of wxMenuBar::wxMenuBar
690 wxMenuBar::wxMenuBar(
691 long WXUNUSED(lStyle
)
695 } // end of wxMenuBar::wxMenuBar
697 wxMenuBar::wxMenuBar(
700 , const wxString sTitles
[]
701 , long WXUNUSED(lStyle
)
706 m_titles
.Alloc(nCount
);
707 for ( int i
= 0; i
< nCount
; i
++ )
709 m_menus
.Append(vMenus
[i
]);
710 m_titles
.Add(sTitles
[i
]);
711 vMenus
[i
]->Attach(this);
713 } // end of wxMenuBar::wxMenuBar
715 wxMenuBar::~wxMenuBar()
718 // We should free PM's resources only if PM doesn't do it for us
719 // which happens if we're attached to a frame
721 if (m_hMenu
&& !IsAttached())
723 ::WinDestroyWindow((HMENU
)m_hMenu
);
724 m_hMenu
= (WXHMENU
)NULL
;
726 } // end of wxMenuBar::~wxMenuBar
728 // ---------------------------------------------------------------------------
730 // ---------------------------------------------------------------------------
732 void wxMenuBar::Refresh()
734 wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
736 WinSendMsg(GetWinHwnd(m_menuBarFrame
), WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
737 } // end of wxMenuBar::Refresh
739 WXHMENU
wxMenuBar::Create()
746 wxCHECK_MSG(!m_hMenu
, TRUE
, wxT("menubar already created"));
749 // Menubars should be associated with a frame otherwise they are popups
751 if (m_menuBarFrame
!= NULL
)
752 hFrame
= GetWinHwnd(m_menuBarFrame
);
754 hFrame
= HWND_DESKTOP
;
756 // Create an empty menu and then fill it with insertions
758 if ((m_hMenu
= ::WinCreateWindow( hFrame
761 ,MS_ACTIONBAR
| WS_SYNCPAINT
| WS_VISIBLE
773 wxLogLastError(wxT("WinLoadMenu"));
777 size_t nCount
= GetMenuCount(), i
;
778 wxMenuList::iterator it
;
779 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
787 // Set the parent and owner of the submenues to be the menubar, not the desktop
789 hSubMenu
= (*it
)->m_vMenuData
.hwndSubMenu
;
790 if (!::WinSetParent((*it
)->m_vMenuData
.hwndSubMenu
, m_hMenu
, FALSE
))
792 vError
= ::WinGetLastError(vHabmain
);
793 sError
= wxPMErrorToStr(vError
);
794 wxLogError(wxT("Error setting parent for submenu. Error: %s\n"), sError
.c_str());
798 if (!::WinSetOwner((*it
)->m_vMenuData
.hwndSubMenu
, m_hMenu
))
800 vError
= ::WinGetLastError(vHabmain
);
801 sError
= wxPMErrorToStr(vError
);
802 wxLogError(wxT("Error setting parent for submenu. Error: %s\n"), sError
.c_str());
806 (*it
)->m_vMenuData
.iPosition
= (SHORT
)i
;
808 rc
= (APIRET
)::WinSendMsg(m_hMenu
, MM_INSERTITEM
, (MPARAM
)&(*it
)->m_vMenuData
, (MPARAM
)m_titles
[i
].c_str());
809 if (rc
== (APIRET
)MIT_MEMERROR
|| rc
== (APIRET
)MIT_ERROR
)
811 vError
= ::WinGetLastError(vHabmain
);
812 sError
= wxPMErrorToStr(vError
);
813 wxLogError(wxT("Error inserting or appending a menuitem. Error: %s\n"), sError
.c_str());
819 } // end of wxMenuBar::Create
821 // ---------------------------------------------------------------------------
822 // wxMenuBar functions to work with the top level submenus
823 // ---------------------------------------------------------------------------
826 // NB: we don't support owner drawn top level items for now, if we do these
827 // functions would have to be changed to use wxMenuItem as well
829 void wxMenuBar::EnableTop(
834 wxCHECK_RET(IsAttached(), wxT("doesn't work with unattached menubars"));
839 uFlag
= MIA_DISABLED
;
841 nId
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0));
842 if (nId
== MIT_ERROR
)
844 wxLogLastError(wxT("LogLastError"));
847 ::WinSendMsg((HWND
)m_hMenu
, MM_SETITEMATTR
, MPFROM2SHORT(nId
, TRUE
), MPFROM2SHORT(MIA_DISABLED
, uFlag
));
849 } // end of wxMenuBar::EnableTop
851 void wxMenuBar::SetLabelTop(
853 , const wxString
& rLabel
859 wxCHECK_RET(nPos
< GetMenuCount(), wxT("invalid menu index"));
860 m_titles
[nPos
] = rLabel
;
867 nId
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0));
868 if (nId
== MIT_ERROR
)
870 wxLogLastError(wxT("LogLastError"));
873 if(!::WinSendMsg( (HWND
)m_hMenu
875 ,MPFROM2SHORT(nId
, TRUE
)
879 wxLogLastError(wxT("QueryItem"));
883 if (::WinSendMsg(GetHmenu(), MM_SETITEMTEXT
, MPFROMSHORT(nId
), (MPARAM
)rLabel
.c_str()));
885 wxLogLastError(wxT("ModifyMenu"));
888 } // end of wxMenuBar::SetLabelTop
890 wxString
wxMenuBar::GetLabelTop(
894 wxCHECK_MSG( nPos
< GetMenuCount(), wxEmptyString
,
895 wxT("invalid menu index in wxMenuBar::GetLabelTop") );
896 return m_titles
[nPos
];
897 } // end of wxMenuBar::GetLabelTop
899 // ---------------------------------------------------------------------------
900 // wxMenuBar construction
901 // ---------------------------------------------------------------------------
903 wxMenu
* wxMenuBar::Replace(
906 , const wxString
& rTitle
910 wxString sTitle
= wxPMTextToLabel(rTitle
);
911 wxMenu
* pMenuOld
= wxMenuBarBase::Replace( nPos
917 nId
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0));
918 if (nId
== MIT_ERROR
)
920 wxLogLastError(wxT("LogLastError"));
925 m_titles
[nPos
] = sTitle
;
928 ::WinSendMsg((HWND
)m_hMenu
, MM_REMOVEITEM
, MPFROM2SHORT(nId
, TRUE
), (MPARAM
)0);
929 ::WinSendMsg((HWND
)m_hMenu
, MM_INSERTITEM
, (MPARAM
)&pMenu
->m_vMenuData
, (MPARAM
)sTitle
.c_str());
932 if (pMenuOld
->HasAccels() || pMenu
->HasAccels())
935 // Need to rebuild accell table
939 #endif // wxUSE_ACCEL
943 } // end of wxMenuBar::Replace
945 bool wxMenuBar::Insert( size_t nPos
,
947 const wxString
& rTitle
)
949 wxString sTitle
= wxPMTextToLabel(rTitle
);
951 if (!wxMenuBarBase::Insert( nPos
, pMenu
, sTitle
))
954 m_titles
.Insert( sTitle
, nPos
);
958 pMenu
->m_vMenuData
.iPosition
= (SHORT
)nPos
;
959 ::WinSendMsg( (HWND
)m_hMenu
961 ,(MPARAM
)&pMenu
->m_vMenuData
962 ,(MPARAM
)sTitle
.c_str()
965 if (pMenu
->HasAccels())
967 // need to rebuild accell table
970 #endif // wxUSE_ACCEL
975 } // end of wxMenuBar::Insert
977 bool wxMenuBar::Append(
979 , const wxString
& rsTitle
982 WXHMENU hSubmenu
= pMenu
? pMenu
->GetHMenu() : 0;
984 wxCHECK_MSG(hSubmenu
, FALSE
, wxT("can't append invalid menu to menubar"));
986 wxString sTitle
= wxPMTextToLabel(rsTitle
);
988 if (!wxMenuBarBase::Append(pMenu
, sTitle
))
991 m_titles
.Add(sTitle
);
995 pMenu
->m_vMenuData
.iPosition
= MIT_END
;
996 ::WinSendMsg((HWND
)m_hMenu
, MM_INSERTITEM
, (MPARAM
)&pMenu
->m_vMenuData
, (MPARAM
)sTitle
.c_str());
998 if (pMenu
->HasAccels())
1001 // Need to rebuild accell table
1003 RebuildAccelTable();
1005 #endif // wxUSE_ACCEL
1009 } // end of wxMenuBar::Append
1011 wxMenu
* wxMenuBar::Remove(
1015 wxMenu
* pMenu
= wxMenuBarBase::Remove(nPos
);
1021 nId
= SHORT1FROMMR(::WinSendMsg( (HWND
)GetHmenu()
1022 ,MM_ITEMIDFROMPOSITION
1026 if (nId
== MIT_ERROR
)
1028 wxLogLastError(wxT("LogLastError"));
1033 ::WinSendMsg( (HWND
)GetHmenu()
1035 ,MPFROM2SHORT(nId
, TRUE
)
1040 if (pMenu
->HasAccels())
1043 // Need to rebuild accell table
1045 RebuildAccelTable();
1047 #endif // wxUSE_ACCEL
1050 m_titles
.RemoveAt(nPos
);
1052 } // end of wxMenuBar::Remove
1056 void wxMenuBar::RebuildAccelTable()
1059 // Merge the accelerators of all menus into one accel table
1061 size_t nAccelCount
= 0;
1063 size_t nCount
= GetMenuCount();
1064 wxMenuList::iterator it
;
1065 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
1067 nAccelCount
+= (*it
)->GetAccelCount();
1072 wxAcceleratorEntry
* pAccelEntries
= new wxAcceleratorEntry
[nAccelCount
];
1075 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
1077 nAccelCount
+= (*it
)->CopyAccels(&pAccelEntries
[nAccelCount
]);
1079 m_vAccelTable
= wxAcceleratorTable( nAccelCount
1082 delete [] pAccelEntries
;
1084 } // end of wxMenuBar::RebuildAccelTable
1086 #endif // wxUSE_ACCEL
1088 void wxMenuBar::Attach(
1092 wxMenuBarBase::Attach(pFrame
);
1095 RebuildAccelTable();
1097 // Ensure the accelerator table is set to the frame (not the client!)
1099 if (!::WinSetAccelTable( vHabmain
1100 ,m_vAccelTable
.GetHACCEL()
1101 ,(HWND
)pFrame
->GetFrame()
1103 wxLogLastError(wxT("WinSetAccelTable"));
1104 #endif // wxUSE_ACCEL
1105 } // end of wxMenuBar::Attach
1107 void wxMenuBar::Detach()
1109 ::WinDestroyWindow((HWND
)m_hMenu
);
1110 m_hMenu
= (WXHMENU
)NULL
;
1111 m_menuBarFrame
= NULL
;
1112 } // end of wxMenuBar::Detach
1114 // ---------------------------------------------------------------------------
1115 // wxMenuBar searching for menu items
1116 // ---------------------------------------------------------------------------
1119 // Find the itemString in menuString, and return the item id or wxNOT_FOUND
1121 int wxMenuBar::FindMenuItem(
1122 const wxString
& rMenuString
1123 , const wxString
& rItemString
1126 wxString sMenuLabel
= wxStripMenuCodes(rMenuString
);
1127 size_t nCount
= GetMenuCount(), i
;
1128 wxMenuList::const_iterator it
;
1129 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
1131 wxString sTitle
= wxStripMenuCodes(m_titles
[i
]);
1133 if (rMenuString
== sTitle
)
1134 return (*it
)->FindItem(rItemString
);
1137 } // end of wxMenuBar::FindMenuItem
1139 wxMenuItem
* wxMenuBar::FindItem(
1141 , wxMenu
** ppItemMenu
1147 wxMenuItem
* pItem
= NULL
;
1148 size_t nCount
= GetMenuCount(), i
;
1149 wxMenuList::const_iterator it
;
1150 for (i
= 0, it
= m_menus
.begin(); !pItem
&& (i
< nCount
); i
++, it
++)
1152 pItem
= (*it
)->FindItem( nId
1157 } // end of wxMenuBar::FindItem
1159 wxMenuItem
* wxMenuBar::FindItem(
1162 , wxMenu
** ppItemMenu
1168 wxMenuItem
* pItem
= NULL
;
1169 size_t nCount
= GetMenuCount(), i
;
1170 wxMenuList::const_iterator it
;
1171 for (i
= 0, it
= m_menus
.begin(); !pItem
&& (i
< nCount
); i
++, it
++)
1173 pItem
= (*it
)->FindItem( nId
1179 } // end of wxMenuBar::FindItem