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
This commit is contained in:
Vadim Zeitlin
2010-05-09 14:55:33 +00:00
parent 3cbb9df817
commit 396e9eb8e2
5 changed files with 52 additions and 1 deletions

View File

@@ -803,6 +803,13 @@ public:
bool ProcessWindowEvent(wxEvent& event) bool ProcessWindowEvent(wxEvent& event)
{ return GetEventHandler()->ProcessEvent(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 // Process an event by calling GetEventHandler()->ProcessEvent() and
// handling any exceptions thrown by event handlers. It's mostly useful // handling any exceptions thrown by event handlers. It's mostly useful
// when processing wx events when called from C code (e.g. in GTK+ // 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. // The same holds for all other wxEvtHandler functions.
using wxEvtHandler::ProcessEvent; using wxEvtHandler::ProcessEvent;
using wxEvtHandler::ProcessEventLocally;
#if wxUSE_THREADS #if wxUSE_THREADS
using wxEvtHandler::ProcessThreadEvent; using wxEvtHandler::ProcessThreadEvent;
#endif #endif

View File

@@ -1840,6 +1840,19 @@ public:
*/ */
bool ProcessWindowEvent(wxEvent& event); 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. Removes and returns the top-most event handler on the event handler stack.

View File

@@ -99,6 +99,10 @@ BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
EVT_MOUSE_EVENTS(MyCanvas::OnEvent) EVT_MOUSE_EVENTS(MyCanvas::OnEvent)
END_EVENT_TABLE() END_EVENT_TABLE()
BEGIN_EVENT_TABLE(MyChild::EventHandler, wxEvtHandler)
EVT_MENU(MDI_REFRESH, MyChild::EventHandler::OnRefresh)
END_EVENT_TABLE()
// =========================================================================== // ===========================================================================
// implementation // implementation
// =========================================================================== // ===========================================================================
@@ -451,10 +455,16 @@ MyChild::MyChild(wxMDIParentFrame *parent)
// they can be resized at all // they can be resized at all
if ( canBeResized ) if ( canBeResized )
SetSizeHints(100, 100); 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() MyChild::~MyChild()
{ {
PopEventHandler(true);
ms_numChildren--; ms_numChildren--;
} }

View File

@@ -94,6 +94,26 @@ private:
MyCanvas *m_canvas; 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() DECLARE_EVENT_TABLE()
}; };

View File

@@ -686,7 +686,7 @@ bool wxMDIParentFrame::TryBefore(wxEvent& event)
if ( event.GetEventType() == wxEVT_COMMAND_MENU_SELECTED ) if ( event.GetEventType() == wxEVT_COMMAND_MENU_SELECTED )
{ {
wxMDIChildFrame * const child = GetActiveChild(); wxMDIChildFrame * const child = GetActiveChild();
if ( child && child->ProcessEventHere(event) ) if ( child && child->ProcessWindowEventLocally(event) )
return true; return true;
} }