From 396e9eb8e296a2e128efa16c88c7899275b454ec Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin <vadim@wxwidgets.org> Date: Sun, 9 May 2010 14:55:33 +0000 Subject: [PATCH] Add wxWindow::ProcessWindowEventLocally() and use it in wxMSW MDI code. Add ProcessWindowEventLocally() which wraps ProcessEventLocally() in the same way as ProcessWindowEvent() wraps ProcessEvent(). I.e. it allows to process the event in this window only, without propagating it upwards, but taking into account any event handlers associated with it. Use the new method in wxMDIParentFrame code in wxMSW to ensure that event handlers pushed on MDI children frames are taken into account. Add a test for this to the MDI sample. Closes #11225. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64262 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/window.h | 8 ++++++++ interface/wx/window.h | 13 +++++++++++++ samples/mdi/mdi.cpp | 10 ++++++++++ samples/mdi/mdi.h | 20 ++++++++++++++++++++ src/msw/mdi.cpp | 2 +- 5 files changed, 52 insertions(+), 1 deletion(-) 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; } -- 2.47.2