avoid duplicating wxWindow::HandleCommand() in wxFrame, only handle the commands for the frame menu bar elements there: this avoid generating duplicate events if a command event handler skips

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@54498 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2008-07-05 20:51:16 +00:00
parent 2587df2c82
commit a6ac49b198
4 changed files with 59 additions and 60 deletions

View File

@@ -87,10 +87,19 @@ public:
// and exists mainly in order to be overridden in the MDI parent frame // and exists mainly in order to be overridden in the MDI parent frame
// which also looks at its active child menu bar // which also looks at its active child menu bar
virtual const wxMenuItem *FindItemInMenuBar(int menuId) const; virtual const wxMenuItem *FindItemInMenuBar(int menuId) const;
#endif // wxUSE_MENUS
// process menu command: returns true if processed // generate menu command corresponding to the given menu item
//
// returns true if processed
bool ProcessCommand(wxMenuItem *item);
// generate menu command corresponding to the given menu command id
//
// returns true if processed
bool ProcessCommand(int winid); bool ProcessCommand(int winid);
#else
bool ProcessCommand(int WXUNUSED(winid)) { return false; }
#endif // wxUSE_MENUS
// status bar functions // status bar functions
// -------------------- // --------------------

View File

@@ -183,42 +183,45 @@ void wxFrameBase::SendSizeEvent()
// misc // misc
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#if wxUSE_MENUS
bool wxFrameBase::ProcessCommand(int id) bool wxFrameBase::ProcessCommand(int id)
{ {
#if wxUSE_MENUS
wxMenuBar *bar = GetMenuBar(); wxMenuBar *bar = GetMenuBar();
if ( !bar ) if ( !bar )
return false; return false;
wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id); wxMenuItem *item = bar->FindItem(id);
if ( !item )
return false;
return ProcessCommand(item);
}
bool wxFrameBase::ProcessCommand(wxMenuItem *item)
{
wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, item->GetId());
commandEvent.SetEventObject(this); commandEvent.SetEventObject(this);
wxMenuItem *item = bar->FindItem(id); if (!item->IsEnabled())
if (item) return true;
if ((item->GetKind() == wxITEM_RADIO) && item->IsChecked() )
return true;
if (item->IsCheckable())
{ {
if (!item->IsEnabled()) item->Toggle();
return true;
if ((item->GetKind() == wxITEM_RADIO) && item->IsChecked() ) // use the new value
return true; commandEvent.SetInt(item->IsChecked());
if (item->IsCheckable())
{
item->Toggle();
// use the new value
commandEvent.SetInt(item->IsChecked());
}
} }
return HandleWindowEvent(commandEvent); return HandleWindowEvent(commandEvent);
#else // !wxUSE_MENUS
wxUnusedVar(id);
return false;
#endif // wxUSE_MENUS/!wxUSE_MENUS
} }
#endif // wxUSE_MENUS
// Do the UI update processing for this window. This is // Do the UI update processing for this window. This is
// provided for the application to call if it wants to // provided for the application to call if it wants to
// force a UI update, particularly for the menus and toolbar. // force a UI update, particularly for the menus and toolbar.

View File

@@ -948,45 +948,29 @@ bool wxFrame::HandleSize(int WXUNUSED(x), int WXUNUSED(y), WXUINT id)
bool wxFrame::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND control) bool wxFrame::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND control)
{ {
// sign extend to int from short before comparing with the other int ids // we only need to handle the menu and accelerator commands from the items
int id = (signed short)id_; // of our menu bar, base wxWindow class already handles the rest
if ( !control && (cmd == 0 /* menu */ || cmd == 1 /* accel */) )
if ( control )
{
// In case it's e.g. a toolbar.
wxWindow *win = wxFindWinFromHandle(control);
if ( win )
return win->MSWCommand(cmd, id);
}
// handle here commands from menus and accelerators
if ( cmd == 0 || cmd == 1 )
{ {
#if wxUSE_MENUS_NATIVE #if wxUSE_MENUS_NATIVE
if ( wxCurrentPopupMenu ) if ( !wxCurrentPopupMenu )
{
wxMenu *popupMenu = wxCurrentPopupMenu;
wxCurrentPopupMenu = NULL;
return popupMenu->MSWCommand(cmd, id);
}
#endif // wxUSE_MENUS_NATIVE #endif // wxUSE_MENUS_NATIVE
#if defined(__SMARTPHONE__) && defined(__WXWINCE__)
// handle here commands from Smartphone menu bar
if ( wxTopLevelWindow::HandleCommand(id, cmd, control ) )
{ {
return true; wxMenuBar * const mbar = GetMenuBar();
} if ( mbar )
#endif // __SMARTPHONE__ && __WXWINCE__ {
// sign extend to int from short before comparing with the
// other int ids
const int id = (signed short)id_;
if ( ProcessCommand(id) ) wxMenuItem * const mitem = mbar->FindItem(id);
{ if ( mitem )
return true; return ProcessCommand(mitem);
}
} }
} }
return false; return wxFrameBase::HandleCommand(id_, cmd, control);;
} }
#if wxUSE_MENUS #if wxUSE_MENUS
@@ -1084,7 +1068,14 @@ WXLRESULT wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPara
UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam, UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam,
&id, &hwnd, &cmd); &id, &hwnd, &cmd);
processed = HandleCommand(id, cmd, (WXHWND)hwnd); HandleCommand(id, cmd, (WXHWND)hwnd);
// don't pass WM_COMMAND to the base class whether we processed
// it or not because we did generate an event for it (our
// HandleCommand() calls the base class version) and we must
// not do it again or the handlers which skip the event would
// be called twice
processed = true;
} }
break; break;

View File

@@ -5093,12 +5093,8 @@ bool wxWindowMSW::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND control)
// coming from a control to wxEVT_COMMAND_MENU_SELECTED // coming from a control to wxEVT_COMMAND_MENU_SELECTED
if ( !control ) if ( !control )
{ {
// If no child window, it may be an accelerator, e.g. for a popup menu wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, id);
// command
wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED);
event.SetEventObject(this); event.SetEventObject(this);
event.SetId(id);
event.SetInt(id); event.SetInt(id);
return HandleWindowEvent(event); return HandleWindowEvent(event);