1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxMenu, wxMenuBar, wxMenuItem
4 // Author: Julian Smart
5 // Modified by: Vadim Zeitlin
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "menu.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
30 #include "wx/ownerdrw.h"
33 #include "wx/msw/private.h"
34 #include "wx/msw/menu.h"
35 #include "wx/menuitem.h"
38 // other standard headers
39 // ----------------------
42 // ----------------------------------------------------------------------------
44 // ----------------------------------------------------------------------------
46 // the (popup) menu title has this special id
47 static const int idMenuTitle
= -2;
49 // ----------------------------------------------------------------------------
51 // ----------------------------------------------------------------------------
52 #if !USE_SHARED_LIBRARY
53 IMPLEMENT_DYNAMIC_CLASS(wxMenu
, wxEvtHandler
)
54 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
, wxEvtHandler
)
57 // ============================================================================
59 // ============================================================================
63 // Construct a menu with optional title (then use append)
64 wxMenu::wxMenu(const wxString
& Title
, const wxFunction func
)
68 m_eventHandler
= this;
69 m_pInvokingWindow
= NULL
;
73 m_hMenu
= (WXHMENU
) CreatePopupMenu();
75 m_topLevelMenu
= this;
76 m_clientData
= (void*) NULL
;
80 Append(idMenuTitle
, m_title
) ;
87 // The wxWindow destructor will take care of deleting the submenus.
91 DestroyMenu((HMENU
) m_hMenu
);
94 // Windows seems really bad on Menu de-allocation...
95 // After many try, here is what I do: RemoveMenu() will ensure
96 // that popup are "disconnected" from their parent; then call
97 // delete method on each child (which in turn do a recursive job),
98 // and finally, DestroyMenu()
100 // With that, BoundCheckers is happy, and no complaints...
104 N = GetMenuItemCount(m_hMenu);
106 for (i = N-1; i >= 0; i--)
107 RemoveMenu(m_hMenu, i, MF_BYPOSITION);
110 // How is deleting submenus in this loop any different from deleting
111 // the submenus in the children list, via ~wxWindow ?
112 // I'll reinstate this deletion for now and remove addition
113 // from children list (which doesn't exist now)
115 wxNode
*node
= m_menuItems
.First();
118 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
120 // Delete child menus.
121 // Beware: they must not be appended to children list!!!
122 // (because order of delete is significant)
123 if (item
->GetSubMenu())
124 item
->DeleteSubMenu();
126 wxNode
*next
= node
->Next();
133 DestroyMenu(m_hMenu);
143 // function appends a new item or submenu to the menu
144 void wxMenu::Append(wxMenuItem
*pItem
)
146 wxCHECK_RET( pItem
!= NULL
, "can't append NULL item to the menu" );
148 m_menuItems
.Append(pItem
);
153 flags
|= MF_MENUBREAK
;
157 if ( pItem
->IsSeparator() ) {
158 flags
|= MF_SEPARATOR
;
161 // id is the numeric id for normal menu items and HMENU for submenus
163 wxMenu
*SubMenu
= pItem
->GetSubMenu();
164 if ( SubMenu
!= NULL
) {
165 wxASSERT( SubMenu
->m_hMenu
!= (WXHMENU
) NULL
);
167 id
= (UINT
)SubMenu
->m_hMenu
;
169 SubMenu
->m_topLevelMenu
= m_topLevelMenu
;
170 SubMenu
->m_parent
= this;
171 SubMenu
->m_savehMenu
= (WXHMENU
)id
;
172 SubMenu
->m_hMenu
= 0;
182 #if wxUSE_OWNER_DRAWN
183 if ( pItem
->IsOwnerDrawn() ) { // want to get {Measure|Draw}Item messages?
184 // item draws itself, pass pointer to it in data parameter
185 flags
|= MF_OWNERDRAW
;
186 pData
= (LPCSTR
)pItem
;
191 // menu is just a normal string (passed in data parameter)
193 pData
= pItem
->GetName();
196 // visually select the menu title
197 if ( id
== idMenuTitle
)
199 // TODO use SetMenuItemInfo(MFS_DEFAULT) to put it in bold face
202 HMENU hMenu
= (HMENU
)((m_hMenu
== 0) ? m_savehMenu
: m_hMenu
);
203 if ( !AppendMenu(hMenu
, flags
, id
, pData
) )
205 wxLogLastError("AppendMenu");
211 void wxMenu::AppendSeparator()
213 Append(new wxMenuItem(this, ID_SEPARATOR
));
217 void wxMenu::Append(int Id
, const wxString
& label
, wxMenu
*SubMenu
,
218 const wxString
& helpString
)
220 Append(new wxMenuItem(this, Id
, label
, helpString
, FALSE
, SubMenu
));
223 // Ordinary menu item
224 void wxMenu::Append(int Id
, const wxString
& label
,
225 const wxString
& helpString
, bool checkable
)
227 // 'checkable' parameter is useless for Windows.
228 Append(new wxMenuItem(this, Id
, label
, helpString
, checkable
));
231 void wxMenu::Delete(int id
)
237 wxMenuItem
*item
= NULL
;
238 for (pos
= 0, node
= m_menuItems
.First(); node
; node
= node
->Next(), pos
++) {
239 item
= (wxMenuItem
*)node
->Data();
240 if (item
->GetId() == id
)
247 menu
= (HMENU
)(m_hMenu
? m_hMenu
: m_savehMenu
);
249 wxMenu
*pSubMenu
= item
->GetSubMenu();
250 if ( pSubMenu
!= NULL
) {
251 RemoveMenu(menu
, (UINT
)pos
, MF_BYPOSITION
);
252 pSubMenu
->m_hMenu
= pSubMenu
->m_savehMenu
;
253 pSubMenu
->m_savehMenu
= 0;
254 pSubMenu
->m_parent
= NULL
;
255 // RemoveChild(item->subMenu);
256 pSubMenu
->m_topLevelMenu
= NULL
;
257 // TODO: Why isn't subMenu deleted here???
258 // Will put this in for now. Assuming this is supposed
259 // to delete the menu, not just remove it.
260 item
->DeleteSubMenu();
263 DeleteMenu(menu
, (UINT
)pos
, MF_BYPOSITION
);
266 m_menuItems
.DeleteNode(node
);
270 void wxMenu::Enable(int Id
, bool Flag
)
272 wxMenuItem
*item
= FindItemForId(Id
);
273 wxCHECK_RET( item
!= NULL
, "can't enable non-existing menu item" );
278 bool wxMenu::Enabled(int Id
) const
280 wxMenuItem
*item
= FindItemForId(Id
);
281 wxCHECK( item
!= NULL
, FALSE
);
283 return item
->IsEnabled();
286 void wxMenu::Check(int Id
, bool Flag
)
288 wxMenuItem
*item
= FindItemForId(Id
);
289 wxCHECK_RET( item
!= NULL
, "can't get status of non-existing menu item" );
294 bool wxMenu::Checked(int Id
) const
296 wxMenuItem
*item
= FindItemForId(Id
);
297 wxCHECK( item
!= NULL
, FALSE
);
299 return item
->IsChecked();
302 void wxMenu::SetTitle(const wxString
& label
)
304 bool hasNoTitle
= m_title
.IsEmpty();
307 HMENU hMenu
= (HMENU
)((m_hMenu
== 0) ? m_savehMenu
: m_hMenu
);
311 if ( !label
.IsEmpty() )
313 if ( !InsertMenu(hMenu
, 0u, MF_BYPOSITION
| MF_STRING
,
314 (unsigned)idMenuTitle
, m_title
) ||
315 !InsertMenu(hMenu
, 1u, MF_BYPOSITION
, (unsigned)-1, NULL
) )
317 wxLogLastError("InsertMenu");
323 if ( label
.IsEmpty() )
325 // remove the title and the separator after it
326 if ( !RemoveMenu(hMenu
, 0, MF_BYPOSITION
) ||
327 !RemoveMenu(hMenu
, 0, MF_BYPOSITION
) )
329 wxLogLastError("RemoveMenu");
335 if ( !ModifyMenu(hMenu
, 0u,
336 MF_BYPOSITION
| MF_STRING
,
337 (unsigned)idMenuTitle
, m_title
) )
339 wxLogLastError("ModifyMenu");
345 // put the title string in bold face
346 if ( !m_title
.IsEmpty() )
349 mii
.cbSize
= sizeof(mii
);
350 mii
.fMask
= MIIM_STATE
;
351 mii
.fState
= MFS_DEFAULT
;
353 if ( !SetMenuItemInfo(hMenu
, (unsigned)idMenuTitle
, FALSE
, &mii
) )
355 wxLogLastError("SetMenuItemInfo");
361 const wxString
wxMenu::GetTitle() const
366 void wxMenu::SetLabel(int Id
, const wxString
& label
)
368 wxMenuItem
*item
= FindItemForId(Id
) ;
372 if (item
->GetSubMenu()==NULL
)
376 UINT was_flag
= GetMenuState((HMENU
)m_hMenu
,Id
,MF_BYCOMMAND
) ;
377 ModifyMenu((HMENU
)m_hMenu
,Id
,MF_BYCOMMAND
|MF_STRING
|was_flag
,Id
,(const char *)label
) ;
379 else if (m_savehMenu
)
381 UINT was_flag
= GetMenuState((HMENU
)m_savehMenu
,Id
,MF_BYCOMMAND
) ;
382 ModifyMenu((HMENU
)m_savehMenu
,Id
,MF_BYCOMMAND
|MF_STRING
|was_flag
,Id
,(const char *)label
) ;
387 wxMenu
*father
= item
->GetSubMenu()->m_topLevelMenu
;
388 wxNode
*node
= father
->m_menuItems
.First() ;
392 wxMenuItem
*matched
= (wxMenuItem
*)node
->Data() ;
396 node
= node
->Next() ;
398 // Here, we have the position.
399 ModifyMenu((HMENU
)father
->m_savehMenu
,i
,
400 MF_BYPOSITION
|MF_STRING
|MF_POPUP
,
401 (UINT
)item
->GetSubMenu()->m_savehMenu
,(const char *)label
) ;
403 item
->SetName(label
);
406 wxString
wxMenu::GetLabel(int id
) const
409 static char tmp[128] ;
412 len = GetMenuString((HMENU)m_hMenu,Id,tmp,WXSIZEOF(tmp) - 1,MF_BYCOMMAND);
413 else if (m_savehMenu)
414 len = GetMenuString((HMENU)m_savehMenu,Id,tmp,WXSIZEOF(tmp) - 1,MF_BYCOMMAND);
418 return wxString(tmp) ;
421 wxMenuItem
*pItem
= FindItemForId(id
) ;
423 return pItem
->GetName() ;
425 return wxEmptyString
;
428 bool wxMenu::MSWCommand(WXUINT
WXUNUSED(param
), WXWORD id
)
430 // ignore commands from the menu title
432 // NB: VC++ generates wrong assembler for `if ( id != idMenuTitle )'!!
433 if ( id
!= (WXWORD
)idMenuTitle
)
435 wxCommandEvent
event(wxEVT_COMMAND_MENU_SELECTED
);
436 event
.SetEventObject( this );
439 ProcessCommand(event
);
445 // Finds the item id matching the given string, -1 if not found.
446 int wxMenu::FindItem (const wxString
& itemString
) const
450 wxStripMenuCodes ((char *)(const char *)itemString
, buf1
);
452 for (wxNode
* node
= m_menuItems
.First (); node
; node
= node
->Next ())
454 wxMenuItem
*item
= (wxMenuItem
*) node
->Data ();
455 if (item
->GetSubMenu())
457 int ans
= item
->GetSubMenu()->FindItem(itemString
);
461 if ( !item
->IsSeparator() )
463 wxStripMenuCodes((char *)item
->GetName().c_str(), buf2
);
464 if (strcmp(buf1
, buf2
) == 0)
465 return item
->GetId();
472 wxMenuItem
*wxMenu::FindItemForId(int itemId
, wxMenu
** itemMenu
) const
476 for (wxNode
* node
= m_menuItems
.First (); node
; node
= node
->Next ())
478 wxMenuItem
*item
= (wxMenuItem
*) node
->Data ();
480 if (item
->GetId() == itemId
)
483 *itemMenu
= (wxMenu
*) this;
487 if (item
->GetSubMenu())
489 wxMenuItem
*ans
= item
->GetSubMenu()->FindItemForId (itemId
, itemMenu
);
500 void wxMenu::SetHelpString(int itemId
, const wxString
& helpString
)
502 wxMenuItem
*item
= FindItemForId (itemId
);
504 item
->SetHelp(helpString
);
507 wxString
wxMenu::GetHelpString (int itemId
) const
509 wxMenuItem
*item
= FindItemForId (itemId
);
511 return item
->GetHelp();
513 return wxEmptyString
;
516 void wxMenu::ProcessCommand(wxCommandEvent
& event
)
518 bool processed
= FALSE
;
523 (void)(*(m_callback
))(*this, event
);
527 // Try the menu's event handler
528 if ( !processed
&& GetEventHandler())
530 processed
= GetEventHandler()->ProcessEvent(event
);
533 // Try the window the menu was popped up from (and up
534 // through the hierarchy)
535 if ( !processed
&& GetInvokingWindow())
536 processed
= GetInvokingWindow()->GetEventHandler()->ProcessEvent(event
);
539 extern wxMenu
*wxCurrentPopupMenu
;
540 bool wxWindow::PopupMenu(wxMenu
*menu
, int x
, int y
)
542 menu
->SetInvokingWindow(this);
545 HWND hWnd
= (HWND
) GetHWND();
546 HMENU hMenu
= (HMENU
)menu
->m_hMenu
;
550 ::ClientToScreen(hWnd
, &point
);
551 wxCurrentPopupMenu
= menu
;
552 ::TrackPopupMenu(hMenu
, TPM_RIGHTBUTTON
, point
.x
, point
.y
, 0, hWnd
, NULL
);
554 wxCurrentPopupMenu
= NULL
;
556 menu
->SetInvokingWindow(NULL
);
562 wxMenuBar::wxMenuBar()
564 m_eventHandler
= this;
568 m_menuBarFrame
= NULL
;
572 wxMenuBar::wxMenuBar( long WXUNUSED(style
) )
574 m_eventHandler
= this;
578 m_menuBarFrame
= NULL
;
582 wxMenuBar::wxMenuBar(int N
, wxMenu
*Menus
[], const wxString Titles
[])
584 m_eventHandler
= this;
587 m_titles
= new wxString
[N
];
589 for ( i
= 0; i
< N
; i
++ )
590 m_titles
[i
] = Titles
[i
];
591 m_menuBarFrame
= NULL
;
592 for (i
= 0; i
< N
; i
++)
593 m_menus
[i
]->m_menuBar
= (wxMenuBar
*) this;
598 wxMenuBar::~wxMenuBar()
600 // In fact, don't want menu to be destroyed before MDI
601 // shuffling has taken place. Let it be destroyed
602 // automatically when the window is destroyed.
604 // DestroyMenu(menu);
609 // See remarks in ::~wxMenu() method
610 // BEWARE - this may interfere with MDI fixes, so
611 // may need to remove
614 if (m_menuBarFrame && ((m_menuBarFrame->GetWindowStyleFlag() & wxSDI) == wxSDI))
617 N = GetMenuItemCount(menu) ;
618 for (i = N-1; i >= 0; i--)
619 RemoveMenu(menu, i, MF_BYPOSITION);
622 for (i
= 0; i
< m_menuCount
; i
++)
629 /* Don't destroy menu here, in case we're MDI and
630 need to do some shuffling with VALID menu handles.
637 // Must only be used AFTER menu has been attached to frame,
638 // otherwise use individual menus to enable/disable items
639 void wxMenuBar::Enable(int Id
, bool Flag
)
643 ms_flag
= MF_ENABLED
;
647 wxMenu
*itemMenu
= NULL
;
648 wxMenuItem
*item
= FindItemForId(Id
, &itemMenu
) ;
652 if (itemMenu
->m_hMenu
)
653 EnableMenuItem((HMENU
)itemMenu
->m_hMenu
, Id
, MF_BYCOMMAND
| ms_flag
);
654 else if (itemMenu
->m_savehMenu
)
655 EnableMenuItem((HMENU
)itemMenu
->m_savehMenu
, Id
, MF_BYCOMMAND
| ms_flag
);
659 void wxMenuBar::EnableTop(int pos
, bool flag
)
663 ms_flag
= MF_ENABLED
;
667 EnableMenuItem((HMENU
)m_hMenu
, pos
, MF_BYPOSITION
| ms_flag
);
668 DrawMenuBar((HWND
) m_menuBarFrame
->GetHWND()) ;
671 // Must only be used AFTER menu has been attached to frame,
672 // otherwise use individual menus
673 void wxMenuBar::Check(int Id
, bool Flag
)
675 wxMenu
*itemMenu
= NULL
;
676 wxMenuItem
*item
= FindItemForId(Id
, &itemMenu
) ;
680 if (!item
->IsCheckable())
684 ms_flag
= MF_CHECKED
;
686 ms_flag
= MF_UNCHECKED
;
688 if (itemMenu
->m_hMenu
)
689 CheckMenuItem((HMENU
)itemMenu
->m_hMenu
, Id
, MF_BYCOMMAND
| ms_flag
);
690 else if (itemMenu
->m_savehMenu
)
691 CheckMenuItem((HMENU
)itemMenu
->m_savehMenu
, Id
, MF_BYCOMMAND
| ms_flag
);
693 // CheckMenuItem((HMENU)m_hMenu, Id, MF_BYCOMMAND | ms_flag);
696 bool wxMenuBar::Checked(int Id
) const
698 wxMenu
*itemMenu
= NULL
;
699 wxMenuItem
*item
= FindItemForId(Id
, &itemMenu
) ;
705 if (itemMenu
->m_hMenu
)
706 Flag
=GetMenuState((HMENU
)itemMenu
->m_hMenu
, Id
, MF_BYCOMMAND
) ;
707 else if (itemMenu
->m_savehMenu
)
708 Flag
=GetMenuState((HMENU
)itemMenu
->m_savehMenu
, Id
, MF_BYCOMMAND
) ;
710 // Flag=GetMenuState((HMENU)m_hMenu, Id, MF_BYCOMMAND) ;
718 bool wxMenuBar::Enabled(int Id
) const
720 wxMenu
*itemMenu
= NULL
;
721 wxMenuItem
*item
= FindItemForId(Id
, &itemMenu
) ;
727 if (itemMenu
->m_hMenu
)
728 Flag
=GetMenuState((HMENU
)itemMenu
->m_hMenu
, Id
, MF_BYCOMMAND
) ;
729 else if (itemMenu
->m_savehMenu
)
730 Flag
=GetMenuState((HMENU
)itemMenu
->m_savehMenu
, Id
, MF_BYCOMMAND
) ;
739 void wxMenuBar::SetLabel(int Id
, const wxString
& label
)
741 wxMenu
*itemMenu
= NULL
;
742 wxMenuItem
*item
= FindItemForId(Id
, &itemMenu
) ;
747 if (itemMenu
->m_hMenu
)
749 UINT was_flag
= GetMenuState((HMENU
)itemMenu
->m_hMenu
,Id
,MF_BYCOMMAND
) ;
750 ModifyMenu((HMENU
)itemMenu
->m_hMenu
,Id
,MF_BYCOMMAND
|MF_STRING
|was_flag
,Id
,(const char *)label
) ;
752 else if (itemMenu
->m_savehMenu
)
754 UINT was_flag
= GetMenuState((HMENU
)itemMenu
->m_savehMenu
,Id
,MF_BYCOMMAND
) ;
755 ModifyMenu((HMENU
)itemMenu
->m_savehMenu
,Id
,MF_BYCOMMAND
|MF_STRING
|was_flag
,Id
,(const char *)label
) ;
759 wxString
wxMenuBar::GetLabel(int Id
) const
761 wxMenu
*itemMenu
= NULL
;
762 wxMenuItem
*item
= FindItemForId(Id
, &itemMenu
) ;
767 static char tmp
[128] ;
769 if (itemMenu
->m_hMenu
)
771 len
= GetMenuString((HMENU
)itemMenu
->m_hMenu
,Id
,tmp
,127,MF_BYCOMMAND
) ;
773 else if (itemMenu
->m_savehMenu
)
775 len
= GetMenuString((HMENU
)itemMenu
->m_savehMenu
,Id
,tmp
,127,MF_BYCOMMAND
) ;
778 // int len = GetMenuString((HMENU)m_hMenu,Id,tmp,127,MF_BYCOMMAND) ;
780 return wxString(tmp
) ;
783 void wxMenuBar::SetLabelTop(int pos
, const wxString
& label
)
785 UINT was_flag
= GetMenuState((HMENU
)m_hMenu
,pos
,MF_BYPOSITION
) ;
786 if (was_flag
&MF_POPUP
)
789 HMENU popup
= GetSubMenu((HMENU
)m_hMenu
,pos
) ;
790 ModifyMenu((HMENU
)m_hMenu
,pos
,MF_BYPOSITION
|MF_STRING
|was_flag
,(UINT
)popup
,(const char *)label
) ;
793 ModifyMenu((HMENU
)m_hMenu
,pos
,MF_BYPOSITION
|MF_STRING
|was_flag
,pos
,(const char *)label
) ;
796 wxString
wxMenuBar::GetLabelTop(int pos
) const
798 static char tmp
[128] ;
799 int len
= GetMenuString((HMENU
)m_hMenu
,pos
,tmp
,127,MF_BYPOSITION
) ;
801 return wxString(tmp
);
804 bool wxMenuBar::OnDelete(wxMenu
*a_menu
, int pos
)
809 if (RemoveMenu((HMENU
)m_hMenu
, (UINT
)pos
, MF_BYPOSITION
)) {
810 m_menus
[pos
]->m_hMenu
= m_menus
[pos
]->m_savehMenu
;
811 m_menus
[pos
]->m_savehMenu
= 0;
813 if (m_menuBarFrame
) {
814 DrawMenuBar((HWND
) m_menuBarFrame
->GetHWND()) ;
823 bool wxMenuBar::OnAppend(wxMenu
*a_menu
, const char *title
)
825 if (!a_menu
->m_hMenu
)
831 a_menu
->m_savehMenu
= a_menu
->m_hMenu
;
834 AppendMenu((HMENU
)m_hMenu
, MF_POPUP
| MF_STRING
, (UINT
)a_menu
->m_savehMenu
, title
);
836 DrawMenuBar((HWND
) m_menuBarFrame
->GetHWND());
841 void wxMenuBar::Append (wxMenu
* menu
, const wxString
& title
)
843 if (!OnAppend(menu
, title
))
847 wxMenu
**new_menus
= new wxMenu
*[m_menuCount
];
848 wxString
*new_titles
= new wxString
[m_menuCount
];
851 for (i
= 0; i
< m_menuCount
- 1; i
++)
853 new_menus
[i
] = m_menus
[i
];
855 new_titles
[i
] = m_titles
[i
];
864 m_titles
= new_titles
;
866 m_menus
[m_menuCount
- 1] = (wxMenu
*)menu
;
867 m_titles
[m_menuCount
- 1] = title
;
869 ((wxMenu
*)menu
)->m_menuBar
= (wxMenuBar
*) this;
870 ((wxMenu
*)menu
)->SetParent(this);
873 void wxMenuBar::Delete(wxMenu
* menu
, int i
)
879 for (ii
= 0; ii
< m_menuCount
; ii
++) {
880 if (m_menus
[ii
] == menu
)
883 if (ii
>= m_menuCount
)
886 if (ii
< 0 || ii
>= m_menuCount
)
891 if (!OnDelete(menu
, ii
))
894 menu
->SetParent(NULL
);
897 for (j
= ii
; j
< m_menuCount
; j
++) {
898 m_menus
[j
] = m_menus
[j
+ 1];
899 m_titles
[j
] = m_titles
[j
+ 1];
903 // Find the menu menuString, item itemString, and return the item id.
904 // Returns -1 if none found.
905 int wxMenuBar::FindMenuItem (const wxString
& menuString
, const wxString
& itemString
) const
909 wxStripMenuCodes ((char *)(const char *)menuString
, buf1
);
911 for (i
= 0; i
< m_menuCount
; i
++)
913 wxStripMenuCodes ((char *)(const char *)m_titles
[i
], buf2
);
914 if (strcmp (buf1
, buf2
) == 0)
915 return m_menus
[i
]->FindItem (itemString
);
920 wxMenuItem
*wxMenuBar::FindItemForId (int Id
, wxMenu
** itemMenu
) const
925 wxMenuItem
*item
= NULL
;
927 for (i
= 0; i
< m_menuCount
; i
++)
929 item
= m_menus
[i
]->FindItemForId (Id
, itemMenu
);
936 void wxMenuBar::SetHelpString (int Id
, const wxString
& helpString
)
939 for (i
= 0; i
< m_menuCount
; i
++)
941 if (m_menus
[i
]->FindItemForId (Id
))
943 m_menus
[i
]->SetHelpString (Id
, helpString
);
949 wxString
wxMenuBar::GetHelpString (int Id
) const
952 for (i
= 0; i
< m_menuCount
; i
++)
954 if (m_menus
[i
]->FindItemForId (Id
))
955 return wxString(m_menus
[i
]->GetHelpString (Id
));
960 wxWindow
*wxMenu::GetWindow() const
962 if ( m_pInvokingWindow
!= NULL
)
963 return m_pInvokingWindow
;
964 if ( m_menuBar
!= NULL
)
965 return m_menuBar
->m_menuBarFrame
;
969 WXHMENU
wxMenu::GetHMenu() const
973 else if ( m_savehMenu
!= 0 )
979 // Update a menu and all submenus recursively.
980 // source is the object that has the update event handlers
981 // defined for it. If NULL, the menu or associated window
983 void wxMenu::UpdateUI(wxEvtHandler
* source
)
985 if (!source
&& GetInvokingWindow())
986 source
= GetInvokingWindow()->GetEventHandler();
988 source
= GetEventHandler();
992 wxNode
* node
= GetItems().First();
995 wxMenuItem
* item
= (wxMenuItem
*) node
->Data();
996 if ( !item
->IsSeparator() )
998 wxWindowID id
= item
->GetId();
999 wxUpdateUIEvent
event(id
);
1000 event
.SetEventObject( source
);
1002 if (source
->ProcessEvent(event
))
1004 if (event
.GetSetText())
1005 SetLabel(id
, event
.GetText());
1006 if (event
.GetSetChecked())
1007 Check(id
, event
.GetChecked());
1008 if (event
.GetSetEnabled())
1009 Enable(id
, event
.GetEnabled());
1012 if (item
->GetSubMenu())
1013 item
->GetSubMenu()->UpdateUI(source
);
1015 node
= node
->Next();