From a6ac49b198cf4693752344cffa20b46bed364c77 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 5 Jul 2008 20:51:16 +0000 Subject: [PATCH] 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 --- include/wx/frame.h | 13 ++++++++-- src/common/framecmn.cpp | 43 +++++++++++++++++--------------- src/msw/frame.cpp | 55 +++++++++++++++++------------------------ src/msw/window.cpp | 6 +---- 4 files changed, 58 insertions(+), 59 deletions(-) diff --git a/include/wx/frame.h b/include/wx/frame.h index fe718971b7..3816a57b3e 100644 --- a/include/wx/frame.h +++ b/include/wx/frame.h @@ -87,10 +87,19 @@ public: // and exists mainly in order to be overridden in the MDI parent frame // which also looks at its active child menu bar 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); +#else + bool ProcessCommand(int WXUNUSED(winid)) { return false; } +#endif // wxUSE_MENUS // status bar functions // -------------------- diff --git a/src/common/framecmn.cpp b/src/common/framecmn.cpp index 710742fd71..f09e2c67cc 100644 --- a/src/common/framecmn.cpp +++ b/src/common/framecmn.cpp @@ -183,42 +183,45 @@ void wxFrameBase::SendSizeEvent() // misc // ---------------------------------------------------------------------------- +#if wxUSE_MENUS + bool wxFrameBase::ProcessCommand(int id) { -#if wxUSE_MENUS wxMenuBar *bar = GetMenuBar(); if ( !bar ) 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); - wxMenuItem *item = bar->FindItem(id); - if (item) - { - if (!item->IsEnabled()) - return true; + if (!item->IsEnabled()) + return true; - if ((item->GetKind() == wxITEM_RADIO) && item->IsChecked() ) - return true; + if ((item->GetKind() == wxITEM_RADIO) && item->IsChecked() ) + return true; - if (item->IsCheckable()) - { - item->Toggle(); + if (item->IsCheckable()) + { + item->Toggle(); - // use the new value - commandEvent.SetInt(item->IsChecked()); - } + // use the new value + commandEvent.SetInt(item->IsChecked()); } 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 // provided for the application to call if it wants to // force a UI update, particularly for the menus and toolbar. diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp index 41b15c2875..917fd8220f 100644 --- a/src/msw/frame.cpp +++ b/src/msw/frame.cpp @@ -948,45 +948,29 @@ bool wxFrame::HandleSize(int WXUNUSED(x), int WXUNUSED(y), WXUINT id) bool wxFrame::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND control) { - // sign extend to int from short before comparing with the other int ids - int id = (signed short)id_; - - 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 ) + // we only need to handle the menu and accelerator commands from the items + // of our menu bar, base wxWindow class already handles the rest + if ( !control && (cmd == 0 /* menu */ || cmd == 1 /* accel */) ) { #if wxUSE_MENUS_NATIVE - if ( wxCurrentPopupMenu ) - { - wxMenu *popupMenu = wxCurrentPopupMenu; - wxCurrentPopupMenu = NULL; - - return popupMenu->MSWCommand(cmd, id); - } + if ( !wxCurrentPopupMenu ) #endif // wxUSE_MENUS_NATIVE - -#if defined(__SMARTPHONE__) && defined(__WXWINCE__) - // handle here commands from Smartphone menu bar - if ( wxTopLevelWindow::HandleCommand(id, cmd, control ) ) { - return true; - } -#endif // __SMARTPHONE__ && __WXWINCE__ + wxMenuBar * const mbar = GetMenuBar(); + if ( mbar ) + { + // sign extend to int from short before comparing with the + // other int ids + const int id = (signed short)id_; - if ( ProcessCommand(id) ) - { - return true; + wxMenuItem * const mitem = mbar->FindItem(id); + if ( mitem ) + return ProcessCommand(mitem); + } } } - return false; + return wxFrameBase::HandleCommand(id_, cmd, control);; } #if wxUSE_MENUS @@ -1084,7 +1068,14 @@ WXLRESULT wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPara UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam, &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; diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 1101fb474c..2da6ce31ef 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -5093,12 +5093,8 @@ bool wxWindowMSW::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND control) // coming from a control to wxEVT_COMMAND_MENU_SELECTED if ( !control ) { - // If no child window, it may be an accelerator, e.g. for a popup menu - // command - - wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED); + wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, id); event.SetEventObject(this); - event.SetId(id); event.SetInt(id); return HandleWindowEvent(event); -- 2.45.2