diff --git a/src/generic/scrlwing.cpp b/src/generic/scrlwing.cpp index 6e0cca186f..bc1d5cdbde 100644 --- a/src/generic/scrlwing.cpp +++ b/src/generic/scrlwing.cpp @@ -204,7 +204,7 @@ bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event) m_hasDrawnWindow = true; // pass it on to the real handler - bool processed = wxEvtHandler::ProcessEvent(event); + bool processed = m_nextHandler->ProcessEventLocally(event); // always process the size events ourselves, even if the user code handles // them as well, as we need to AdjustScrollbars() diff --git a/tests/events/propagation.cpp b/tests/events/propagation.cpp index e240dd6e17..f27395f1a5 100644 --- a/tests/events/propagation.cpp +++ b/tests/events/propagation.cpp @@ -20,6 +20,7 @@ #ifndef WX_PRECOMP #include "wx/app.h" #include "wx/event.h" + #include "wx/scrolwin.h" #include "wx/window.h" #endif // WX_PRECOMP @@ -34,37 +35,58 @@ wxString g_str; // a custom event wxDEFINE_EVENT(TEST_EVT, wxCommandEvent); -// a custom event handler -class TestEvtHandler : public wxEvtHandler +// a custom event handler tracing the propagation of the events of the +// specified types +template +class TestEvtHandlerBase : public wxEvtHandler { public: - TestEvtHandler(char tag) - : m_tag(tag) + TestEvtHandlerBase(wxEventType evtType, char tag) + : m_evtType(evtType), + m_tag(tag) { - Connect(TEST_EVT, wxCommandEventHandler(TestEvtHandler::OnTest)); + Connect(evtType, + static_cast(&TestEvtHandlerBase::OnTest)); } // override ProcessEvent() to confirm that it is called for all event // handlers in the chain virtual bool ProcessEvent(wxEvent& event) { - if ( event.GetEventType() == TEST_EVT ) + if ( event.GetEventType() == m_evtType ) g_str += 'o'; // "o" == "overridden" return wxEvtHandler::ProcessEvent(event); } private: - void OnTest(wxCommandEvent& event) + void OnTest(wxEvent& event) { g_str += m_tag; event.Skip(); } + const wxEventType m_evtType; const char m_tag; - DECLARE_NO_COPY_CLASS(TestEvtHandler) + wxDECLARE_NO_COPY_TEMPLATE_CLASS(TestEvtHandlerBase, Event); +}; + +struct TestEvtHandler : TestEvtHandlerBase +{ + TestEvtHandler(char tag) + : TestEvtHandlerBase(TEST_EVT, tag) + { + } +}; + +struct TestPaintEvtHandler : TestEvtHandlerBase +{ + TestPaintEvtHandler(char tag) + : TestEvtHandlerBase(wxEVT_PAINT, tag) + { + } }; // a window handling the test event @@ -91,6 +113,35 @@ private: DECLARE_NO_COPY_CLASS(TestWindow) }; +// a scroll window handling paint event: we want to have a special test case +// for this because the event propagation is complicated even further than +// usual here by the presence of wxScrollHelperEvtHandler in the event handlers +// chain and the fact that OnDraw() virtual method must be called if EVT_PAINT +// is not handled +class TestScrollWindow : public wxScrolledWindow +{ +public: + TestScrollWindow(wxWindow *parent) + : wxScrolledWindow(parent, wxID_ANY) + { + Connect(wxEVT_PAINT, wxPaintEventHandler(TestScrollWindow::OnPaint)); + } + + virtual void OnDraw(wxDC& WXUNUSED(dc)) + { + g_str += 'D'; // draw + } + +private: + void OnPaint(wxPaintEvent& event) + { + g_str += 'P'; // paint + event.Skip(); + } + + wxDECLARE_NO_COPY_CLASS(TestScrollWindow); +}; + int DoFilterEvent(wxEvent& event) { if ( event.GetEventType() == TEST_EVT ) @@ -127,12 +178,16 @@ private: CPPUNIT_TEST( TwoHandlers ); CPPUNIT_TEST( WindowWithoutHandler ); CPPUNIT_TEST( WindowWithHandler ); + CPPUNIT_TEST( ScrollWindowWithoutHandler ); + CPPUNIT_TEST( ScrollWindowWithHandler ); CPPUNIT_TEST_SUITE_END(); void OneHandler(); void TwoHandlers(); void WindowWithoutHandler(); void WindowWithHandler(); + void ScrollWindowWithoutHandler(); + void ScrollWindowWithHandler(); DECLARE_NO_COPY_CLASS(EventPropagationTestCase) }; @@ -207,3 +262,29 @@ void EventPropagationTestCase::WindowWithHandler() CPPUNIT_ASSERT_EQUAL( "oa2o1cpA", g_str ); } +void EventPropagationTestCase::ScrollWindowWithoutHandler() +{ + TestScrollWindow * const + win = new TestScrollWindow(wxTheApp->GetTopWindow()); + wxON_BLOCK_EXIT_OBJ0( *win, wxWindow::Destroy ); + + wxPaintEvent event(win->GetId()); + win->ProcessWindowEvent(event); + CPPUNIT_ASSERT_EQUAL( "PD", g_str ); +} + +void EventPropagationTestCase::ScrollWindowWithHandler() +{ + TestScrollWindow * const + win = new TestScrollWindow(wxTheApp->GetTopWindow()); + wxON_BLOCK_EXIT_OBJ0( *win, wxWindow::Destroy ); + + TestPaintEvtHandler h('h'); + win->PushEventHandler(&h); + wxON_BLOCK_EXIT_OBJ1( *win, wxWindow::PopEventHandler, false ); + + wxPaintEvent event(win->GetId()); + win->ProcessWindowEvent(event); + CPPUNIT_ASSERT_EQUAL( "ohPD", g_str ); +} +