1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/menu.cpp
3 // Purpose: wxMenu, wxMenuBar, wxMenuItem
4 // Author: David Webster
7 // Copyright: (c) David Webster
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #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 // ============================================================================
59 // ============================================================================
61 // ---------------------------------------------------------------------------
62 // wxMenu construction, adding and removing menu items
63 // ---------------------------------------------------------------------------
66 // Construct a menu with optional title (then use append)
71 m_nStartRadioGroup
= -1;
74 // Create the menu (to be used as a submenu or a popup)
76 if ((m_hMenu
= ::WinCreateWindow( HWND_DESKTOP
91 wxLogLastError(wxT("WinLoadMenu"));
93 m_vMenuData
.iPosition
= 0;
94 m_vMenuData
.afStyle
= MIS_SUBMENU
| MIS_TEXT
;
95 m_vMenuData
.afAttribute
= (USHORT
)0;
96 m_vMenuData
.id
= m_nextMenuId
++;
97 m_vMenuData
.hwndSubMenu
= m_hMenu
;
98 m_vMenuData
.hItem
= NULLHANDLE
;
101 // If we have a title, insert it in the beginning of the menu
103 if (!m_title
.empty())
112 } // end of wxMenu::Init
115 // The wxWindow destructor will take care of deleting the submenus.
120 // We should free PM resources only if PM doesn't do it for us
121 // which happens if we're attached to a menubar or a submenu of another
123 if (!IsAttached() && !GetParent())
125 if (!::WinDestroyWindow((HWND
)GetHmenu()) )
127 wxLogLastError(wxT("WinDestroyWindow"));
135 WX_CLEAR_ARRAY(m_vAccels
);
136 #endif // wxUSE_ACCEL
137 } // end of wxMenu::~wxMenu
141 // this will take effect during the next call to Append()
143 } // end of wxMenu::Break
146 wxMenuBarBase
* pMenubar
149 wxMenuBase::Attach(pMenubar
);
151 } // end of wxMenu::Break;
155 int wxMenu::FindAccel(
160 size_t nCount
= m_vAccels
.GetCount();
162 for (n
= 0; n
< nCount
; n
++)
163 if (m_vAccels
[n
]->m_command
== nId
)
166 } // end of wxMenu::FindAccel
168 void wxMenu::UpdateAccel(
172 if (pItem
->IsSubMenu())
174 wxMenu
* pSubmenu
= pItem
->GetSubMenu();
175 wxMenuItemList::compatibility_iterator node
= pSubmenu
->GetMenuItems().GetFirst();
179 UpdateAccel(node
->GetData());
180 node
= node
->GetNext();
183 else if (!pItem
->IsSeparator())
186 // Recurse upwards: we should only modify m_accels of the top level
187 // menus, not of the submenus as wxMenuBar doesn't look at them
188 // (alternative and arguable cleaner solution would be to recurse
189 // downwards in GetAccelCount() and CopyAccels())
193 GetParent()->UpdateAccel(pItem
);
198 // Find the (new) accel for this item
200 wxAcceleratorEntry
* pAccel
= wxAcceleratorEntry::Create(pItem
->GetItemLabel());
203 pAccel
->m_command
= pItem
->GetId();
208 size_t n
= FindAccel(pItem
->GetId());
210 if (n
== (size_t)wxNOT_FOUND
)
213 // No old, add new if any
216 m_vAccels
.Add(pAccel
);
223 // Replace old with new or just remove the old one if no new
227 m_vAccels
[n
] = pAccel
;
229 m_vAccels
.RemoveAt(n
);
234 GetMenuBar()->RebuildAccelTable();
237 } // wxMenu::UpdateAccel
239 #endif // wxUSE_ACCEL
242 // Append a new item or submenu to the menu
244 bool wxMenu::DoInsertOrAppend( wxMenuItem
* pItem
,
247 wxMenu
* pSubmenu
= pItem
->GetSubMenu();
248 MENUITEM
& rItem
= (pSubmenu
!= NULL
)?pSubmenu
->m_vMenuData
:
256 #endif // wxUSE_ACCEL
259 // If "Break" has just been called, insert a menu break before this item
260 // (and don't forget to reset the flag)
264 rItem
.afStyle
|= MIS_BREAK
;
269 // Id is the numeric id for normal menu items and HMENU for submenus as
270 // required by ::MM_INSERTITEM message API
272 if (pSubmenu
!= NULL
)
274 wxASSERT_MSG(pSubmenu
->GetHMenu(), wxT("invalid submenu"));
275 pSubmenu
->SetParent(this);
277 rItem
.iPosition
= 0; // submenus have a 0 position
278 rItem
.id
= (USHORT
)pSubmenu
->GetHMenu();
279 rItem
.afStyle
|= MIS_SUBMENU
| MIS_TEXT
;
283 rItem
.id
= (USHORT
)pItem
->GetId();
288 #if wxUSE_OWNER_DRAWN
289 if (pItem
->IsOwnerDrawn())
292 // Want to get {Measure|Draw}Item messages?
293 // item draws itself, passing pointer to data doesn't work in OS/2
294 // Will eventually need to set the image handle somewhere into vItem.hItem
296 rItem
.afStyle
|= MIS_OWNERDRAW
;
298 rItem
.hItem
= (HBITMAP
)pItem
->GetBitmap().GetHBITMAP();
299 pItem
->m_vMenuData
.afStyle
= rItem
.afStyle
;
300 pItem
->m_vMenuData
.hItem
= rItem
.hItem
;
304 if (pItem
->IsSeparator())
306 rItem
.afStyle
= MIS_SEPARATOR
;
310 if (pItem
->GetId() == idMenuTitle
)
312 // Item is an unselectable title to be passed via pData
313 rItem
.afStyle
= MIS_STATIC
;
318 // Menu is just a normal string (passed in data parameter)
320 rItem
.afStyle
|= MIS_TEXT
;
322 pData
= (char*) pItem
->GetItemLabel().wx_str();
325 if (nPos
== (size_t)-1)
327 rItem
.iPosition
= MIT_END
;
331 rItem
.iPosition
= (SHORT
)nPos
;
336 rc
= (APIRET
)::WinSendMsg( GetHmenu()
341 #if wxUSE_OWNER_DRAWN
342 if (pItem
->IsOwnerDrawn())
346 ::WinSendMsg( GetHmenu()
348 ,MPFROM2SHORT( (USHORT
)pItem
->GetId()
356 if (rc
== (APIRET
)MIT_MEMERROR
|| rc
== (APIRET
)MIT_ERROR
)
358 vError
= ::WinGetLastError(vHabmain
);
359 sError
= wxPMErrorToStr(vError
);
360 wxLogError(wxT("Error inserting or appending a menuitem. Error: %s\n"), sError
.c_str());
361 wxLogLastError(wxT("Insert or AppendMenu"));
366 // If we're already attached to the menubar, we must update it
368 if (IsAttached() && GetMenuBar()->IsAttached())
370 GetMenuBar()->Refresh();
374 } // end of wxMenu::DoInsertOrAppend
376 void wxMenu::EndRadioGroup()
379 // We're not inside a radio group any longer
381 m_nStartRadioGroup
= -1;
382 } // end of wxMenu::EndRadioGroup
384 wxMenuItem
* wxMenu::DoAppend( wxMenuItem
* pItem
)
386 wxCHECK_MSG( pItem
, NULL
, wxT("NULL item in wxMenu::DoAppend") );
390 if (pItem
->GetKind() == wxITEM_RADIO
)
392 int nCount
= GetMenuItemCount();
394 if (m_nStartRadioGroup
== -1)
397 // Start a new radio group
399 m_nStartRadioGroup
= nCount
;
402 // For now it has just one element
404 pItem
->SetAsRadioGroupStart();
405 pItem
->SetRadioGroupEnd(m_nStartRadioGroup
);
408 // Ensure that we have a checked item in the radio group
412 else // extend the current radio group
415 // We need to update its end item
417 pItem
->SetRadioGroupStart(m_nStartRadioGroup
);
419 wxMenuItemList::compatibility_iterator node
= GetMenuItems().Item(m_nStartRadioGroup
);
423 node
->GetData()->SetRadioGroupEnd(nCount
);
427 wxFAIL_MSG( wxT("where is the radio group start item?") );
431 else // not a radio item
436 if (!wxMenuBase::DoAppend(pItem
) || !DoInsertOrAppend(pItem
))
443 // Check the item initially
448 } // end of wxMenu::DoAppend
450 wxMenuItem
* wxMenu::DoInsert(
455 if ( wxMenuBase::DoInsert( nPos
457 DoInsertOrAppend( pItem
463 } // end of wxMenu::DoInsert
465 wxMenuItem
* wxMenu::DoRemove(
470 // We need to find the items position in the child list
473 wxMenuItemList::compatibility_iterator node
= GetMenuItems().GetFirst();
475 for (nPos
= 0; node
; nPos
++)
477 if (node
->GetData() == pItem
)
479 node
= node
->GetNext();
483 // DoRemove() (unlike Remove) can only be called for existing item!
485 wxCHECK_MSG(node
, NULL
, wxT("bug in wxMenu::Remove logic"));
489 // Remove the corresponding accel from the accel table
491 int n
= FindAccel(pItem
->GetId());
493 if (n
!= wxNOT_FOUND
)
496 m_vAccels
.RemoveAt(n
);
499 #endif // wxUSE_ACCEL
501 // Remove the item from the menu
503 ::WinSendMsg( GetHmenu()
505 ,MPFROM2SHORT(pItem
->GetId(), TRUE
)
508 if (IsAttached() && GetMenuBar()->IsAttached())
511 // Otherwise, the chane won't be visible
513 GetMenuBar()->Refresh();
517 // And from internal data structures
519 return wxMenuBase::DoRemove(pItem
);
520 } // end of wxMenu::DoRemove
522 // ---------------------------------------------------------------------------
523 // accelerator helpers
524 // ---------------------------------------------------------------------------
529 // Create the wxAcceleratorEntries for our accels and put them into provided
530 // array - return the number of accels we have
532 size_t wxMenu::CopyAccels(
533 wxAcceleratorEntry
* pAccels
536 size_t nCount
= GetAccelCount();
538 for (size_t n
= 0; n
< nCount
; n
++)
540 *pAccels
++ = *m_vAccels
[n
];
543 } // end of wxMenu::CopyAccels
545 #endif // wxUSE_ACCEL
547 // ---------------------------------------------------------------------------
549 // ---------------------------------------------------------------------------
551 void wxMenu::SetTitle( const wxString
& rLabel
)
553 bool bHasNoTitle
= m_title
.empty();
554 HWND hMenu
= GetHmenu();
561 if (!::WinSetWindowText(hMenu
, rLabel
.c_str()))
563 wxLogLastError(wxT("SetMenuTitle"));
571 ::WinSendMsg( GetHmenu()
573 ,MPFROM2SHORT(hMenu
, TRUE
)
582 if (!::WinSetWindowText(hMenu
, rLabel
.c_str()))
584 wxLogLastError(wxT("SetMenuTitle"));
588 } // end of wxMenu::SetTitle
590 // ---------------------------------------------------------------------------
592 // ---------------------------------------------------------------------------
594 bool wxMenu::OS2Command( WXUINT
WXUNUSED(uParam
),
598 // Ignore commands from the menu title
601 if (vId
!= (WXWORD
)idMenuTitle
)
604 ,(int)::WinSendMsg( GetHmenu()
612 } // end of wxMenu::OS2Command
614 // ---------------------------------------------------------------------------
616 // ---------------------------------------------------------------------------
618 wxWindow
* wxMenu::GetWindow() const
620 if (m_invokingWindow
!= NULL
)
621 return m_invokingWindow
;
622 else if ( GetMenuBar() != NULL
)
623 return GetMenuBar()->GetFrame();
626 } // end of wxMenu::GetWindow
628 // recursive search for item by id
629 wxMenuItem
* wxMenu::FindItem(
632 , wxMenu
** ppItemMenu
638 wxMenuItem
* pItem
= NULL
;
640 for ( wxMenuItemList::compatibility_iterator node
= m_items
.GetFirst();
642 node
= node
->GetNext() )
644 pItem
= node
->GetData();
646 if ( pItem
->GetId() == nItemId
&& pItem
->m_vMenuData
.hItem
== hItem
)
649 *ppItemMenu
= (wxMenu
*)this;
651 else if ( pItem
->IsSubMenu() )
653 pItem
= pItem
->GetSubMenu()->FindItem( nItemId
662 // don't exit the loop
667 } // end of wxMenu::FindItem
669 // ---------------------------------------------------------------------------
671 // ---------------------------------------------------------------------------
673 void wxMenuBar::Init()
675 m_eventHandler
= this;
676 m_menuBarFrame
= NULL
;
678 } // end of wxMenuBar::Init
680 wxMenuBar::wxMenuBar()
683 } // end of wxMenuBar::wxMenuBar
685 wxMenuBar::wxMenuBar(
686 long WXUNUSED(lStyle
)
690 } // end of wxMenuBar::wxMenuBar
692 wxMenuBar::wxMenuBar(
695 , const wxString sTitles
[]
696 , long WXUNUSED(lStyle
)
701 m_titles
.Alloc(nCount
);
702 for ( int i
= 0; i
< nCount
; i
++ )
704 m_menus
.Append(vMenus
[i
]);
705 m_titles
.Add(sTitles
[i
]);
706 vMenus
[i
]->Attach(this);
708 } // end of wxMenuBar::wxMenuBar
710 wxMenuBar::~wxMenuBar()
713 // We should free PM's resources only if PM doesn't do it for us
714 // which happens if we're attached to a frame
716 if (m_hMenu
&& !IsAttached())
718 ::WinDestroyWindow((HMENU
)m_hMenu
);
719 m_hMenu
= (WXHMENU
)NULL
;
721 } // end of wxMenuBar::~wxMenuBar
723 // ---------------------------------------------------------------------------
725 // ---------------------------------------------------------------------------
727 void wxMenuBar::Refresh()
729 wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
731 WinSendMsg(GetWinHwnd(m_menuBarFrame
), WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
732 } // end of wxMenuBar::Refresh
734 WXHMENU
wxMenuBar::Create()
741 wxCHECK_MSG(!m_hMenu
, TRUE
, wxT("menubar already created"));
744 // Menubars should be associated with a frame otherwise they are popups
746 if (m_menuBarFrame
!= NULL
)
747 hFrame
= GetWinHwnd(m_menuBarFrame
);
749 hFrame
= HWND_DESKTOP
;
751 // Create an empty menu and then fill it with insertions
753 if ((m_hMenu
= ::WinCreateWindow( hFrame
756 ,MS_ACTIONBAR
| WS_SYNCPAINT
| WS_VISIBLE
768 wxLogLastError(wxT("WinLoadMenu"));
772 size_t nCount
= GetMenuCount(), i
;
773 wxMenuList::iterator it
;
774 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
782 // Set the parent and owner of the submenues to be the menubar, not the desktop
784 hSubMenu
= (*it
)->m_vMenuData
.hwndSubMenu
;
785 if (!::WinSetParent((*it
)->m_vMenuData
.hwndSubMenu
, m_hMenu
, FALSE
))
787 vError
= ::WinGetLastError(vHabmain
);
788 sError
= wxPMErrorToStr(vError
);
789 wxLogError(wxT("Error setting parent for submenu. Error: %s\n"), sError
.c_str());
793 if (!::WinSetOwner((*it
)->m_vMenuData
.hwndSubMenu
, m_hMenu
))
795 vError
= ::WinGetLastError(vHabmain
);
796 sError
= wxPMErrorToStr(vError
);
797 wxLogError(wxT("Error setting parent for submenu. Error: %s\n"), sError
.c_str());
801 (*it
)->m_vMenuData
.iPosition
= (SHORT
)i
;
803 rc
= (APIRET
)::WinSendMsg(m_hMenu
, MM_INSERTITEM
, (MPARAM
)&(*it
)->m_vMenuData
, (MPARAM
)m_titles
[i
].wx_str());
804 if (rc
== (APIRET
)MIT_MEMERROR
|| rc
== (APIRET
)MIT_ERROR
)
806 vError
= ::WinGetLastError(vHabmain
);
807 sError
= wxPMErrorToStr(vError
);
808 wxLogError(wxT("Error inserting or appending a menuitem. Error: %s\n"), sError
.c_str());
814 } // end of wxMenuBar::Create
816 // ---------------------------------------------------------------------------
817 // wxMenuBar functions to work with the top level submenus
818 // ---------------------------------------------------------------------------
821 // NB: we don't support owner drawn top level items for now, if we do these
822 // functions would have to be changed to use wxMenuItem as well
824 void wxMenuBar::EnableTop(
829 wxCHECK_RET(IsAttached(), wxT("doesn't work with unattached menubars"));
834 uFlag
= MIA_DISABLED
;
836 nId
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0));
837 if (nId
== MIT_ERROR
)
839 wxLogLastError(wxT("LogLastError"));
842 ::WinSendMsg((HWND
)m_hMenu
, MM_SETITEMATTR
, MPFROM2SHORT(nId
, TRUE
), MPFROM2SHORT(MIA_DISABLED
, uFlag
));
844 } // end of wxMenuBar::EnableTop
846 void wxMenuBar::SetMenuLabel(
848 , const wxString
& rLabel
854 wxCHECK_RET(nPos
< GetMenuCount(), wxT("invalid menu index"));
855 m_titles
[nPos
] = rLabel
;
862 nId
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0));
863 if (nId
== MIT_ERROR
)
865 wxLogLastError(wxT("LogLastError"));
868 if(!::WinSendMsg( (HWND
)m_hMenu
870 ,MPFROM2SHORT(nId
, TRUE
)
874 wxLogLastError(wxT("QueryItem"));
878 if (::WinSendMsg(GetHmenu(), MM_SETITEMTEXT
, MPFROMSHORT(nId
), (MPARAM
)rLabel
.wx_str()));
880 wxLogLastError(wxT("ModifyMenu"));
883 } // end of wxMenuBar::SetMenuLabel
885 wxString
wxMenuBar::GetMenuLabel(
889 wxCHECK_MSG( nPos
< GetMenuCount(), wxEmptyString
,
890 wxT("invalid menu index in wxMenuBar::GetMenuLabel") );
891 return m_titles
[nPos
];
892 } // end of wxMenuBar::GetMenuLabel
894 // ---------------------------------------------------------------------------
895 // wxMenuBar construction
896 // ---------------------------------------------------------------------------
898 wxMenu
* wxMenuBar::Replace(
901 , const wxString
& rTitle
905 wxString sTitle
= wxPMTextToLabel(rTitle
);
906 wxMenu
* pMenuOld
= wxMenuBarBase::Replace( nPos
912 nId
= SHORT1FROMMR(::WinSendMsg((HWND
)m_hMenu
, MM_ITEMIDFROMPOSITION
, MPFROMSHORT(nPos
), (MPARAM
)0));
913 if (nId
== MIT_ERROR
)
915 wxLogLastError(wxT("LogLastError"));
920 m_titles
[nPos
] = sTitle
;
923 ::WinSendMsg((HWND
)m_hMenu
, MM_REMOVEITEM
, MPFROM2SHORT(nId
, TRUE
), (MPARAM
)0);
924 ::WinSendMsg((HWND
)m_hMenu
, MM_INSERTITEM
, (MPARAM
)&pMenu
->m_vMenuData
, (MPARAM
)sTitle
.wx_str());
927 if (pMenuOld
->HasAccels() || pMenu
->HasAccels())
930 // Need to rebuild accell table
934 #endif // wxUSE_ACCEL
938 } // end of wxMenuBar::Replace
940 bool wxMenuBar::Insert( size_t nPos
,
942 const wxString
& rTitle
)
944 wxString sTitle
= wxPMTextToLabel(rTitle
);
946 if (!wxMenuBarBase::Insert( nPos
, pMenu
, sTitle
))
949 m_titles
.Insert( sTitle
, nPos
);
953 pMenu
->m_vMenuData
.iPosition
= (SHORT
)nPos
;
954 ::WinSendMsg( (HWND
)m_hMenu
956 ,(MPARAM
)&pMenu
->m_vMenuData
957 ,(MPARAM
)sTitle
.wx_str()
960 if (pMenu
->HasAccels())
962 // need to rebuild accell table
965 #endif // wxUSE_ACCEL
970 } // end of wxMenuBar::Insert
972 bool wxMenuBar::Append( wxMenu
* pMenu
,
973 const wxString
& rsTitle
)
975 WXHMENU hSubmenu
= pMenu
? pMenu
->GetHMenu() : 0;
977 wxCHECK_MSG(hSubmenu
, false, wxT("can't append invalid menu to menubar"));
979 wxString sTitle
= wxPMTextToLabel(rsTitle
);
981 if (!wxMenuBarBase::Append(pMenu
, sTitle
))
984 m_titles
.Add(sTitle
);
988 pMenu
->m_vMenuData
.iPosition
= MIT_END
;
989 ::WinSendMsg((HWND
)m_hMenu
, MM_INSERTITEM
, (MPARAM
)&pMenu
->m_vMenuData
, (MPARAM
)sTitle
.wx_str());
991 if (pMenu
->HasAccels())
994 // Need to rebuild accell table
998 #endif // wxUSE_ACCEL
1002 } // end of wxMenuBar::Append
1004 wxMenu
* wxMenuBar::Remove(
1008 wxMenu
* pMenu
= wxMenuBarBase::Remove(nPos
);
1014 nId
= SHORT1FROMMR(::WinSendMsg( (HWND
)GetHmenu()
1015 ,MM_ITEMIDFROMPOSITION
1019 if (nId
== MIT_ERROR
)
1021 wxLogLastError(wxT("LogLastError"));
1026 ::WinSendMsg( (HWND
)GetHmenu()
1028 ,MPFROM2SHORT(nId
, TRUE
)
1033 if (pMenu
->HasAccels())
1036 // Need to rebuild accell table
1038 RebuildAccelTable();
1040 #endif // wxUSE_ACCEL
1043 m_titles
.RemoveAt(nPos
);
1045 } // end of wxMenuBar::Remove
1049 void wxMenuBar::RebuildAccelTable()
1052 // Merge the accelerators of all menus into one accel table
1054 size_t nAccelCount
= 0;
1056 size_t nCount
= GetMenuCount();
1057 wxMenuList::iterator it
;
1058 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
1060 nAccelCount
+= (*it
)->GetAccelCount();
1065 wxAcceleratorEntry
* pAccelEntries
= new wxAcceleratorEntry
[nAccelCount
];
1068 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
1070 nAccelCount
+= (*it
)->CopyAccels(&pAccelEntries
[nAccelCount
]);
1072 m_vAccelTable
= wxAcceleratorTable( nAccelCount
1075 delete [] pAccelEntries
;
1077 } // end of wxMenuBar::RebuildAccelTable
1079 #endif // wxUSE_ACCEL
1081 void wxMenuBar::Attach(
1085 wxMenuBarBase::Attach(pFrame
);
1088 RebuildAccelTable();
1090 // Ensure the accelerator table is set to the frame (not the client!)
1092 if (!::WinSetAccelTable( vHabmain
1093 ,m_vAccelTable
.GetHACCEL()
1094 ,(HWND
)pFrame
->GetFrame()
1097 wxLogLastError(wxT("WinSetAccelTable"));
1099 #endif // wxUSE_ACCEL
1100 } // end of wxMenuBar::Attach
1102 void wxMenuBar::Detach()
1104 ::WinDestroyWindow((HWND
)m_hMenu
);
1105 m_hMenu
= (WXHMENU
)NULL
;
1106 m_menuBarFrame
= NULL
;
1107 } // end of wxMenuBar::Detach
1109 // ---------------------------------------------------------------------------
1110 // wxMenuBar searching for menu items
1111 // ---------------------------------------------------------------------------
1114 // Find the itemString in menuString, and return the item id or wxNOT_FOUND
1116 int wxMenuBar::FindMenuItem(
1117 const wxString
& rMenuString
1118 , const wxString
& rItemString
1121 wxString sMenuLabel
= wxStripMenuCodes(rMenuString
);
1122 size_t nCount
= GetMenuCount(), i
;
1123 wxMenuList::const_iterator it
;
1124 for (i
= 0, it
= m_menus
.begin(); i
< nCount
; i
++, it
++)
1126 wxString sTitle
= wxStripMenuCodes(m_titles
[i
]);
1128 if (rMenuString
== sTitle
)
1129 return (*it
)->FindItem(rItemString
);
1132 } // end of wxMenuBar::FindMenuItem
1134 wxMenuItem
* wxMenuBar::FindItem(
1136 , wxMenu
** ppItemMenu
1142 wxMenuItem
* pItem
= NULL
;
1143 size_t nCount
= GetMenuCount(), i
;
1144 wxMenuList::const_iterator it
;
1145 for (i
= 0, it
= m_menus
.begin(); !pItem
&& (i
< nCount
); i
++, it
++)
1147 pItem
= (*it
)->FindItem( nId
1152 } // end of wxMenuBar::FindItem
1154 wxMenuItem
* wxMenuBar::FindItem(
1157 , wxMenu
** ppItemMenu
1163 wxMenuItem
* pItem
= NULL
;
1164 size_t nCount
= GetMenuCount(), i
;
1165 wxMenuList::const_iterator it
;
1166 for (i
= 0, it
= m_menus
.begin(); !pItem
&& (i
< nCount
); i
++, it
++)
1168 pItem
= (*it
)->FindItem( nId
1174 } // end of wxMenuBar::FindItem