X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/898a466aef28f9a1d8266205f376dd22eaacf855..2728c3bfe7b7c4d4cac4dfb003e1da74727e8113:/include/wx/event.h diff --git a/include/wx/event.h b/include/wx/event.h index cd8b991501..6b0f093f30 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -27,6 +27,10 @@ #include "wx/thread.h" #include "wx/tracker.h" +#if !wxEVENTS_COMPATIBILITY_2_8 + #include "wx/meta/convertible.h" +#endif + // ---------------------------------------------------------------------------- // forward declarations // ---------------------------------------------------------------------------- @@ -69,7 +73,8 @@ typedef int wxEventType; #define wxEVT_ANY ((wxEventType)-1) // this is used to make the event table entry type safe, so that for an event -// handler only a function with proper parameter list can be given. +// handler only a function with proper parameter list can be given. See also +// the wxEVENT_HANDLER_CAST-macro. #define wxStaticCastEvent(type, val) static_cast(val) #define DECLARE_EVENT_TABLE_ENTRY(type, winid, idLast, fn, obj) \ @@ -94,90 +99,95 @@ typedef int wxEventType; // generate a new unique event type extern WXDLLIMPEXP_BASE wxEventType wxNewEventType(); -// macros to create an event type depending on whether type safe events are -// enabled. +// New macros to create templatized event types: #if wxEVENTS_COMPATIBILITY_2_8 + + // Define/Declare a wxEventType-based event type: + #define wxDEFINE_EVENT( name, type ) \ const wxEventType name( wxNewEventType() ); #define wxDECLARE_EXPORTED_EVENT( expdecl, name, type ) \ extern const expdecl wxEventType name; - #define wxDEFINE_EVENT_REFERENCE( name, type, value ) \ - const wxEventType &name( value ); + // Define/Declare a wxEventType-based event type and initialize it with a + // predefined event type. (Only used for wxEVT_SPIN_XXX for backward + // compatibility) + + #define wxDEFINE_EVENT_ALIAS( name, type, value ) \ + const wxEventType name = value; - #define wxDECLARE_EXPORTED_EVENT_REFERENCE( expdecl, name, type ) \ - extern const expdecl wxEventType &name; + #define wxDECLARE_EXPORTED_EVENT_ALIAS( expdecl, name, type ) \ + extern const expdecl wxEventType name; + + // Declare a local (not exported) wxEventType-based event type: #define wxDECLARE_LOCAL_EVENT( name, type ) \ wxDECLARE_EXPORTED_EVENT( wxEMPTY_PARAMETER_VALUE, name, type ) + // Try to cast the given event handler to the correct handler type: + #define wxEVENT_HANDLER_CAST( functype, func ) \ ( wxObjectEventFunction )( wxEventFunction )wxStaticCastEvent( functype, &func ) #else + // Define/Declare a templatized event type with the corresponding event as + // a nested typedef: + #define wxDEFINE_EVENT( name, type ) \ - const wxTypedEventType< type > name( wxNewEventType() ); + const wxEventTypeTag< type > name( wxNewEventType() ); #define wxDECLARE_EXPORTED_EVENT( expdecl, name, type ) \ - extern const expdecl wxTypedEventType< type > name; + extern const expdecl wxEventTypeTag< type > name; + + // Define/Declare a templatized event type and initialize it with a + // predefined event type. (Only used for wxEVT_SPIN_XXX for backward + // compatibility) - #define wxDEFINE_EVENT_REFERENCE( name, type, value ) \ - const wxTypedEventTypeReference< type > name( value ); + #define wxDEFINE_EVENT_ALIAS( name, type, value ) \ + const wxEventTypeTag< type > name( value ); - #define wxDECLARE_EXPORTED_EVENT_REFERENCE( expdecl, name, type ) \ - extern const expdecl wxTypedEventTypeReference< type > name; + #define wxDECLARE_EXPORTED_EVENT_ALIAS( expdecl, name, type ) \ + extern const expdecl wxEventTypeTag< type > name; + + // Declare a local (not exported) templatized event type: #define wxDECLARE_LOCAL_EVENT( name, type ) \ wxDECLARE_EXPORTED_EVENT( wxEMPTY_PARAMETER_VALUE, name, type ) + // Don't cast the given event handler so that wxEvtHandler::Connect() sees + // the actual type: + #define wxEVENT_HANDLER_CAST( functype, func ) \ ( &func ) #endif -// template which associates the correct event object with the event type +// Template which associates the correct event object with the event type #if !wxEVENTS_COMPATIBILITY_2_8 -template -class WXDLLIMPEXP_BASE wxTypedEventType +// The tag is a type associated to the event type (which is an integer itself, +// in spite of its name) value. It exists in order to be used as a template +// parameter and provide a mapping between the event type values and their +// corresponding wxEvent-derived classes. +template +class wxEventTypeTag { public: - typedef Event CorrespondingEvent; + // The class of wxEvent-derived class carried by the events of this type. + typedef T EventClass; - wxTypedEventType(wxEventType type) { m_type = type; } + wxEventTypeTag(wxEventType type) { m_type = type; } - // used for static event tables + // Return a wxEventType reference for the initialization of the static + // event tables. See wxEventTableEntry::m_eventType for a more thorough + // explanation. operator const wxEventType&() const { return m_type; } private: wxEventType m_type; }; -// Due to a bug in older wx versions wxSpinEvents were being sent with type of -// wxEVT_SCROLL_LINEUP, wxEVT_SCROLL_LINEDOWN and wxEVT_SCROLL_THUMBTRACK. But -// with the type-safe events in place, these event types are associated with -// wxScrollEvent. To allow handling of spin events, new event types have been -// defined in spinbutt.h/spinnbuttcmn.cpp. To maintain backward compatibility -// the spin event types are being initialized with the scroll event types. But -// this presents as with the same static initialization order problem we also -// have for the static event tables. So we use the same solution and the -// template definition below holds a reference to a wxEventType. -template -class WXDLLIMPEXP_BASE wxTypedEventTypeReference -{ -public: - typedef Event CorrespondingEvent; - - wxTypedEventTypeReference(const wxEventType& type) : m_type(type) { } - - // used for static event tables - operator const wxEventType&() const { return m_type; } - -private: - const wxEventType &m_type; -}; - #endif // !wxEVENTS_COMPATIBILITY_2_8 // These are needed for the functor definitions @@ -193,25 +203,31 @@ typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&); typedef wxEventFunction wxObjectEventFunction; -// the functors which will be stored in the static/dynamic tables +// The event functor which is stored in the static and dynamic event tables: class WXDLLIMPEXP_BASE wxEventFunctor { public: virtual ~wxEventFunctor(); - // this operator is used to actually invoke the event handler - virtual void operator()(wxEvtHandler *, wxEvent &) = 0; + // Invoke the actual event handler: + virtual void operator()(wxEvtHandler *, wxEvent&) = 0; // this function tests whether this functor is matched, for the purpose of // finding it in an event table in Disconnect(), by the given func virtual bool Matches(const wxEventFunctor& func) const = 0; - virtual wxEvtHandler *GetHandler() const { return NULL; } + // these functions are used for functors comparison in Matches() + virtual void *GetHandler() const { return GetEvtHandler(); } + virtual wxEventFunction GetMethod() const { return NULL; } - virtual wxObjectEventFunction GetMethod() const { return NULL; } + // this one is also used elsewhere in the code and should be overridden to + // return non-NULL if we are indeed associated with an wxEvtHandler + virtual wxEvtHandler *GetEvtHandler() const { return NULL; } }; -// A plain method functor +// A plain method functor: notice that it is used even with the new events as +// it is reused as a specialization of wxEventFunctorMethod for legacy untyped +// event types class WXDLLIMPEXP_BASE wxObjectEventFunctor : public wxEventFunctor { public: @@ -228,27 +244,34 @@ public: (realHandler->*m_method)(event); } - virtual bool Matches(const wxEventFunctor& other) const + virtual bool Matches(const wxEventFunctor& func) const { - wxEvtHandler * const handler = other.GetHandler(); + void * const handler = func.GetHandler(); + if ( handler && GetHandler() != handler ) + return false; - return (m_handler == handler || !handler) && - (m_method == other.GetMethod()); + const wxEventFunction method = GetMethod(); + + // FIXME-VC6: amazing but true: replacing "method == NULL" here with + // "!method" makes VC6 crash with an ICE in DLL build (only!) + return method == NULL || GetMethod() == method; } - virtual wxEvtHandler *GetHandler() const { return m_handler; } - virtual wxObjectEventFunction GetMethod() const { return m_method; } + virtual wxEvtHandler *GetEvtHandler() const { return m_handler; } + virtual wxEventFunction GetMethod() const { return m_method; } private: wxEvtHandler *m_handler; - wxObjectEventFunction m_method; + wxEventFunction m_method; }; +#if wxEVENTS_COMPATIBILITY_2_8 + // Create a functor for the legacy events: handler can be NULL and its default // value is used by the event table macros inline wxObjectEventFunctor * -wxNewEventFunctor(wxEventType WXUNUSED(evtType), +wxNewEventFunctor(const wxEventType& WXUNUSED(evtType), wxObjectEventFunction method, wxEvtHandler *handler = NULL) { @@ -256,224 +279,234 @@ wxNewEventFunctor(wxEventType WXUNUSED(evtType), } inline wxObjectEventFunctor -wxConstructEventFunctor(wxEventType WXUNUSED(evtType), +wxMakeEventFunctor(const wxEventType& WXUNUSED(evtType), wxObjectEventFunction method, wxEvtHandler *handler) { return wxObjectEventFunctor(method, handler); } -#if !wxEVENTS_COMPATIBILITY_2_8 +#else // !wxEVENTS_COMPATIBILITY_2_8 -template -class WXDLLIMPEXP_BASE wxEventFunctorFunction : public wxEventFunctor +// functor forwarding the event to anything callable (function, static method, +// generalized functor...) +template +class wxEventFunctorFunction : public wxEventFunctor { public: - wxEventFunctorFunction(void (*handler)(typename EventType::CorrespondingEvent &)) + typedef typename EventTag::EventClass EventArg; + + wxEventFunctorFunction(Functor handler) { m_handler = handler; } virtual void operator()(wxEvtHandler *WXUNUSED(handler), wxEvent& event) { - // Protect against wrong event i.e. wxMouseEvent evt(wxEVT_PAINT): - wxASSERT( dynamic_cast< typename EventType::CorrespondingEvent * >( &event ) != NULL ); - - // Will throw a std::bad_cast exception in release build: - ( *m_handler )( dynamic_cast< typename EventType::CorrespondingEvent & >( event )); + m_handler(static_cast(event)); } - virtual bool Matches( const wxEventFunctor &right ) const + virtual bool Matches(const wxEventFunctor& WXUNUSED(func)) const { - wxEventFunctorFunction const &other = dynamic_cast< wxEventFunctorFunction const & >( right ); - - return m_handler == other.m_handler || other.m_handler == NULL; + // we have no way to compare arbitrary functors so just consider them + // to be equal: this means that disconnecting a functor will always + // find the last functor connected which in turn implies that it's + // probably a bad idea to connect more than one functor if you plan to + // disconnect them but this limitation doesn't seem very important in + // practice + return true; } private: - void ( *m_handler )( typename EventType::CorrespondingEvent & ); + Functor m_handler; }; +// helper class defining operations different for method functors using an +// object of wxEvtHandler-derived class as handler and the others +namespace wxPrivate +{ -template -class WXDLLIMPEXP_BASE wxEventFunctorMethod : public wxEventFunctor +template struct HandlerImpl; + +// specialization for handlers deriving from wxEvtHandler +template +struct HandlerImpl +{ + static bool IsEvtHandler() + { return true; } + static T *ConvertFromEvtHandler(wxEvtHandler *p) + { return static_cast(p); } + static wxEvtHandler *ConvertToEvtHandler(T *p) + { return p; } + static wxEventFunction ConvertToEvtFunction(void (T::*f)(A&)) + { return reinterpret_cast(f); } +}; + +// specialization for handlers not deriving from wxEvtHandler +template +struct HandlerImpl +{ + static bool IsEvtHandler() + { return false; } + static T *ConvertFromEvtHandler(wxEvtHandler *) + { return NULL; } + static wxEvtHandler *ConvertToEvtHandler(T *) + { return NULL; } + static wxEventFunction ConvertToEvtFunction(void (T::*)(A&)) + { return NULL; } +}; + +} // namespace wxPrivate + +// functor forwarding the event to a method of the given object +// +// notice that the object class may be different from the class in which the +// method is defined but it must be convertible to this class +template +class wxEventFunctorMethod + : public wxEventFunctor, + private wxPrivate::HandlerImpl + < + Class, + typename EventTag::EventClass, + wxConvertibleTo::value + > { public: - wxEventFunctorMethod( void ( Class::*method )( typename EventType::CorrespondingEvent & ), - Derived *handler ) + typedef typename EventTag::EventClass EventArg; + + wxEventFunctorMethod(void (Class::*method)(EventArg&), ObjClass *handler) { + wxASSERT_MSG( handler || this->IsEvtHandler(), + "handlers defined in non-wxEvtHandler-derived classes " + "must be connected with a valid sink object" ); + m_handler = handler; m_method = method; } - virtual void operator () ( wxEvtHandler *handler, wxEvent &event ) + virtual void operator()(wxEvtHandler *handler, wxEvent& event) { - // Compile-time type check 1: This requires Derived to derive from or - // be of the same type as Class - Class *realHandler = m_handler; - - if( m_handler == NULL ) + Class * realHandler = m_handler; + if ( !realHandler ) { - // Verify that the handler does indeed derive from the class - // containing the handler method - wxASSERT( dynamic_cast< Class * >( handler) != NULL ); + realHandler = this->ConvertFromEvtHandler(handler); - realHandler = dynamic_cast< Class * >( handler ); + // this is not supposed to happen but check for it nevertheless + wxCHECK_RET( realHandler, "invalid event handler" ); } - // Protect against wrong event i.e. wxMouseEvent evt(wxEVT_PAINT): - wxASSERT( dynamic_cast< typename EventType::CorrespondingEvent * >( &event ) != NULL ); - - // Will throw a std::bad_cast exception in release build: - ( realHandler->*m_method )( dynamic_cast< typename EventType::CorrespondingEvent & >( event )); + (realHandler->*m_method)(static_cast(event)); } - virtual bool Matches( const wxEventFunctor &right ) const + virtual bool Matches(const wxEventFunctor& func) const { - wxEventFunctorMethod const &other = dynamic_cast< wxEventFunctorMethod const & >( right ); + void * const handler = func.GetHandler(); + if ( handler && GetHandler() != handler ) + return false; - return (( m_handler == other.m_handler || other.m_handler == NULL ) && - ( m_method == other.m_method || other.m_method == NULL )); + const wxEventFunction method = GetMethod(); + return !method || GetMethod() == method; } - virtual wxEvtHandler *GetHandler() const + virtual void *GetHandler() const { - // This makes sure Derived derives from wxEvtHandler (it is still - // possible and even ok if Class does not derive from wxEvtHandler. In - // this case Derived would end up using multiple inheritance: class - // Derived : public wxEvtHandler, public Class { } where Class contains - // the method to call, but wxEvtHandler contains the wxTrackable and - // code for weak ref support return m_handler; } - virtual wxObjectEventFunction GetMethod() const + virtual wxEventFunction GetMethod() const + { + return this->ConvertToEvtFunction(m_method); + } + + virtual wxEvtHandler *GetEvtHandler() const { - return reinterpret_cast(m_method); + return this->ConvertToEvtHandler(m_handler); } private: - Derived *m_handler; - void (Class::*m_method)(typename EventType::CorrespondingEvent&); + ObjClass *m_handler; + void (Class::*m_method)(EventArg&); }; - -template -class WXDLLIMPEXP_BASE wxEventFunctorAdapter : public wxEventFunctor +// partial specialization for legacy event types +template +class wxEventFunctorMethod + : public wxObjectEventFunctor { public: - wxEventFunctorAdapter( Functor &functor ) + wxEventFunctorMethod(wxObjectEventFunction method, ObjClass *handler) + : wxObjectEventFunctor(method, handler) { - m_functor = functor; - } - - virtual void operator () ( wxEvtHandler *WXUNUSED( handler ), wxEvent &event ) - { - // Protect against wrong event i.e. wxMouseEvent evt(wxEVT_PAINT): - wxASSERT( dynamic_cast< typename EventType::CorrespondingEvent * >( &event ) != NULL ); - - // Will throw a std::bad_cast exception in release build: - m_functor( dynamic_cast< typename EventType::CorrespondingEvent & >( event )); } - - virtual bool Matches( const wxEventFunctor &right ) const - { - wxEventFunctorAdapter const &other = dynamic_cast< wxEventFunctorAdapter const & >( right ); - - return m_functor == other.m_functor; - } - -private: - Functor m_functor; }; -// -// Create functors for the templatized events (needed in wxEvtHandler::Connect): -// - -// Create a functor for functions: - -template -inline wxEventFunctorFunction * -wxNewEventFunctor(const EventType &, - void (*function)(typename EventType::CorrespondingEvent&)) -{ - return new wxEventFunctorFunction(function); -} -// Create a functor for methods: +// +// Create functors for the templatized events, either allocated on the heap for +// wxNewXXX() variants (this is needed in wxEvtHandler::Connect() to store them +// in dynamic event table) or just by returning them as temporary objects (this +// is enough for Disconnect() and we allocate unnecessary heap allocation like +// this) -template -inline wxEventFunctorMethod * -wxNewEventFunctor(const EventType &, - void (Class::*method)(typename EventType::CorrespondingEvent&)) -{ - return new wxEventFunctorMethod(method, NULL); -} -template -inline wxEventFunctorMethod * -wxNewEventFunctor(const EventType &, - void (Class::*method)(typename EventType::CorrespondingEvent &), - Derived *handler ) +// Create functors wrapping other functors (including functions): +template +inline wxEventFunctorFunction * +wxNewEventFunctor(const EventTag&, Functor func) { - return new wxEventFunctorMethod(method, handler); + return new wxEventFunctorFunction(func); } -// Create a functor for arbitrary functors (like boost::function): -template -inline wxEventFunctorAdapter * -wxNewEventFunctor(const EventType &, - Functor& functor ) +template +inline wxEventFunctorFunction +wxMakeEventFunctor(const EventTag&, Functor func) { - return new wxEventFunctorAdapter(functor); + return wxEventFunctorFunction(func); } -// -// Construct functors for the templatized events (needed in wxEvtHandler::Disconnect): -// - -// Construct a functor for functions: -template -inline wxEventFunctorFunction -wxConstructEventFunctor(const EventType &, - void (*function)(typename EventType::CorrespondingEvent&)) +// Create functors for methods: +template + +inline wxEventFunctorMethod * +wxNewEventFunctor(const EventTag&, + void (Class::*method)(EventArg&), + ObjClass *handler) { - return wxEventFunctorFunction(function); + return new wxEventFunctorMethod(method, handler); } -// Construct a functor for methods: - -template -inline wxEventFunctorMethod -wxConstructEventFunctor(const EventType &, - void (Class::*method)(typename EventType::CorrespondingEvent&)) +template + +inline wxEventFunctorMethod +wxMakeEventFunctor(const EventTag&, + void (Class::*method)(EventArg&), + ObjClass *handler) { - return wxEventFunctorMethod(method, NULL); + return wxEventFunctorMethod(method, handler); } -template -inline wxEventFunctorMethod -wxConstructEventFunctor(const EventType &, - void (Class::*method)(typename EventType::CorrespondingEvent&), - Derived *handler) +// Special case for the wxNewEventFunctor() calls used inside the event table +// macros: they don't specify the handler so ObjClass can't be deduced +template +inline wxEventFunctorMethod * +wxNewEventFunctor(const EventTag&, void (Class::*method)(EventArg&)) { - return wxEventFunctorMethod(method, handler); + return new wxEventFunctorMethod(method, NULL); } -// Construct a functor for arbitrary functors (like boost:function): - -template -inline wxEventFunctorAdapter -wxConstructEventFunctor(const EventType &, - Functor& functor) +template + +inline wxEventFunctorMethod +wxMakeEventFunctor(const EventTag&, void (Class::*method)(EventArg&)) { - return wxEventFunctorAdapter(functor); + return wxEventFunctorMethod(method, NULL); } #endif // !wxEVENTS_COMPATIBILITY_2_8 + // many, but not all, standard event types // some generic events @@ -490,6 +523,7 @@ class WXDLLIMPEXP_FWD_CORE wxKeyEvent; class WXDLLIMPEXP_FWD_CORE wxNavigationKeyEvent; class WXDLLIMPEXP_FWD_CORE wxSetCursorEvent; class WXDLLIMPEXP_FWD_CORE wxScrollEvent; +class WXDLLIMPEXP_FWD_CORE wxSpinEvent; class WXDLLIMPEXP_FWD_CORE wxScrollWinEvent; class WXDLLIMPEXP_FWD_CORE wxSizeEvent; class WXDLLIMPEXP_FWD_CORE wxMoveEvent; @@ -587,6 +621,21 @@ wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_SCROLL_THUMBTRACK, wxScrollEven wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_SCROLL_THUMBRELEASE, wxScrollEvent) wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_SCROLL_CHANGED, wxScrollEvent) +// Due to a bug in older wx versions, wxSpinEvents were being sent with type of +// wxEVT_SCROLL_LINEUP, wxEVT_SCROLL_LINEDOWN and wxEVT_SCROLL_THUMBTRACK. But +// with the type-safe events in place, these event types are associated with +// wxScrollEvent. To allow handling of spin events, new event types have been +// defined in spinbutt.h/spinnbuttcmn.cpp. To maintain backward compatibility +// the spin event types are being initialized with the scroll event types. + +#if wxUSE_SPINBTN + +wxDECLARE_EXPORTED_EVENT_ALIAS( WXDLLIMPEXP_CORE, wxEVT_SPIN_UP, wxSpinEvent ) +wxDECLARE_EXPORTED_EVENT_ALIAS( WXDLLIMPEXP_CORE, wxEVT_SPIN_DOWN, wxSpinEvent ) +wxDECLARE_EXPORTED_EVENT_ALIAS( WXDLLIMPEXP_CORE, wxEVT_SPIN, wxSpinEvent ) + +#endif + // Scroll events from wxWindow wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_SCROLLWIN_TOP, wxScrollWinEvent) wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_SCROLLWIN_BOTTOM, wxScrollWinEvent) @@ -713,7 +762,7 @@ public: void Skip(bool skip = true) { m_skipped = skip; } bool GetSkipped() const { return m_skipped; } - // this function is used to create a copy of the event polymorphically and + // This function is used to create a copy of the event polymorphically and // all derived classes must implement it because otherwise wxPostEvent() // for them wouldn't work (it needs to do a copy of the event) virtual wxEvent *Clone() const = 0; @@ -742,6 +791,20 @@ public: m_propagationLevel = propagationLevel; } + + // This is for internal use only and is only called by + // wxEvtHandler::ProcessEvent() to check whether it's the first time this + // event is being processed + bool WasProcessed() + { + if ( m_wasProcessed ) + return true; + + m_wasProcessed = true; + + return false; + } + protected: wxObject* m_eventObject; wxEventType m_eventType; @@ -763,6 +826,12 @@ protected: bool m_skipped; bool m_isCommandEvent; + // initially false but becomes true as soon as WasProcessed() is called for + // the first time, as this is done only by ProcessEvent() it explains the + // variable name: it becomes true after ProcessEvent() was called at least + // once for this event + bool m_wasProcessed; + protected: wxEvent(const wxEvent&); // for implementing Clone() wxEvent& operator=(const wxEvent&); // for derived classes operator=() @@ -979,7 +1048,7 @@ class WXDLLIMPEXP_CORE wxScrollWinEvent : public wxEvent public: wxScrollWinEvent(wxEventType commandType = wxEVT_NULL, int pos = 0, int orient = 0); - wxScrollWinEvent(const wxScrollWinEvent & event) : wxEvent(event) + wxScrollWinEvent(const wxScrollWinEvent& event) : wxEvent(event) { m_commandInt = event.m_commandInt; m_extraLong = event.m_extraLong; } @@ -1223,7 +1292,7 @@ public: m_x(x), m_y(y), m_cursor() { } - wxSetCursorEvent(const wxSetCursorEvent & event) + wxSetCursorEvent(const wxSetCursorEvent& event) : wxEvent(event), m_x(event.m_x), m_y(event.m_y), @@ -1366,7 +1435,7 @@ public: : wxEvent(winid, wxEVT_SIZE), m_size(sz) { } - wxSizeEvent(const wxSizeEvent & event) + wxSizeEvent(const wxSizeEvent& event) : wxEvent(event), m_size(event.m_size), m_rect(event.m_rect) { } @@ -1621,7 +1690,7 @@ public: wxMenuEvent(wxEventType type = wxEVT_NULL, int winid = 0, wxMenu* menu = NULL) : wxEvent(winid, type) { m_menuId = winid; m_menu = menu; } - wxMenuEvent(const wxMenuEvent & event) + wxMenuEvent(const wxMenuEvent& event) : wxEvent(event) { m_menuId = event.m_menuId; m_menu = event.m_menu; } @@ -1659,7 +1728,7 @@ public: m_veto(false), // should be false by default m_canVeto(true) {} - wxCloseEvent(const wxCloseEvent & event) + wxCloseEvent(const wxCloseEvent& event) : wxEvent(event), m_loggingOff(event.m_loggingOff), m_veto(event.m_veto), @@ -1709,7 +1778,7 @@ public: wxShowEvent(int winid = 0, bool show = false) : wxEvent(winid, wxEVT_SHOW) { m_show = show; } - wxShowEvent(const wxShowEvent & event) + wxShowEvent(const wxShowEvent& event) : wxEvent(event) { m_show = event.m_show; } @@ -1741,7 +1810,7 @@ public: wxIconizeEvent(int winid = 0, bool iconized = true) : wxEvent(winid, wxEVT_ICONIZE) { m_iconized = iconized; } - wxIconizeEvent(const wxIconizeEvent & event) + wxIconizeEvent(const wxIconizeEvent& event) : wxEvent(event) { m_iconized = event.m_iconized; } @@ -1823,7 +1892,7 @@ public: m_joyStick(joystick) { } - wxJoystickEvent(const wxJoystickEvent & event) + wxJoystickEvent(const wxJoystickEvent& event) : wxEvent(event), m_pos(event.m_pos), m_zPosition(event.m_zPosition), @@ -1958,7 +2027,7 @@ public: m_setText = m_setChecked = false; } - wxUpdateUIEvent(const wxUpdateUIEvent & event) + wxUpdateUIEvent(const wxUpdateUIEvent& event) : wxCommandEvent(event), m_checked(event.m_checked), m_enabled(event.m_enabled), @@ -2154,7 +2223,7 @@ public: : wxEvent(winid, wxEVT_QUERY_NEW_PALETTE), m_paletteRealized(false) { } - wxQueryNewPaletteEvent(const wxQueryNewPaletteEvent & event) + wxQueryNewPaletteEvent(const wxQueryNewPaletteEvent& event) : wxEvent(event), m_paletteRealized(event.m_paletteRealized) { } @@ -2300,7 +2369,7 @@ public: m_pos(pt), m_origin(GuessOrigin(origin)) { } - wxHelpEvent(const wxHelpEvent & event) + wxHelpEvent(const wxHelpEvent& event) : wxCommandEvent(event), m_pos(event.m_pos), m_target(event.m_target), @@ -2358,7 +2427,7 @@ public: wxWindowID winid = 0) : wxCommandEvent(type, winid) { } - wxClipboardTextEvent(const wxClipboardTextEvent & event) + wxClipboardTextEvent(const wxClipboardTextEvent& event) : wxCommandEvent(event) { } @@ -2385,7 +2454,7 @@ public: : wxCommandEvent(type, winid), m_pos(pt) { } - wxContextMenuEvent(const wxContextMenuEvent & event) + wxContextMenuEvent(const wxContextMenuEvent& event) : wxCommandEvent(event), m_pos(event.m_pos) { } @@ -2431,7 +2500,7 @@ public: : wxEvent(0, wxEVT_IDLE), m_requestMore(false) { } - wxIdleEvent(const wxIdleEvent & event) + wxIdleEvent(const wxIdleEvent& event) : wxEvent(event), m_requestMore(event.m_requestMore) { } @@ -2497,7 +2566,7 @@ struct WXDLLIMPEXP_BASE wxEventTableEntryBase // being initialized (a temporary instance is created and then this // constructor is called). - const_cast< wxEventTableEntryBase & >( entry ).m_fn = NULL; + const_cast( entry ).m_fn = NULL; } ~wxEventTableEntryBase() @@ -2517,7 +2586,7 @@ struct WXDLLIMPEXP_BASE wxEventTableEntryBase wxObject* m_callbackUserData; private: - wxEventTableEntryBase &operator = ( const wxEventTableEntryBase & ); + DECLARE_NO_ASSIGN_CLASS(wxEventTableEntryBase) }; // an entry from a static event table @@ -2538,7 +2607,7 @@ struct WXDLLIMPEXP_BASE wxEventTableEntry : public wxEventTableEntryBase const int& m_eventType; private: - wxEventTableEntry &operator = ( const wxEventTableEntry & ); + DECLARE_NO_ASSIGN_CLASS(wxEventTableEntry) }; // an entry used in dynamic event table managed by wxEvtHandler::Connect() @@ -2556,7 +2625,7 @@ struct WXDLLIMPEXP_BASE wxDynamicEventTableEntry : public wxEventTableEntryBase int m_eventType; private: - wxDynamicEventTableEntry &operator = ( const wxDynamicEventTableEntry & ); + DECLARE_NO_ASSIGN_CLASS(wxDynamicEventTableEntry) }; // ---------------------------------------------------------------------------- @@ -2597,7 +2666,7 @@ public: // Handle the given event, in other words search the event table hash // and call self->ProcessEvent() if a match was found. - bool HandleEvent(wxEvent &event, wxEvtHandler *self); + bool HandleEvent(wxEvent& event, wxEvtHandler *self); // Clear table void Clear(); @@ -2643,14 +2712,27 @@ public: wxEvtHandler(); virtual ~wxEvtHandler(); + + // Event handler chain + // ------------------- + wxEvtHandler *GetNextHandler() const { return m_nextHandler; } wxEvtHandler *GetPreviousHandler() const { return m_previousHandler; } - void SetNextHandler(wxEvtHandler *handler) { m_nextHandler = handler; } - void SetPreviousHandler(wxEvtHandler *handler) { m_previousHandler = handler; } + virtual void SetNextHandler(wxEvtHandler *handler) { m_nextHandler = handler; } + virtual void SetPreviousHandler(wxEvtHandler *handler) { m_previousHandler = handler; } void SetEvtHandlerEnabled(bool enabled) { m_enabled = enabled; } bool GetEvtHandlerEnabled() const { return m_enabled; } + void Unlink(); + bool IsUnlinked() const; + + + + // Event queuing and processing + // ---------------------------- + + // Process an event right now: this can only be called from the main // thread, use QueueEvent() for scheduling the events for // processing from other threads. @@ -2661,6 +2743,7 @@ public: // when called from C code (e.g. in GTK+ callback) when the exception // wouldn't correctly propagate to wxEventLoop. bool SafelyProcessEvent(wxEvent& event); + // NOTE: uses ProcessEvent() // Schedule the given event to be processed later. It takes ownership of // the event pointer, i.e. it will be deleted later. This is safe to call @@ -2683,11 +2766,26 @@ public: } void ProcessPendingEvents(); + // NOTE: uses ProcessEvent() #if wxUSE_THREADS bool ProcessThreadEvent(const wxEvent& event); + // NOTE: uses AddPendingEvent() #endif + + // Connecting and disconnecting + // ---------------------------- + + // These functions are used for old, untyped, event handlers and don't + // check that the type of the function passed to them actually matches the + // type of the event. They also only allow connecting events to methods of + // wxEvtHandler-derived classes. + // + // The template Connect() methods below are safer and allow connecting + // events to arbitrary functions or functors -- but require compiler + // support for templates. + // Dynamic association of a member function handler with the event handler, // winid and event type void Connect(int winid, @@ -2697,9 +2795,9 @@ public: wxObject *userData = NULL, wxEvtHandler *eventSink = NULL) { - wxObjectEventFunctor *functor = wxNewEventFunctor( eventType, func, eventSink ); - - Subscribe( winid, lastId, eventType, functor, userData ); + DoConnect(winid, lastId, eventType, + wxNewEventFunctor(eventType, func, eventSink), + userData); } // Convenience function: take just one id @@ -2724,9 +2822,9 @@ public: wxObject *userData = NULL, wxEvtHandler *eventSink = NULL) { - wxObjectEventFunctor functor = wxConstructEventFunctor( eventType, func, eventSink ); - - return Unsubscribe( winid, lastId, eventType, functor, userData ); + return DoDisconnect(winid, lastId, eventType, + wxMakeEventFunctor(eventType, func, eventSink), + userData ); } bool Disconnect(int winid = wxID_ANY, @@ -2742,306 +2840,257 @@ public: wxEvtHandler *eventSink = NULL) { return Disconnect(wxID_ANY, eventType, func, userData, eventSink); } - #if !wxEVENTS_COMPATIBILITY_2_8 - // - // Connect a function to an event: - // - template + // Event handling in functions (including generalized functors): + + template void Connect(int winid, int lastId, - const EventType &eventType, - void (*func)(typename EventType::CorrespondingEvent&), - wxObject* userData = NULL) + const EventTag& eventType, + Functor func) { - wxEventFunctorFunction< EventType > *functor = wxNewEventFunctor( eventType, func ); - - Subscribe( winid, lastId, eventType, functor, userData ); + DoConnect(winid, lastId, eventType, + wxNewEventFunctor(eventType, func)); } - template - void Connect( int winid, - const EventType &eventType, - void ( *func )( typename EventType::CorrespondingEvent & ), - wxObject* userData = NULL ) - { Connect( winid, wxID_ANY, eventType, func, userData ); } + template + void Connect(int winid, const EventTag& eventType, Functor func) + { Connect(winid, wxID_ANY, eventType, func); } - template - void Connect( const EventType &eventType, - void ( *func )( typename EventType::CorrespondingEvent & ), - wxObject* userData = NULL ) - { Connect( wxID_ANY, wxID_ANY, eventType, func, userData ); } + template + void Connect(const EventTag& eventType, Functor func) + { Connect(wxID_ANY, eventType, func); } - // - // Connect a method to an event: - // - template - void Connect( int winid, - int lastId, - const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL ) - { - wxEventFunctorMethod< EventType, Class, Class > *functor = - wxNewEventFunctor( eventType, func, static_cast< Class * const >( this )); + template + bool Disconnect(int winid, + int lastId, + const EventTag& eventType, + Functor func) + { + return DoDisconnect(winid, lastId, eventType, + wxMakeEventFunctor(eventType, func)); + } - Subscribe( winid, lastId, eventType, functor, userData ); - } + template + bool Disconnect(int winid, const EventTag& eventType, Functor func) + { return Disconnect(winid, wxID_ANY, eventType, func); } - template - void Connect( int winid, - const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL ) - { Connect( winid, wxID_ANY, eventType, func, userData ); } - - template - void Connect( const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL ) - { Connect( wxID_ANY, wxID_ANY, eventType, func, userData ); } - - template - void Connect( int winid, - int lastId, - const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL, - Derived *eventSink = NULL ) - { - wxEventFunctorMethod< EventType, Class, Derived > *functor = - wxNewEventFunctor( eventType, func, eventSink ); + template + bool Disconnect(const EventTag& eventType, Functor func) + { return Disconnect(wxID_ANY, eventType, func); } - Subscribe( winid, lastId, eventType, functor, userData ); - } - template - void Connect( int winid, - const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL, - Derived *eventSink = NULL ) - { Connect( winid, wxID_ANY, eventType, func, userData, eventSink ); } - - template - void Connect( const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL, - Derived *eventSink = NULL ) - { Connect( wxID_ANY, wxID_ANY, eventType, func, userData, eventSink ); } - - template - static void Connect( Sender *sender, - int winid, - int lastId, - const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL, - Derived *eventSink = NULL ) - { - wxEventFunctorMethod< EventType, Class, Derived > *functor = - wxNewEventFunctor( eventType, func, eventSink ); - sender->Subscribe( winid, lastId, eventType, functor, userData ); + // Event handling in class methods: the object handling the event (i.e. + // this object itself by default or eventSink if specified) must be + // convertible to this class. + // + // Notice that we need to have separate overloads for the versions with and + // without eventSink because in the latter case we must check that this + // object itself derives from Class while in the former this is not + // necessarily true + + // Methods connecting/disconnecting event to this object itself + + template + void Connect(int winid, + int lastId, + const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData = NULL) + { + DoConnect(winid, lastId, eventType, + wxNewEventFunctor(eventType, func, static_cast(this)), + userData); } - template - static void Connect( Sender *sender, - int winid, - const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL, - Derived *eventSink = NULL ) - { Connect( sender, winid, wxID_ANY, eventType, func, userData, eventSink ); } - - template - static void Connect( Sender *sender, - const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL, - Derived *eventSink = NULL ) - { Connect( sender, wxID_ANY, wxID_ANY, eventType, func, userData, eventSink ); } + template + void Connect(int winid, + const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData = NULL) + { Connect(winid, wxID_ANY, eventType, func, userData); } - // - // Connect an arbitrary functor to an event: - // + template + void Connect(const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData = NULL) + { Connect(wxID_ANY, eventType, func, userData); } - template - void Connect( int winid, - int lastId, - const EventType &eventType, - Functor &functor, - wxObject* userData = NULL) - { - wxEventFunctorAdapter< EventType, Functor > *adapter = - wxNewEventFunctor( eventType, functor ); - Subscribe( winid, lastId, eventType, adapter, userData ); + template + bool Disconnect(int winid, + int lastId, + const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData = NULL) + { + return DoDisconnect(winid, lastId, eventType, + wxMakeEventFunctor(eventType, func, + static_cast(this)), + userData); } - template - void Connect( int winid, - const EventType &eventType, - Functor &functor, - wxObject* userData = NULL) - { Connect( winid, wxID_ANY, eventType, functor, userData ); } - - template - void Connect( const EventType &eventType, - Functor &functor, - wxObject* userData = NULL) - { Connect( wxID_ANY, wxID_ANY, eventType, functor, userData ); } - // - // Disconnect a function from an event: - // + template + bool Disconnect(int winid, + const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData = NULL) + { return Disconnect(winid, wxID_ANY, eventType, func, userData); } + + template + bool Disconnect(const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData = NULL) + { return Disconnect(wxID_ANY, eventType, func, userData); } - template - bool Disconnect( int winid, - int lastId, - const EventType &eventType, - void ( *func )( typename EventType::CorrespondingEvent & ), - wxObject* userData = NULL ) - { - wxEventFunctorFunction< EventType > functor = wxConstructEventFunctor( eventType, func ); - return Unsubscribe( winid, lastId, eventType, functor, userData ); + // Methods connecting/disconnecting event to another object + + template + + void Connect(int winid, + int lastId, + const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData, + ObjClass *eventSink) + { + DoConnect(winid, lastId, eventType, + wxNewEventFunctor(eventType, func, eventSink), + userData); } - template - bool Disconnect( int winid, - const EventType &eventType, - void ( *func )( typename EventType::CorrespondingEvent & ), - wxObject* userData = NULL ) - { return Disconnect( winid, wxID_ANY, eventType, func, userData ); } + template + + void Connect(int winid, + const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData, + ObjClass *eventSink) + { Connect(winid, wxID_ANY, eventType, func, userData, eventSink); } - template - bool Disconnect( const EventType &eventType, - void ( *func )( typename EventType::CorrespondingEvent & ), - wxObject* userData = NULL ) - { return Disconnect( wxID_ANY, wxID_ANY, eventType, func, userData ); } + template + + void Connect(const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData, + ObjClass *eventSink) + { Connect(wxID_ANY, eventType, func, userData, eventSink); } - // - // Disconnect a method from an event: - // - template - bool Disconnect( int winid, - int lastId, - const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL ) - { - wxEventFunctorMethod< EventType, Class, Class > functor = - wxConstructEventFunctor( eventType, func, static_cast< Class * const >( this )); + template + + bool Disconnect(int winid, + int lastId, + const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData, + ObjClass *eventSink) + { + return DoDisconnect(winid, lastId, eventType, + wxMakeEventFunctor(eventType, func, eventSink), + userData); + } - return Unsubscribe( winid, lastId, eventType, functor, userData ); - } + template + + bool Disconnect(int winid, + const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData, + ObjClass *eventSink) + { return Disconnect(winid, wxID_ANY, eventType, func, + userData, eventSink); } + + template + + bool Disconnect(const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData, + ObjClass *eventSink) + { return Disconnect(wxID_ANY, eventType, func, userData, eventSink); } - template - bool Disconnect( int winid, - const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL ) - { return Disconnect( winid, wxID_ANY, eventType, func, userData ); } - - template - bool Disconnect( const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL ) - { return Disconnect( wxID_ANY, wxID_ANY, eventType, func, userData ); } - - template - bool Disconnect( int winid, - int lastId, - const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL, - Derived *eventSink = NULL ) - { - wxEventFunctorMethod< EventType, Class, Derived > functor = - wxConstructEventFunctor( eventType, func, eventSink ); - return Unsubscribe( winid, lastId, eventType, functor, userData ); - } - template - bool Disconnect( int winid, - const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL, - Derived *eventSink = NULL ) - { return Disconnect( winid, wxID_ANY, eventType, func, userData, eventSink ); } - - template - bool Disconnect( const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL, - Derived *eventSink = NULL ) - { return Disconnect( wxID_ANY, wxID_ANY, eventType, func, userData, eventSink ); } - - template - static bool Disconnect( Sender *sender, - int winid, - int lastId, - const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL, - Derived *eventSink = NULL ) + // Static version of Connect() which allows to specify the event source and + // event handler in a more symmetric way + template + static void Connect(ObjSource *eventSrc, + int winid, + int lastId, + const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData = NULL, + ObjClass *eventSink = NULL) { - wxEventFunctorMethod< EventType, Class, Derived > functor = - wxConstructEventFunctor( eventType, func, eventSink ); + eventSrc->Connect(winid, lastId, eventType, func, userData, eventSink); + } - return sender->Unsubscribe( winid, lastId, eventType, functor, userData ); + template + static void Connect(ObjSource *eventSrc, + int winid, + const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData = NULL, + ObjClass *eventSink = NULL) + { + Connect(eventSrc, winid, wxID_ANY, eventType, func, userData, eventSink); } - template - static bool Disconnect( Sender *sender, - int winid, - const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL, - Derived *eventSink = NULL ) - { return Disconnect( sender, winid, wxID_ANY, eventType, func, userData, eventSink ); } - - template - static bool Disconnect( Sender *sender, - const EventType &eventType, - void ( Class::*func )( typename EventType::CorrespondingEvent & ), - wxObject *userData = NULL, - Derived *eventSink = NULL ) - { return Disconnect( sender, wxID_ANY, wxID_ANY, eventType, func, userData, eventSink ); } + template + static void Connect(ObjSource *eventSrc, + const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData = NULL, + ObjClass *eventSink = NULL) + { + Connect(eventSrc, wxID_ANY, eventType, func, userData, eventSink); + } - // - // Disconnect an arbitrary functor from an event: - // - template - bool Disconnect( int winid, - int lastId, - const EventType &eventType, - Functor &functor, - wxObject* userData = NULL) + template + static bool Disconnect(ObjSource *eventSrc, + int winid, + int lastId, + const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData = NULL, + ObjClass *eventSink = NULL) { - wxEventFunctorAdapter< EventType, Functor > adapter = - wxConstructEventFunctor( eventType, functor ); - - return Unsubscribe( winid, lastId, eventType, adapter, userData ); + return eventSrc->Disconnect(winid, lastId, eventType, func, + userData, eventSink); } - template - bool Disconnect( int winid, - const EventType &eventType, - Functor &functor, - wxObject* userData = NULL) - { return Disconnect( winid, wxID_ANY, eventType, functor, userData ); } - - template - bool Disconnect( const EventType &eventType, - Functor &functor, - wxObject* userData = NULL) - { return Disconnect( wxID_ANY, wxID_ANY, eventType, functor, userData ); } + template + static bool Disconnect(ObjSource *eventSrc, + int winid, + const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData = NULL, + ObjClass *eventSink = NULL) + { + return Disconnect(eventSrc, winid, wxID_ANY, eventType, func, + userData, eventSink); + } + template + static bool Disconnect(ObjSource *eventSrc, + const EventTag& eventType, + void (Class::*func)(EventArg&), + wxObject *userData = NULL, + ObjClass *eventSink = NULL) + { + return Disconnect(eventSrc, wxID_ANY, eventType, func, + userData, eventSink); + } #endif // !wxEVENTS_COMPATIBILITY_2_8 @@ -3076,12 +3125,7 @@ public: void OnSinkDestroyed( wxEvtHandler *sink ); - // The method processing the event in this event handler (or rather in this - // event handler chain as it also tries the next handler and so on), i.e. - // it returns true if we processed this event or false if we didn't but - // does not call TryParent() in the latter case. It also doesn't call - // wxApp::FilterEvent() before processing it, this is supposed to be done - // by the public ProcessEvent() only once for every event we handle. + // The method tries to process the event in this event handler. // // It is meant to be called from ProcessEvent() only and is not virtual, // additional event handlers can be hooked into the normal event processing @@ -3090,17 +3134,17 @@ public: private: - void Subscribe(int winid, + void DoConnect(int winid, int lastId, wxEventType eventType, wxEventFunctor *func, - wxObject* userData); + wxObject* userData = NULL); - bool Unsubscribe(int winid, - int lastId, - wxEventType eventType, - const wxEventFunctor &func, - wxObject *userData); + bool DoDisconnect(int winid, + int lastId, + wxEventType eventType, + const wxEventFunctor& func, + wxObject *userData = NULL); static const wxEventTableEntry sm_eventTableEntries[];