diff --git a/include/wx/window.h b/include/wx/window.h index 9218362735..52b6daafc2 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -803,6 +803,13 @@ public: bool ProcessWindowEvent(wxEvent& event) { return GetEventHandler()->ProcessEvent(event); } + // Call GetEventHandler()->ProcessEventLocally(): this should be used + // instead of calling ProcessEventLocally() directly on the window + // itself as this wouldn't take any pushed event handlers into account + // correctly + bool ProcessWindowEventLocally(wxEvent& event) + { return GetEventHandler()->ProcessEventLocally(event); } + // Process an event by calling GetEventHandler()->ProcessEvent() and // handling any exceptions thrown by event handlers. It's mostly useful // when processing wx events when called from C code (e.g. in GTK+ @@ -830,6 +837,7 @@ protected: // The same holds for all other wxEvtHandler functions. using wxEvtHandler::ProcessEvent; + using wxEvtHandler::ProcessEventLocally; #if wxUSE_THREADS using wxEvtHandler::ProcessThreadEvent; #endif diff --git a/interface/wx/window.h b/interface/wx/window.h index 63b2703191..ffa3548aec 100644 --- a/interface/wx/window.h +++ b/interface/wx/window.h @@ -1840,6 +1840,19 @@ public: */ bool ProcessWindowEvent(wxEvent& event); + /** + Wrapper for wxEvtHandler::ProcessEventLocally(). + + This method is similar to ProcessWindowEvent() but can be used to + search for the event handler only in this window and any event handlers + pushed on top of it. Unlike ProcessWindowEvent() it won't propagate the + event upwards. But unlike wxEvtHandler::ProcessEventHere() it will use + the event handlers associated with this window. + + @since 2.9.1 + */ + bool ProcessWindowEventLocally(wxEvent& event); + /** Removes and returns the top-most event handler on the event handler stack. diff --git a/samples/mdi/mdi.cpp b/samples/mdi/mdi.cpp index 1866983260..a1ebf73cb8 100644 --- a/samples/mdi/mdi.cpp +++ b/samples/mdi/mdi.cpp @@ -99,6 +99,10 @@ BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow) EVT_MOUSE_EVENTS(MyCanvas::OnEvent) END_EVENT_TABLE() +BEGIN_EVENT_TABLE(MyChild::EventHandler, wxEvtHandler) + EVT_MENU(MDI_REFRESH, MyChild::EventHandler::OnRefresh) +END_EVENT_TABLE() + // =========================================================================== // implementation // =========================================================================== @@ -451,10 +455,16 @@ MyChild::MyChild(wxMDIParentFrame *parent) // they can be resized at all if ( canBeResized ) SetSizeHints(100, 100); + + // test that event handlers pushed on top of MDI children do work (this + // used to be broken, see #11225) + PushEventHandler(new EventHandler(ms_numChildren)); } MyChild::~MyChild() { + PopEventHandler(true); + ms_numChildren--; } diff --git a/samples/mdi/mdi.h b/samples/mdi/mdi.h index 82a5330c37..e04957b831 100644 --- a/samples/mdi/mdi.h +++ b/samples/mdi/mdi.h @@ -94,6 +94,26 @@ private: MyCanvas *m_canvas; + // simple test event handler class + class EventHandler : public wxEvtHandler + { + public: + EventHandler(unsigned numChild) : m_numChild(numChild) { } + + private: + void OnRefresh(wxCommandEvent& event) + { + wxLogMessage("Child #%u refreshed.", m_numChild); + event.Skip(); + } + + const unsigned m_numChild; + + DECLARE_EVENT_TABLE() + + wxDECLARE_NO_COPY_CLASS(EventHandler); + }; + DECLARE_EVENT_TABLE() }; diff --git a/src/msw/mdi.cpp b/src/msw/mdi.cpp index 9bcee0a86a..6dd3e63db5 100644 --- a/src/msw/mdi.cpp +++ b/src/msw/mdi.cpp @@ -686,7 +686,7 @@ bool wxMDIParentFrame::TryBefore(wxEvent& event) if ( event.GetEventType() == wxEVT_COMMAND_MENU_SELECTED ) { wxMDIChildFrame * const child = GetActiveChild(); - if ( child && child->ProcessEventHere(event) ) + if ( child && child->ProcessWindowEventLocally(event) ) return true; }