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
41 // ----------------------------------------------------------------------------
43 // ----------------------------------------------------------------------------
45 extern wxMenu
*wxCurrentPopupMenu
;
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 // the (popup) menu title has this special id
52 static const int idMenuTitle
= -2;
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 #if !USE_SHARED_LIBRARY
59 IMPLEMENT_DYNAMIC_CLASS(wxMenu
, wxEvtHandler
)
60 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
, wxEvtHandler
)
64 #define GetHMENU() ((HMENU)GetHMenu())
65 #define GetHMenuOf(menu) ((HMENU)menu->GetHMenu())
67 // ============================================================================
69 // ============================================================================
73 // Construct a menu with optional title (then use append)
74 wxMenu::wxMenu(const wxString
& title
, const wxFunction func
)
78 m_eventHandler
= this;
79 m_pInvokingWindow
= NULL
;
83 m_hMenu
= (WXHMENU
) CreatePopupMenu();
85 m_topLevelMenu
= this;
86 m_clientData
= (void*) NULL
;
90 Append(idMenuTitle
, m_title
) ;
97 // The wxWindow destructor will take care of deleting the submenus.
101 DestroyMenu((HMENU
) m_hMenu
);
104 // Windows seems really bad on Menu de-allocation...
105 // After many try, here is what I do: RemoveMenu() will ensure
106 // that popup are "disconnected" from their parent; then call
107 // delete method on each child (which in turn do a recursive job),
108 // and finally, DestroyMenu()
110 // With that, BoundCheckers is happy, and no complaints...
114 N = GetMenuItemCount(m_hMenu);
116 for (i = N-1; i >= 0; i--)
117 RemoveMenu(m_hMenu, i, MF_BYPOSITION);
120 // How is deleting submenus in this loop any different from deleting
121 // the submenus in the children list, via ~wxWindow ?
122 // I'll reinstate this deletion for now and remove addition
123 // from children list (which doesn't exist now)
125 wxNode
*node
= m_menuItems
.First();
128 wxMenuItem
*item
= (wxMenuItem
*)node
->Data();
130 // Delete child menus.
131 // Beware: they must not be appended to children list!!!
132 // (because order of delete is significant)
133 if (item
->GetSubMenu())
134 item
->DeleteSubMenu();
136 wxNode
*next
= node
->Next();
143 DestroyMenu(m_hMenu);
153 // function appends a new item or submenu to the menu
154 void wxMenu::Append(wxMenuItem
*pItem
)
156 wxCHECK_RET( pItem
!= NULL
, "can't append NULL item to the menu" );
158 m_menuItems
.Append(pItem
);
163 flags
|= MF_MENUBREAK
;
167 if ( pItem
->IsSeparator() ) {
168 flags
|= MF_SEPARATOR
;
171 // id is the numeric id for normal menu items and HMENU for submenus
173 wxMenu
*SubMenu
= pItem
->GetSubMenu();
174 if ( SubMenu
!= NULL
) {
175 wxASSERT( SubMenu
->m_hMenu
!= (WXHMENU
) NULL
);
177 id
= (UINT
)SubMenu
->m_hMenu
;
179 SubMenu
->m_topLevelMenu
= m_topLevelMenu
;
180 SubMenu
->m_parent
= this;
181 SubMenu
->m_savehMenu
= (WXHMENU
)id
;
182 SubMenu
->m_hMenu
= 0;
192 #if wxUSE_OWNER_DRAWN
193 if ( pItem
->IsOwnerDrawn() ) { // want to get {Measure|Draw}Item messages?
194 // item draws itself, pass pointer to it in data parameter
195 flags
|= MF_OWNERDRAW
;
196 pData
= (LPCSTR
)pItem
;
201 // menu is just a normal string (passed in data parameter)
203 pData
= pItem
->GetName();
206 // visually select the menu title
207 if ( id
== idMenuTitle
)
209 // TODO use SetMenuItemInfo(MFS_DEFAULT) to put it in bold face
212 if ( !AppendMenu(GetHMENU(), flags
, id
, pData
) )
214 wxLogLastError("AppendMenu");
220 void wxMenu::AppendSeparator()
222 Append(new wxMenuItem(this, ID_SEPARATOR
));
226 void wxMenu::Append(int id
, const wxString
& label
,
227 wxMenu
*SubMenu
, const wxString
& helpString
)
229 Append(new wxMenuItem(this, id
, label
, helpString
, FALSE
, SubMenu
));
232 // Ordinary menu item
233 void wxMenu::Append(int id
, const wxString
& label
,
234 const wxString
& helpString
, bool checkable
)
236 // 'checkable' parameter is useless for Windows.
237 Append(new wxMenuItem(this, id
, label
, helpString
, checkable
));
240 void wxMenu::Delete(int id
)
242 wxMenuItem
*item
= NULL
;
245 for (pos
= 0, node
= m_menuItems
.First(); node
; node
= node
->Next(), pos
++)
247 item
= (wxMenuItem
*)node
->Data();
248 if ( item
->GetId() == id
)
252 wxCHECK_RET( node
, "wxMenu::Delete(): item doesn't exist" );
254 HMENU menu
= GetHMENU();
256 wxMenu
*pSubMenu
= item
->GetSubMenu();
257 if ( pSubMenu
!= NULL
) {
258 RemoveMenu(menu
, (UINT
)pos
, MF_BYPOSITION
);
259 pSubMenu
->m_hMenu
= pSubMenu
->m_savehMenu
;
260 pSubMenu
->m_savehMenu
= 0;
261 pSubMenu
->m_parent
= NULL
;
262 // RemoveChild(item->subMenu);
263 pSubMenu
->m_topLevelMenu
= NULL
;
264 // TODO: Why isn't subMenu deleted here???
265 // Will put this in for now. Assuming this is supposed
266 // to delete the menu, not just remove it.
267 item
->DeleteSubMenu();
270 DeleteMenu(menu
, (UINT
)pos
, MF_BYPOSITION
);
273 m_menuItems
.DeleteNode(node
);
277 void wxMenu::Enable(int id
, bool Flag
)
279 wxMenuItem
*item
= FindItemForId(id
);
280 wxCHECK_RET( item
!= NULL
, "can't enable non-existing menu item" );
285 bool wxMenu::IsEnabled(int id
) const
287 wxMenuItem
*item
= FindItemForId(id
);
288 wxCHECK_MSG( item
!= NULL
, FALSE
, "invalid item id" );
290 return item
->IsEnabled();
293 void wxMenu::Check(int id
, bool Flag
)
295 wxMenuItem
*item
= FindItemForId(id
);
296 wxCHECK_RET( item
!= NULL
, "can't get status of non-existing menu item" );
301 bool wxMenu::IsChecked(int id
) const
303 wxMenuItem
*item
= FindItemForId(id
);
304 wxCHECK_MSG( item
!= NULL
, FALSE
, "invalid item id" );
306 return item
->IsChecked();
309 void wxMenu::SetTitle(const wxString
& label
)
311 bool hasNoTitle
= m_title
.IsEmpty();
314 HMENU hMenu
= GetHMENU();
318 if ( !label
.IsEmpty() )
320 if ( !InsertMenu(hMenu
, 0u, MF_BYPOSITION
| MF_STRING
,
321 (unsigned)idMenuTitle
, m_title
) ||
322 !InsertMenu(hMenu
, 1u, MF_BYPOSITION
, (unsigned)-1, NULL
) )
324 wxLogLastError("InsertMenu");
330 if ( label
.IsEmpty() )
332 // remove the title and the separator after it
333 if ( !RemoveMenu(hMenu
, 0, MF_BYPOSITION
) ||
334 !RemoveMenu(hMenu
, 0, MF_BYPOSITION
) )
336 wxLogLastError("RemoveMenu");
342 if ( !ModifyMenu(hMenu
, 0u,
343 MF_BYPOSITION
| MF_STRING
,
344 (unsigned)idMenuTitle
, m_title
) )
346 wxLogLastError("ModifyMenu");
352 // put the title string in bold face
353 if ( !m_title
.IsEmpty() )
356 mii
.cbSize
= sizeof(mii
);
357 mii
.fMask
= MIIM_STATE
;
358 mii
.fState
= MFS_DEFAULT
;
360 if ( !SetMenuItemInfo(hMenu
, (unsigned)idMenuTitle
, FALSE
, &mii
) )
362 wxLogLastError("SetMenuItemInfo");
368 const wxString
wxMenu::GetTitle() const
373 void wxMenu::SetLabel(int id
, const wxString
& label
)
375 wxMenuItem
*item
= FindItemForId(id
) ;
379 if (item
->GetSubMenu()==NULL
)
381 HMENU hMenu
= GetHMENU();
383 UINT was_flag
= GetMenuState(hMenu
, id
, MF_BYCOMMAND
);
384 ModifyMenu(hMenu
, id
, MF_BYCOMMAND
| MF_STRING
| was_flag
, id
, label
);
388 wxMenu
*father
= item
->GetSubMenu()->m_topLevelMenu
;
389 wxNode
*node
= father
->m_menuItems
.First() ;
393 wxMenuItem
*matched
= (wxMenuItem
*)node
->Data() ;
397 node
= node
->Next() ;
399 // Here, we have the position.
400 ModifyMenu((HMENU
)father
->m_savehMenu
,i
,
401 MF_BYPOSITION
|MF_STRING
|MF_POPUP
,
402 (UINT
)item
->GetSubMenu()->m_savehMenu
,(const char *)label
) ;
404 item
->SetName(label
);
407 wxString
wxMenu::GetLabel(int id
) const
410 wxMenuItem
*pItem
= FindItemForId(id
) ;
412 label
= pItem
->GetName() ;
414 wxFAIL_MSG("wxMenu::GetLabel: item doesn't exist");
419 bool wxMenu::MSWCommand(WXUINT
WXUNUSED(param
), WXWORD id
)
421 // ignore commands from the menu title
423 // NB: VC++ generates wrong assembler for `if ( id != idMenuTitle )'!!
424 if ( id
!= (WXWORD
)idMenuTitle
)
426 wxCommandEvent
event(wxEVT_COMMAND_MENU_SELECTED
);
427 event
.SetEventObject( this );
430 ProcessCommand(event
);
436 // Finds the item id matching the given string, -1 if not found.
437 int wxMenu::FindItem (const wxString
& itemString
) const
439 // FIXME fixed size buffer
442 wxStripMenuCodes ((char *)(const char *)itemString
, buf1
);
444 for (wxNode
* node
= m_menuItems
.First (); node
; node
= node
->Next ())
446 wxMenuItem
*item
= (wxMenuItem
*) node
->Data ();
447 if (item
->GetSubMenu())
449 int ans
= item
->GetSubMenu()->FindItem(itemString
);
453 if ( !item
->IsSeparator() )
455 wxStripMenuCodes((char *)item
->GetName().c_str(), buf2
);
456 if (strcmp(buf1
, buf2
) == 0)
457 return item
->GetId();
464 wxMenuItem
*wxMenu::FindItemForId(int itemId
, wxMenu
** itemMenu
) const
468 for (wxNode
* node
= m_menuItems
.First (); node
; node
= node
->Next ())
470 wxMenuItem
*item
= (wxMenuItem
*) node
->Data ();
472 if (item
->GetId() == itemId
)
475 *itemMenu
= (wxMenu
*) this;
479 if (item
->GetSubMenu())
481 wxMenuItem
*ans
= item
->GetSubMenu()->FindItemForId (itemId
, itemMenu
);
492 void wxMenu::SetHelpString(int itemId
, const wxString
& helpString
)
494 wxMenuItem
*item
= FindItemForId (itemId
);
496 item
->SetHelp(helpString
);
498 wxFAIL_MSG("wxMenu::SetHelpString: item doesn't exist");
501 wxString
wxMenu::GetHelpString (int itemId
) const
504 wxMenuItem
*item
= FindItemForId (itemId
);
506 help
= item
->GetHelp();
508 wxFAIL_MSG("wxMenu::GetHelpString: item doesn't exist");
513 void wxMenu::ProcessCommand(wxCommandEvent
& event
)
515 bool processed
= FALSE
;
520 (void)(*(m_callback
))(*this, event
);
524 // Try the menu's event handler
525 if ( !processed
&& GetEventHandler())
527 processed
= GetEventHandler()->ProcessEvent(event
);
530 // Try the window the menu was popped up from (and up through the
532 wxWindow
*win
= GetInvokingWindow();
533 if ( !processed
&& win
)
534 processed
= win
->GetEventHandler()->ProcessEvent(event
);
537 bool wxWindow::PopupMenu(wxMenu
*menu
, int x
, int y
)
539 menu
->SetInvokingWindow(this);
542 HWND hWnd
= (HWND
) GetHWND();
543 HMENU hMenu
= (HMENU
)menu
->m_hMenu
;
547 ::ClientToScreen(hWnd
, &point
);
548 wxCurrentPopupMenu
= menu
;
549 ::TrackPopupMenu(hMenu
, TPM_RIGHTBUTTON
, point
.x
, point
.y
, 0, hWnd
, NULL
);
551 wxCurrentPopupMenu
= NULL
;
553 menu
->SetInvokingWindow(NULL
);
559 wxMenuBar::wxMenuBar()
561 m_eventHandler
= this;
565 m_menuBarFrame
= NULL
;
569 wxMenuBar::wxMenuBar( long WXUNUSED(style
) )
571 m_eventHandler
= this;
575 m_menuBarFrame
= NULL
;
579 wxMenuBar::wxMenuBar(int N
, wxMenu
*Menus
[], const wxString Titles
[])
581 m_eventHandler
= this;
584 m_titles
= new wxString
[N
];
586 for ( i
= 0; i
< N
; i
++ )
587 m_titles
[i
] = Titles
[i
];
588 m_menuBarFrame
= NULL
;
589 for (i
= 0; i
< N
; i
++)
590 m_menus
[i
]->m_menuBar
= (wxMenuBar
*) this;
595 wxMenuBar::~wxMenuBar()
597 // In fact, don't want menu to be destroyed before MDI
598 // shuffling has taken place. Let it be destroyed
599 // automatically when the window is destroyed.
601 // DestroyMenu(menu);
606 // See remarks in ::~wxMenu() method
607 // BEWARE - this may interfere with MDI fixes, so
608 // may need to remove
611 if (m_menuBarFrame && ((m_menuBarFrame->GetWindowStyleFlag() & wxSDI) == wxSDI))
614 N = GetMenuItemCount(menu) ;
615 for (i = N-1; i >= 0; i--)
616 RemoveMenu(menu, i, MF_BYPOSITION);
619 for (i
= 0; i
< m_menuCount
; i
++)
626 /* Don't destroy menu here, in case we're MDI and
627 need to do some shuffling with VALID menu handles.
634 // Must only be used AFTER menu has been attached to frame,
635 // otherwise use individual menus to enable/disable items
636 void wxMenuBar::Enable(int id
, bool enable
)
638 int flag
= enable
? MF_ENABLED
: MF_GRAYED
;
640 wxMenu
*itemMenu
= NULL
;
641 wxMenuItem
*item
= FindItemForId(id
, &itemMenu
) ;
643 wxCHECK_RET( item
, "attempt to enable an item which doesn't exist" );
645 EnableMenuItem(GetHMenuOf(itemMenu
), id
, MF_BYCOMMAND
| flag
);
648 void wxMenuBar::EnableTop(int pos
, bool enable
)
650 int flag
= enable
? MF_ENABLED
: MF_GRAYED
;;
652 EnableMenuItem((HMENU
)m_hMenu
, pos
, MF_BYPOSITION
| flag
);
653 DrawMenuBar((HWND
)m_menuBarFrame
->GetHWND()) ;
656 // Must only be used AFTER menu has been attached to frame,
657 // otherwise use individual menus
658 void wxMenuBar::Check(int id
, bool check
)
660 wxMenu
*itemMenu
= NULL
;
661 wxMenuItem
*item
= FindItemForId(id
, &itemMenu
) ;
663 wxCHECK_RET( item
, "attempt to check an item which doesn't exist" );
664 wxCHECK_RET( item
->IsCheckable(), "attempt to check an uncheckable item" );
666 int flag
= check
? MF_CHECKED
: MF_UNCHECKED
;
667 CheckMenuItem(GetHMenuOf(itemMenu
), id
, MF_BYCOMMAND
| flag
);
670 bool wxMenuBar::IsChecked(int id
) const
672 wxMenu
*itemMenu
= NULL
;
673 wxMenuItem
*item
= FindItemForId(id
, &itemMenu
) ;
675 wxCHECK_MSG( item
, FALSE
, "wxMenuItem::IsChecked(): no such item" );
677 int flag
= ::GetMenuState(GetHMenuOf(itemMenu
), id
, MF_BYCOMMAND
);
679 return (flag
& MF_CHECKED
) != 0;
682 bool wxMenuBar::IsEnabled(int id
) const
684 wxMenu
*itemMenu
= NULL
;
685 wxMenuItem
*item
= FindItemForId(id
, &itemMenu
) ;
687 wxCHECK_MSG( item
, FALSE
, "wxMenuItem::IsEnabled(): no such item" );
689 int flag
= ::GetMenuState(GetHMenuOf(itemMenu
), id
, MF_BYCOMMAND
) ;
691 return (flag
& MF_ENABLED
) != 0;
694 void wxMenuBar::SetLabel(int id
, const wxString
& label
)
696 wxMenu
*itemMenu
= NULL
;
697 wxMenuItem
*item
= FindItemForId(id
, &itemMenu
) ;
702 HMENU hMenu
= GetHMenuOf(itemMenu
);
703 UINT was_flag
= ::GetMenuState(hMenu
, id
, MF_BYCOMMAND
);
704 ::ModifyMenu(hMenu
, id
, MF_BYCOMMAND
| MF_STRING
| was_flag
, id
, label
);
707 wxString
wxMenuBar::GetLabel(int id
) const
709 wxMenu
*itemMenu
= NULL
;
710 wxMenuItem
*item
= FindItemForId(id
, &itemMenu
) ;
712 wxCHECK_MSG( item
, "", "wxMenuItem::GetLabel(): no such item" );
714 HMENU hMenu
= GetHMenuOf(itemMenu
);
715 int len
= ::GetMenuString(hMenu
, id
, NULL
, 0, MF_BYCOMMAND
);
717 len
++; // for the NUL character
719 ::GetMenuString(hMenu
, id
, label
.GetWriteBuf(len
), len
, MF_BYCOMMAND
);
720 label
.UngetWriteBuf();
725 void wxMenuBar::SetLabelTop(int pos
, const wxString
& label
)
728 UINT was_flag
= ::GetMenuState((HMENU
)m_hMenu
, pos
, MF_BYPOSITION
);
729 if (was_flag
& MF_POPUP
)
732 id
= (UINT
)::GetSubMenu((HMENU
)m_hMenu
, pos
) ;
739 ::ModifyMenu((HMENU
)m_hMenu
, pos
, MF_BYPOSITION
| MF_STRING
| was_flag
,
743 wxString
wxMenuBar::GetLabelTop(int pos
) const
745 int len
= ::GetMenuString((HMENU
)m_hMenu
, pos
, NULL
, 0, MF_BYCOMMAND
);
747 len
++; // for the NUL character
749 ::GetMenuString((HMENU
)m_hMenu
, pos
, label
.GetWriteBuf(len
), len
, MF_BYCOMMAND
);
750 label
.UngetWriteBuf();
755 bool wxMenuBar::OnDelete(wxMenu
*a_menu
, int pos
)
760 if (RemoveMenu((HMENU
)m_hMenu
, (UINT
)pos
, MF_BYPOSITION
)) {
761 m_menus
[pos
]->m_hMenu
= m_menus
[pos
]->m_savehMenu
;
762 m_menus
[pos
]->m_savehMenu
= 0;
764 if (m_menuBarFrame
) {
765 DrawMenuBar((HWND
) m_menuBarFrame
->GetHWND()) ;
774 bool wxMenuBar::OnAppend(wxMenu
*a_menu
, const char *title
)
776 if (!a_menu
->m_hMenu
)
782 a_menu
->m_savehMenu
= a_menu
->m_hMenu
;
785 AppendMenu((HMENU
)m_hMenu
, MF_POPUP
| MF_STRING
, (UINT
)a_menu
->m_savehMenu
, title
);
787 DrawMenuBar((HWND
)m_menuBarFrame
->GetHWND());
792 void wxMenuBar::Append (wxMenu
* menu
, const wxString
& title
)
794 if (!OnAppend(menu
, title
))
798 wxMenu
**new_menus
= new wxMenu
*[m_menuCount
];
799 wxString
*new_titles
= new wxString
[m_menuCount
];
802 for (i
= 0; i
< m_menuCount
- 1; i
++)
804 new_menus
[i
] = m_menus
[i
];
806 new_titles
[i
] = m_titles
[i
];
815 m_titles
= new_titles
;
817 m_menus
[m_menuCount
- 1] = (wxMenu
*)menu
;
818 m_titles
[m_menuCount
- 1] = title
;
820 ((wxMenu
*)menu
)->m_menuBar
= (wxMenuBar
*) this;
821 ((wxMenu
*)menu
)->SetParent(this);
824 void wxMenuBar::Delete(wxMenu
* menu
, int i
)
830 for (ii
= 0; ii
< m_menuCount
; ii
++) {
831 if (m_menus
[ii
] == menu
)
834 if (ii
>= m_menuCount
)
837 if (ii
< 0 || ii
>= m_menuCount
)
842 if (!OnDelete(menu
, ii
))
845 menu
->SetParent(NULL
);
848 for (j
= ii
; j
< m_menuCount
; j
++) {
849 m_menus
[j
] = m_menus
[j
+ 1];
850 m_titles
[j
] = m_titles
[j
+ 1];
854 // Find the menu menuString, item itemString, and return the item id.
855 // Returns -1 if none found.
856 int wxMenuBar::FindMenuItem (const wxString
& menuString
, const wxString
& itemString
) const
860 wxStripMenuCodes ((char *)(const char *)menuString
, buf1
);
862 for (i
= 0; i
< m_menuCount
; i
++)
864 wxStripMenuCodes ((char *)(const char *)m_titles
[i
], buf2
);
865 if (strcmp (buf1
, buf2
) == 0)
866 return m_menus
[i
]->FindItem (itemString
);
871 wxMenuItem
*wxMenuBar::FindItemForId (int id
, wxMenu
** itemMenu
) const
876 wxMenuItem
*item
= NULL
;
878 for (i
= 0; i
< m_menuCount
; i
++)
880 item
= m_menus
[i
]->FindItemForId (id
, itemMenu
);
887 void wxMenuBar::SetHelpString (int id
, const wxString
& helpString
)
890 for (i
= 0; i
< m_menuCount
; i
++)
892 if (m_menus
[i
]->FindItemForId (id
))
894 m_menus
[i
]->SetHelpString (id
, helpString
);
900 wxString
wxMenuBar::GetHelpString (int id
) const
904 for (int i
= 0; i
< m_menuCount
; i
++)
906 wxMenuItem
*item
= m_menus
[i
]->FindItemForId(id
);
909 helpString
= item
->GetHelp();
918 // ----------------------------------------------------------------------------
920 // ----------------------------------------------------------------------------
922 wxWindow
*wxMenu::GetWindow() const
924 if ( m_pInvokingWindow
!= NULL
)
925 return m_pInvokingWindow
;
926 else if ( m_menuBar
!= NULL
)
927 return m_menuBar
->m_menuBarFrame
;
932 WXHMENU
wxMenu::GetHMenu() const
936 else if ( m_savehMenu
!= 0 )
939 wxFAIL_MSG("wxMenu without HMENU");
944 // Update a menu and all submenus recursively. source is the object that has
945 // the update event handlers defined for it. If NULL, the menu or associated
946 // window will be used.
947 void wxMenu::UpdateUI(wxEvtHandler
* source
)
949 if (!source
&& GetInvokingWindow())
950 source
= GetInvokingWindow()->GetEventHandler();
952 source
= GetEventHandler();
956 wxNode
* node
= GetItems().First();
959 wxMenuItem
* item
= (wxMenuItem
*) node
->Data();
960 if ( !item
->IsSeparator() )
962 wxWindowID id
= item
->GetId();
963 wxUpdateUIEvent
event(id
);
964 event
.SetEventObject( source
);
966 if (source
->ProcessEvent(event
))
968 if (event
.GetSetText())
969 SetLabel(id
, event
.GetText());
970 if (event
.GetSetChecked())
971 Check(id
, event
.GetChecked());
972 if (event
.GetSetEnabled())
973 Enable(id
, event
.GetEnabled());
976 if (item
->GetSubMenu())
977 item
->GetSubMenu()->UpdateUI(source
);