]> git.saurik.com Git - wxWidgets.git/commitdiff
Changes to template Connect() to make it compile with MSVC7 and possible other
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 2 Feb 2009 20:38:56 +0000 (20:38 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 2 Feb 2009 20:38:56 +0000 (20:38 +0000)
not quite up-to-date compilers, to reduce repetitions and to allow using
methods of non-wxEvtHandler-derived classes as event callbacks:

1. Don't rely on compiler ability to deduce template parameter from the type
   of a parameter of a function used as another template parameter, at least
   MSVC7 can't do this and it's probably not the only one.
2. Do rely on compiler support for partial specialization to make
   wxEventFunctorMethod compile for non-wxEvtHandler-derived handlers while
   still keeping the old functionality for the wxEvtHandler-derived ones.
3. Don't make any difference between functions and functors, both are callable
   objects so use them as such, this allows to fold code for both cases.
4. Avoid the use of dynamic_cast<>.
5. Several naming changes:
 a) wxTypedEventType -> wxEventTypeTag (because this is what it is)
 b) Subscribe/Unsubscribe -> DoConnect/Disconnect (to follow the usual
    convention of public Foo calling private DoFoo and to avoid using up
    another name)
 c) Derived -> ObjClass (because it's not clear what does Derived mean)
6. Extend the unit test to cover more cases.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58625 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/event.h
include/wx/msw/chkconf.h
src/common/event.cpp
tests/events/evthandler.cpp

index 8bea6245136e83824db60ad2016ed2a03f43eadb..ed6a8017f2d9fcb76366a038b019a42f8a632f43 100644 (file)
 #include "wx/thread.h"
 #include "wx/tracker.h"
 
 #include "wx/thread.h"
 #include "wx/tracker.h"
 
+#if !wxEVENTS_COMPATIBILITY_2_8
+    #include "wx/meta/convertible.h"
+#endif
+
 // ----------------------------------------------------------------------------
 // forward declarations
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // forward declarations
 // ----------------------------------------------------------------------------
@@ -131,20 +135,20 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType();
     // a nested typedef:
  
     #define wxDEFINE_EVENT( name, type ) \
     // 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 ) \
 
     #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_ALIAS( name, type, value ) \
 
     // 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_ALIAS( name, type, value ) \
-        const wxTypedEventType< type > name( value );
+        const wxEventTypeTag< type > name( value );
 
     #define wxDECLARE_EXPORTED_EVENT_ALIAS( expdecl, name, type ) \
 
     #define wxDECLARE_EXPORTED_EVENT_ALIAS( expdecl, name, type ) \
-        extern const expdecl wxTypedEventType< type > name;
+        extern const expdecl wxEventTypeTag< type > name;
 
     // Declare a local (not exported) templatized event type:
 
 
     // Declare a local (not exported) templatized event type:
 
@@ -162,13 +166,18 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType();
 
 #if !wxEVENTS_COMPATIBILITY_2_8
 
 
 #if !wxEVENTS_COMPATIBILITY_2_8
 
-template <typename Event>
-class 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 <typename T>
+class wxEventTypeTag
 {
 public:
 {
 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; }
 
     // Return a wxEventType reference for the initialization of the static
     // event tables. See wxEventTableEntry::m_eventType for a more thorough
 
     // Return a wxEventType reference for the initialization of the static
     // event tables. See wxEventTableEntry::m_eventType for a more thorough
@@ -201,18 +210,24 @@ public:
     virtual ~wxEventFunctor();
 
     // Invoke the actual event handler:
     virtual ~wxEventFunctor();
 
     // Invoke the actual event handler:
-    virtual void operator()(wxEvtHandler *, wxEvent &) = 0;
+    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;
 
 
     // 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:
 class WXDLLIMPEXP_BASE wxObjectEventFunctor : public wxEventFunctor
 {
 public:
@@ -229,22 +244,26 @@ public:
         (realHandler->*m_method)(event);
     }
 
         (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();
+        return !method || 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;
 };
 
 
 private:
     wxEvtHandler *m_handler;
     wxObjectEventFunction 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
 
 // Create a functor for the legacy events: handler can be NULL and its default
 // value is used by the event table macros
 
@@ -257,224 +276,234 @@ wxNewEventFunctor(const wxEventType& WXUNUSED(evtType),
 }
 
 inline wxObjectEventFunctor
 }
 
 inline wxObjectEventFunctor
-wxConstructEventFunctor(const wxEventType& WXUNUSED(evtType),
+wxMakeEventFunctor(const wxEventType& WXUNUSED(evtType),
                         wxObjectEventFunction method,
                         wxEvtHandler *handler)
 {
     return wxObjectEventFunctor(method, handler);
 }
 
                         wxObjectEventFunction method,
                         wxEvtHandler *handler)
 {
     return wxObjectEventFunctor(method, handler);
 }
 
-#if !wxEVENTS_COMPATIBILITY_2_8
+#else // !wxEVENTS_COMPATIBILITY_2_8
 
 
-template <typename EventType>
+// functor forwarding the event to anything callable (function, static method,
+// generalized functor...)
+template <typename EventTag, typename Functor>
 class wxEventFunctorFunction : public wxEventFunctor
 {
 public:
 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)
     {
     {
         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<EventArg&>(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:
     }
 
 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 <typename T, typename A, bool> struct HandlerImpl;
+
+// specialization for handlers deriving from wxEvtHandler
+template <typename T, typename A>
+struct HandlerImpl<T, A, true>
+{
+    static bool IsEvtHandler()
+        { return true; }
+    static T *ConvertFromEvtHandler(wxEvtHandler *p)
+        { return static_cast<T *>(p); }
+    static wxEvtHandler *ConvertToEvtHandler(T *p)
+        { return p; }
+    static wxEventFunction ConvertToEvtFunction(void (T::*f)(A&))
+        { return reinterpret_cast<wxEventFunction>(f); }
 };
 
 };
 
+// specialization for handlers not deriving from wxEvtHandler
+template <typename T, typename A>
+struct HandlerImpl<T, A, false>
+{
+    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
 
 
-template <typename EventType, typename Class, typename Derived>
-class wxEventFunctorMethod : public wxEventFunctor
+// 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 <typename EventTag, typename Class, typename ObjClass>
+class wxEventFunctorMethod
+    : public wxEventFunctor,
+      private wxPrivate::HandlerImpl
+              <
+                Class,
+                typename EventTag::EventClass,
+                wxConvertibleTo<Class, wxEvtHandler>::value
+              >
 {
 public:
 {
 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 || IsEvtHandler(),
+                      "handlers defined in non-wxEvtHandler-derived classes "
+                      "must be connected with a valid sink object" );
+
         m_handler = handler;
         m_method =  method;
     }
 
         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 = 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<EventArg&>(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;
     }
 
         return m_handler;
     }
 
-    virtual wxObjectEventFunction GetMethod() const
+    virtual wxEventFunction GetMethod() const
     {
     {
-        return reinterpret_cast<wxObjectEventFunction>(m_method);
+        return ConvertToEvtFunction(m_method);
+    }
+
+    virtual wxEvtHandler *GetEvtHandler() const
+    {
+        return ConvertToEvtHandler(m_handler);
     }
 
 private:
     }
 
 private:
-    Derived *m_handler;
-    void (Class::*m_method)(typename EventType::CorrespondingEvent&);
+    ObjClass *m_handler;
+    void (Class::*m_method)(EventArg&);
 };
 
 };
 
-
-template <typename EventType, typename Functor>
-class wxEventFunctorAdapter : public wxEventFunctor
+// partial specialization for legacy event types
+template <typename ObjClass>
+class wxEventFunctorMethod<wxEventType, wxEvtHandler, ObjClass>
+    : public wxObjectEventFunctor
 {
 public:
 {
 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 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)
 
 
-// Create a functor for functions:
 
 
-template <typename EventType>
-inline wxEventFunctorFunction<EventType> *
-wxNewEventFunctor(const EventType &,
-                  void (*function)(typename EventType::CorrespondingEvent&))
+// Create functors wrapping other functors (including functions):
+template <typename EventTag, typename Functor>
+inline wxEventFunctorFunction<EventTag, Functor> *
+wxNewEventFunctor(const EventTag&, Functor func)
 {
 {
-    return new wxEventFunctorFunction<EventType>(function);
+    return new wxEventFunctorFunction<EventTag, Functor>(func);
 }
 
 }
 
-// Create a functor for methods:
-
-template <typename EventType, typename Class>
-inline wxEventFunctorMethod<EventType, Class, Class> *
-wxNewEventFunctor(const EventType &,
-                  void (Class::*method)(typename EventType::CorrespondingEvent&))
+template <typename EventTag, typename Functor>
+inline wxEventFunctorFunction<EventTag, Functor>
+wxMakeEventFunctor(const EventTag&, Functor func)
 {
 {
-    return new wxEventFunctorMethod<EventType, Class, Class>(method, NULL);
+    return wxEventFunctorFunction<EventTag, Functor>(func);
 }
 
 }
 
-template <typename EventType, typename Class, typename Derived>
-inline wxEventFunctorMethod<EventType, Class, Derived> *
-wxNewEventFunctor(const EventType &,
-                  void (Class::*method)(typename EventType::CorrespondingEvent &),
-                  Derived *handler )
-{
-    return new wxEventFunctorMethod<EventType, Class, Derived>(method, handler);
-}
 
 
-// Create a functor for arbitrary functors (like boost::function):
-template <typename EventType, typename Functor>
-inline wxEventFunctorAdapter<EventType, Functor> *
-wxNewEventFunctor(const EventType &,
-                  Functor& functor )
+// Create functors for methods:
+template
+  <typename EventTag, typename Class, typename EventArg, typename ObjClass>
+inline wxEventFunctorMethod<EventTag, Class, ObjClass> *
+wxNewEventFunctor(const EventTag&,
+                  void (Class::*method)(EventArg&),
+                  ObjClass *handler)
 {
 {
-    return new wxEventFunctorAdapter<EventType, Functor>(functor);
+    return new wxEventFunctorMethod<EventTag, Class, ObjClass>(method, handler);
 }
 
 }
 
-//
-// Construct functors for the templatized events (needed in wxEvtHandler::Disconnect):
-//
-
-// Construct a functor for functions:
-
-template <typename EventType>
-inline wxEventFunctorFunction<EventType>
-wxConstructEventFunctor(const EventType &,
-                        void (*function)(typename EventType::CorrespondingEvent&))
+template
+    <typename EventTag, typename Class, typename EventArg, typename ObjClass>
+inline wxEventFunctorMethod<EventTag, Class, ObjClass>
+wxMakeEventFunctor(const EventTag&,
+                   void (Class::*method)(EventArg&),
+                   ObjClass *handler)
 {
 {
-    return wxEventFunctorFunction<EventType>(function);
+    return wxEventFunctorMethod<EventTag, Class, ObjClass>(method, handler);
 }
 
 }
 
-// Construct a functor for methods:
-
-template <typename EventType, typename Class>
-inline wxEventFunctorMethod<EventType, Class, Class>
-wxConstructEventFunctor(const EventType &,
-                        void (Class::*method)(typename EventType::CorrespondingEvent&))
+// 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 <typename EventTag, typename Class, typename EventArg>
+inline wxEventFunctorMethod<EventTag, Class, Class> *
+wxNewEventFunctor(const EventTag&, void (Class::*method)(EventArg&))
 {
 {
-    return wxEventFunctorMethod<EventType, Class, Class>(method, NULL);
+    return new wxEventFunctorMethod<EventTag, Class, Class>(method, NULL);
 }
 
 }
 
-template <typename EventType, typename Class, typename Derived>
-inline wxEventFunctorMethod<EventType, Class, Derived>
-wxConstructEventFunctor(const EventType &,
-                        void (Class::*method)(typename EventType::CorrespondingEvent&),
-                        Derived *handler)
+template
+    <typename EventTag, typename Class, typename EventArg, typename ObjClass>
+inline wxEventFunctorMethod<EventTag, Class, Class>
+wxMakeEventFunctor(const EventTag&, void (Class::*method)(EventArg&))
 {
 {
-    return wxEventFunctorMethod<EventType, Class, Derived>(method, handler);
-}
-
-// Construct a functor for arbitrary functors (like boost:function):
-
-template <typename EventType, typename Functor>
-inline wxEventFunctorAdapter<EventType, Functor>
-wxConstructEventFunctor(const EventType &,
-                        Functor& functor)
-{
-    return wxEventFunctorAdapter<EventType, Functor>(functor);
+    return wxEventFunctorMethod<EventTag, Class, Class>(method, NULL);
 }
 
 #endif // !wxEVENTS_COMPATIBILITY_2_8
 
 }
 
 #endif // !wxEVENTS_COMPATIBILITY_2_8
 
+
 // many, but not all, standard event types
 
     // some generic events
 // many, but not all, standard event types
 
     // some generic events
@@ -1016,7 +1045,7 @@ class WXDLLIMPEXP_CORE wxScrollWinEvent : public wxEvent
 public:
     wxScrollWinEvent(wxEventType commandType = wxEVT_NULL,
                      int pos = 0, int orient = 0);
 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;    }
 
         {    m_commandInt = event.m_commandInt;
             m_extraLong = event.m_extraLong;    }
 
@@ -1260,7 +1289,7 @@ public:
           m_x(x), m_y(y), m_cursor()
         { }
 
           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),
         : wxEvent(event),
           m_x(event.m_x),
           m_y(event.m_y),
@@ -1403,7 +1432,7 @@ public:
         : wxEvent(winid, wxEVT_SIZE),
           m_size(sz)
         { }
         : 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)
         { }
         : wxEvent(event),
           m_size(event.m_size), m_rect(event.m_rect)
         { }
@@ -1658,7 +1687,7 @@ public:
     wxMenuEvent(wxEventType type = wxEVT_NULL, int winid = 0, wxMenu* menu = NULL)
         : wxEvent(winid, type)
         { m_menuId = winid; m_menu = menu; }
     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; }
 
         : wxEvent(event)
     { m_menuId = event.m_menuId; m_menu = event.m_menu; }
 
@@ -1696,7 +1725,7 @@ public:
           m_veto(false),      // should be false by default
           m_canVeto(true) {}
 
           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),
         : wxEvent(event),
         m_loggingOff(event.m_loggingOff),
         m_veto(event.m_veto),
@@ -1746,7 +1775,7 @@ public:
     wxShowEvent(int winid = 0, bool show = false)
         : wxEvent(winid, wxEVT_SHOW)
         { m_show = show; }
     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; }
 
         : wxEvent(event)
     { m_show = event.m_show; }
 
@@ -1778,7 +1807,7 @@ public:
     wxIconizeEvent(int winid = 0, bool iconized = true)
         : wxEvent(winid, wxEVT_ICONIZE)
         { m_iconized = iconized; }
     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; }
 
         : wxEvent(event)
     { m_iconized = event.m_iconized; }
 
@@ -1860,7 +1889,7 @@ public:
           m_joyStick(joystick)
     {
     }
           m_joyStick(joystick)
     {
     }
-    wxJoystickEvent(const wxJoystickEvent & event)
+    wxJoystickEvent(const wxJoystickEvent& event)
         : wxEvent(event),
           m_pos(event.m_pos),
           m_zPosition(event.m_zPosition),
         : wxEvent(event),
           m_pos(event.m_pos),
           m_zPosition(event.m_zPosition),
@@ -1995,7 +2024,7 @@ public:
         m_setText =
         m_setChecked = false;
     }
         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),
         : wxCommandEvent(event),
           m_checked(event.m_checked),
           m_enabled(event.m_enabled),
@@ -2191,7 +2220,7 @@ public:
         : wxEvent(winid, wxEVT_QUERY_NEW_PALETTE),
           m_paletteRealized(false)
         { }
         : wxEvent(winid, wxEVT_QUERY_NEW_PALETTE),
           m_paletteRealized(false)
         { }
-    wxQueryNewPaletteEvent(const wxQueryNewPaletteEvent & event)
+    wxQueryNewPaletteEvent(const wxQueryNewPaletteEvent& event)
         : wxEvent(event),
         m_paletteRealized(event.m_paletteRealized)
     { }
         : wxEvent(event),
         m_paletteRealized(event.m_paletteRealized)
     { }
@@ -2337,7 +2366,7 @@ public:
           m_pos(pt),
           m_origin(GuessOrigin(origin))
     { }
           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),
         : wxCommandEvent(event),
           m_pos(event.m_pos),
           m_target(event.m_target),
@@ -2395,7 +2424,7 @@ public:
                      wxWindowID winid = 0)
         : wxCommandEvent(type, winid)
     { }
                      wxWindowID winid = 0)
         : wxCommandEvent(type, winid)
     { }
-    wxClipboardTextEvent(const wxClipboardTextEvent & event)
+    wxClipboardTextEvent(const wxClipboardTextEvent& event)
         : wxCommandEvent(event)
     { }
 
         : wxCommandEvent(event)
     { }
 
@@ -2422,7 +2451,7 @@ public:
         : wxCommandEvent(type, winid),
           m_pos(pt)
     { }
         : wxCommandEvent(type, winid),
           m_pos(pt)
     { }
-    wxContextMenuEvent(const wxContextMenuEvent & event)
+    wxContextMenuEvent(const wxContextMenuEvent& event)
         : wxCommandEvent(event),
         m_pos(event.m_pos)
     { }
         : wxCommandEvent(event),
         m_pos(event.m_pos)
     { }
@@ -2468,7 +2497,7 @@ public:
         : wxEvent(0, wxEVT_IDLE),
           m_requestMore(false)
         { }
         : wxEvent(0, wxEVT_IDLE),
           m_requestMore(false)
         { }
-    wxIdleEvent(const wxIdleEvent & event)
+    wxIdleEvent(const wxIdleEvent& event)
         : wxEvent(event),
           m_requestMore(event.m_requestMore)
     { }
         : wxEvent(event),
           m_requestMore(event.m_requestMore)
     { }
@@ -2534,7 +2563,7 @@ struct WXDLLIMPEXP_BASE wxEventTableEntryBase
         // being initialized (a temporary instance is created and then this
         // constructor is called).
 
         // being initialized (a temporary instance is created and then this
         // constructor is called).
 
-        const_cast< wxEventTableEntryBase & >( entry ).m_fn = NULL;
+        const_cast<wxEventTableEntryBase&>( entry ).m_fn = NULL;
     }
 
     ~wxEventTableEntryBase()
     }
 
     ~wxEventTableEntryBase()
@@ -2554,7 +2583,7 @@ struct WXDLLIMPEXP_BASE wxEventTableEntryBase
     wxObject* m_callbackUserData;
 
 private:
     wxObject* m_callbackUserData;
 
 private:
-    wxEventTableEntryBase &operator = ( const wxEventTableEntryBase & );
+    DECLARE_NO_ASSIGN_CLASS(wxEventTableEntryBase)
 };
 
 // an entry from a static event table
 };
 
 // an entry from a static event table
@@ -2575,7 +2604,7 @@ struct WXDLLIMPEXP_BASE wxEventTableEntry : public wxEventTableEntryBase
     const int& m_eventType;
 
 private:
     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()
 };
 
 // an entry used in dynamic event table managed by wxEvtHandler::Connect()
@@ -2593,7 +2622,7 @@ struct WXDLLIMPEXP_BASE wxDynamicEventTableEntry : public wxEventTableEntryBase
     int m_eventType;
 
 private:
     int m_eventType;
 
 private:
-    wxDynamicEventTableEntry &operator = ( const wxDynamicEventTableEntry & );
+    DECLARE_NO_ASSIGN_CLASS(wxDynamicEventTableEntry)
 };
 
 // ----------------------------------------------------------------------------
 };
 
 // ----------------------------------------------------------------------------
@@ -2634,7 +2663,7 @@ public:
 
     // Handle the given event, in other words search the event table hash
     // and call self->ProcessEvent() if a match was found.
 
     // 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(wxEventevent, wxEvtHandler *self);
 
     // Clear table
     void Clear();
 
     // Clear table
     void Clear();
@@ -2745,6 +2774,15 @@ public:
     // Connecting and disconnecting
     // ----------------------------
 
     // 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,
     // Dynamic association of a member function handler with the event handler,
     // winid and event type
     void Connect(int winid,
@@ -2754,9 +2792,9 @@ public:
                  wxObject *userData = NULL,
                  wxEvtHandler *eventSink = NULL)
     {
                  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
     }
 
     // Convenience function: take just one id
@@ -2781,9 +2819,9 @@ public:
                     wxObject *userData = NULL,
                     wxEvtHandler *eventSink = NULL)
     {
                     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,
     }
 
     bool Disconnect(int winid = wxID_ANY,
@@ -2798,305 +2836,258 @@ public:
                     wxObject *userData = NULL,
                     wxEvtHandler *eventSink = NULL)
         { return Disconnect(wxID_ANY, eventType, func, userData, eventSink); }
                     wxObject *userData = NULL,
                     wxEvtHandler *eventSink = NULL)
         { return Disconnect(wxID_ANY, eventType, func, userData, eventSink); }
+
 #if !wxEVENTS_COMPATIBILITY_2_8
 #if !wxEVENTS_COMPATIBILITY_2_8
-    //
-    // Connect a method to an event:
-    //
+    // Event handling in functions (including generalized functors):
 
 
-    template <typename EventType, typename Class>
-    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 <typename EventTag, typename Functor>
+    void Connect(int winid,
+                 int lastId,
+                 const EventTag& eventType,
+                 Functor func)
+    {
+        DoConnect(winid, lastId, eventType,
+                  wxNewEventFunctor(eventType, func));
+    }
 
 
-            Subscribe( winid, lastId, eventType, functor, userData );
-        }
+    template <typename EventTag, typename Functor>
+    void Connect(int winid, const EventTag& eventType, Functor func)
+        { Connect(winid, wxID_ANY, eventType, func); }
 
 
-    template <typename EventType, typename Class>
-    void Connect( int winid,
-            const EventType &eventType,
-            void ( Class::*func )( typename EventType::CorrespondingEvent & ),
-            wxObject *userData = NULL )
-        { Connect( winid, wxID_ANY, eventType, func, userData ); }
-
-    template <typename EventType, typename Class>
-    void Connect( const EventType &eventType,
-            void ( Class::*func )( typename EventType::CorrespondingEvent & ),
-            wxObject *userData = NULL )
-        { Connect( wxID_ANY, wxID_ANY, eventType, func, userData ); }
-
-    template <typename EventType, typename Class, typename Derived>
-    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 <typename EventTag, typename Functor>
+    void Connect(const EventTag& eventType, Functor func)
+        { Connect(wxID_ANY, eventType, func); }
 
 
-            Subscribe( winid, lastId, eventType, functor, userData );
-        }
 
 
-    template <typename EventType, typename Class, typename Derived>
-    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 <typename EventType, typename Class, typename Derived>
-    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 <typename Sender, typename EventType, typename Class, typename Derived>
-    static void Connect( Sender *sender,
-            int winid,
-            int lastId,
-            const EventType &eventType,
-            void ( Class::*func )( typename EventType::CorrespondingEvent & ),
-            wxObject *userData = NULL,
-            Derived *eventSink = NULL )
+    template <typename EventTag, typename Functor>
+    bool Disconnect(int winid,
+                    int lastId,
+                    const EventTag& eventType,
+                    Functor func)
     {
     {
-        wxEventFunctorMethod< EventType, Class, Derived > *functor =
-            wxNewEventFunctor( eventType, func, eventSink );
-
-        sender->Subscribe( winid, lastId, eventType, functor, userData );
+        return DoDisconnect(winid, lastId, eventType,
+                           wxMakeEventFunctor(eventType, func));
     }
 
     }
 
-    template <typename Sender, typename EventType, typename Class, typename Derived>
-    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 <typename Sender, typename EventType, typename Class, typename Derived>
-    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 <typename EventTag, typename Functor>
+    bool Disconnect(int winid, const EventTag& eventType, Functor func)
+        { return Disconnect(winid, wxID_ANY, eventType, func); }
 
 
+    template <typename EventTag, typename Functor>
+    bool Disconnect(const EventTag& eventType, Functor func)
+        { return Disconnect(wxID_ANY, eventType, func); }
+
+
+
+    // 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.
     //
     //
-    // Connect a function to an event:
-    //
-    template <typename EventType>
+    // 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 <typename EventTag, typename Class, typename EventArg>
     void Connect(int winid,
                  int lastId,
     void Connect(int winid,
                  int lastId,
-                 const EventType &eventType,
-                 void (*func)(typename EventType::CorrespondingEvent&),
-                 wxObjectuserData = NULL)
+                 const EventTag& eventType,
+                 void (Class::*func)(EventArg&),
+                 wxObject *userData = NULL)
     {
     {
-        wxEventFunctorFunction< EventType > *functor = wxNewEventFunctor( eventType, func );
-
-        Subscribe( winid, lastId, eventType, functor, userData );
+        DoConnect(winid, lastId, eventType,
+                  wxNewEventFunctor(eventType, func, static_cast<Class *>(this)),
+                  userData);
     }
 
     }
 
-    template <typename EventType>
-    void Connect( int winid,
-            const EventType &eventType,
-            void ( *func )( typename EventType::CorrespondingEvent & ),
-            wxObject* userData = NULL )
-        { Connect( winid, wxID_ANY, eventType, func, userData ); }
+    template <typename EventTag, typename Class, typename EventArg>
+    void Connect(int winid,
+                 const EventTag& eventType,
+                 void (Class::*func)(EventArg&),
+                 wxObject *userData = NULL)
+        { Connect(winid, wxID_ANY, eventType, func, userData); }
 
 
-    template <typename EventType>
-    void Connect( const EventType &eventType,
-            void ( *func )( typename EventType::CorrespondingEvent & ),
-            wxObject* userData = NULL )
-        { Connect( wxID_ANY, wxID_ANY, eventType, func, userData ); }
+    template <typename EventTag, typename Class, typename EventArg>
+    void Connect(const EventTag& eventType,
+                 void (Class::*func)(EventArg&),
+                 wxObject *userData = NULL)
+        { Connect(wxID_ANY, eventType, func, userData); }
 
 
-    //
-    // Connect an arbitrary functor to an event:
-    //
 
 
-    template <typename EventType, typename Functor>
-    void Connect( int winid,
-            int lastId,
-            const EventType &eventType,
-            Functor &functor,
-            wxObject* userData = NULL)
+    template <typename EventTag, typename Class, typename EventArg>
+    bool Disconnect(int winid,
+                    int lastId,
+                    const EventTag& eventType,
+                    void (Class::*func)(EventArg&),
+                    wxObject *userData = NULL)
     {
     {
-        wxEventFunctorAdapter< EventType, Functor > *adapter =
-            wxNewEventFunctor( eventType, functor );
-
-        Subscribe( winid, lastId, eventType, adapter, userData );
+        return DoDisconnect(winid, lastId, eventType,
+                            wxMakeEventFunctor(eventType, func,
+                                               static_cast<Class *>(this)),
+                            userData);
     }
     }
-    template <typename EventType, typename Functor>
-    void Connect( int winid,
-            const EventType &eventType,
-            Functor &functor,
-            wxObject* userData = NULL)
-        { Connect( winid, wxID_ANY, eventType, functor, userData ); }
-
-    template <typename EventType, typename Functor>
-    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 <typename EventTag, typename Class, typename EventArg>
+    bool Disconnect(int winid,
+                    const EventTag& eventType,
+                    void (Class::*func)(EventArg&),
+                    wxObject *userData = NULL)
+        { return Disconnect(winid, wxID_ANY, eventType, func, userData); }
 
 
-    template <typename EventType>
-    bool Disconnect( int winid,
-        int lastId,
-        const EventType &eventType,
-        void ( *func )( typename EventType::CorrespondingEvent & ),
-        wxObject* userData = NULL )
-    {
-        wxEventFunctorFunction< EventType > functor = wxConstructEventFunctor( eventType, func );
+    template <typename EventTag, typename Class, typename EventArg>
+    bool Disconnect(const EventTag& eventType,
+                    void (Class::*func)(EventArg&),
+                    wxObject *userData = NULL)
+        { return Disconnect(wxID_ANY, eventType, func, userData); }
+
+
+    // Methods connecting/disconnecting event to another object
 
 
-        return Unsubscribe( winid, lastId, eventType, functor, userData );
+    template
+      <typename EventTag, typename Class, typename EventArg, typename ObjClass>
+    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 <typename EventType>
-    bool Disconnect( int winid,
-            const EventType &eventType,
-            void ( *func )( typename EventType::CorrespondingEvent & ),
-            wxObject* userData = NULL )
-        { return Disconnect( winid, wxID_ANY, eventType, func, userData ); }
+    template
+      <typename EventTag, typename Class, typename EventArg, typename ObjClass>
+    void Connect(int winid,
+                 const EventTag& eventType,
+                 void (Class::*func)(EventArg&),
+                 wxObject *userData,
+                 ObjClass *eventSink)
+        { Connect(winid, wxID_ANY, eventType, func, userData, eventSink); }
 
 
-    template <typename EventType>
-    bool Disconnect( const EventType &eventType,
-            void ( *func )( typename EventType::CorrespondingEvent & ),
-            wxObject* userData = NULL )
-        { return Disconnect( wxID_ANY, wxID_ANY, eventType, func, userData ); }
+    template
+      <typename EventTag, typename Class, typename EventArg, typename ObjClass>
+    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 <typename EventType, typename Class>
-    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
+      <typename EventTag, typename Class, typename EventArg, typename ObjClass>
+    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
+      <typename EventTag, typename Class, typename EventArg, typename ObjClass>
+    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
+      <typename EventTag, typename Class, typename EventArg, typename ObjClass>
+    bool Disconnect(const EventTag& eventType,
+                    void (Class::*func)(EventArg&),
+                    wxObject *userData,
+                    ObjClass *eventSink)
+        { return Disconnect(wxID_ANY, eventType, func, userData, eventSink); }
 
 
-    template <typename EventType, typename Class>
-    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 <typename EventType, typename Class>
-    bool Disconnect( const EventType &eventType,
-            void ( Class::*func )( typename EventType::CorrespondingEvent & ),
-            wxObject *userData = NULL )
-        { return Disconnect( wxID_ANY, wxID_ANY, eventType, func, userData ); }
-
-    template <typename EventType, typename Class, typename Derived>
-    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 <typename EventType, typename Class, typename Derived>
-    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 <typename EventType, typename Class, typename Derived>
-    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 <typename Sender, typename EventType, typename Class, typename Derived>
-    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 <typename ObjSource, typename EventTag,
+              typename Class, typename EventArg, typename ObjClass>
+    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 <typename ObjSource, typename EventTag,
+              typename Class, typename EventArg, typename ObjClass>
+    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 <typename Sender, typename EventType, typename Class, typename Derived>
-    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 <typename Sender, typename EventType, typename Class, typename Derived>
-    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 <typename ObjSource, typename EventTag,
+              typename Class, typename EventArg, typename ObjClass>
+    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 <typename EventType, typename Functor>
-    bool Disconnect( int winid,
-            int lastId,
-            const EventType &eventType,
-            Functor &functor,
-            wxObject* userData = NULL)
+    template <typename ObjSource, typename EventTag,
+              typename Class, typename EventArg, typename ObjClass>
+    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 <typename EventType, typename Functor>
-    bool Disconnect( int winid,
-            const EventType &eventType,
-            Functor &functor,
-            wxObject* userData = NULL)
-        { return Disconnect( winid, wxID_ANY, eventType, functor, userData ); }
-
-    template <typename EventType, typename Functor>
-    bool Disconnect( const EventType &eventType,
-            Functor &functor,
-            wxObject* userData = NULL)
-        { return Disconnect( wxID_ANY, wxID_ANY, eventType, functor, userData ); }
+    template <typename ObjSource, typename EventTag,
+              typename Class, typename EventArg, typename ObjClass>
+    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 <typename ObjSource, typename EventTag,
+              typename Class, typename EventArg, typename ObjClass>
+    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
 
 
 #endif // !wxEVENTS_COMPATIBILITY_2_8
 
 
@@ -3140,17 +3131,17 @@ public:
 
 
 private:
 
 
 private:
-    void Subscribe(int winid,
+    void DoConnect(int winid,
                    int lastId,
                    wxEventType eventType,
                    wxEventFunctor *func,
                    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[];
 
 
     static const wxEventTableEntry sm_eventTableEntries[];
 
index 356cb0160b2cee81da5d0bfa1b18feee55ba1381..d1d30c7c24556f26807c6dbbfdaa85d4cb5c2c45 100644 (file)
    Windows.
  */
 #if !wxEVENTS_COMPATIBILITY_2_8
    Windows.
  */
 #if !wxEVENTS_COMPATIBILITY_2_8
-#   if !wxCHECK_VISUALC_VERSION(8)
+#   if !wxCHECK_VISUALC_VERSION(7)
 #       undef wxEVENTS_COMPATIBILITY_2_8
 #       define wxEVENTS_COMPATIBILITY_2_8 1
 #   endif
 #       undef wxEVENTS_COMPATIBILITY_2_8
 #       define wxEVENTS_COMPATIBILITY_2_8 1
 #   endif
index 85951a1b3eb7c32e2681cd44e117f3c053748a0a..6a878fd4601561017f111d9b124906a9e67a8dd2 100644 (file)
@@ -1065,7 +1065,7 @@ wxEvtHandler::~wxEvtHandler()
 
             // Remove ourselves from sink destructor notifications
             // (this has usually been done, in wxTrackable destructor)
 
             // Remove ourselves from sink destructor notifications
             // (this has usually been done, in wxTrackable destructor)
-            wxEvtHandler *eventSink = entry->m_fn->GetHandler();
+            wxEvtHandler *eventSink = entry->m_fn->GetEvtHandler();
             if ( eventSink )
             {
                 wxEventConnectionRef * const
             if ( eventSink )
             {
                 wxEventConnectionRef * const
@@ -1408,10 +1408,11 @@ bool wxEvtHandler::SearchEventTable(wxEventTable& table, wxEvent& event)
     return false;
 }
 
     return false;
 }
 
-void wxEvtHandler::Subscribe( int id, int lastId,
-                            wxEventType eventType,
-                            wxEventFunctor *func,
-                            wxObject *userData )
+void wxEvtHandler::DoConnect(int id,
+                             int lastId,
+                             wxEventType eventType,
+                             wxEventFunctor *func,
+                             wxObject *userData)
 {
     wxDynamicEventTableEntry *entry =
         new wxDynamicEventTableEntry(eventType, id, lastId, func, userData);
 {
     wxDynamicEventTableEntry *entry =
         new wxDynamicEventTableEntry(eventType, id, lastId, func, userData);
@@ -1423,7 +1424,7 @@ void wxEvtHandler::Subscribe( int id, int lastId,
     m_dynamicEvents->Insert( (wxObject*) entry );
 
     // Make sure we get to know when a sink is destroyed
     m_dynamicEvents->Insert( (wxObject*) entry );
 
     // Make sure we get to know when a sink is destroyed
-    wxEvtHandler *eventSink = func->GetHandler();
+    wxEvtHandler *eventSink = func->GetEvtHandler();
     if ( eventSink && eventSink != this )
     {
         wxEventConnectionRef *evtConnRef = FindRefInTrackerList(eventSink);
     if ( eventSink && eventSink != this )
     {
         wxEventConnectionRef *evtConnRef = FindRefInTrackerList(eventSink);
@@ -1435,17 +1436,17 @@ void wxEvtHandler::Subscribe( int id, int lastId,
 }
 
 bool
 }
 
 bool
-wxEvtHandler::Unsubscribe(int id,
-                          int lastId,
-                          wxEventType eventType,
-                          const wxEventFunctor& func,
-                          wxObject *userData)
+wxEvtHandler::DoDisconnect(int id,
+                           int lastId,
+                           wxEventType eventType,
+                           const wxEventFunctor& func,
+                           wxObject *userData)
 {
     if (!m_dynamicEvents)
         return false;
 
     // Remove connection from tracker node (wxEventConnectionRef)
 {
     if (!m_dynamicEvents)
         return false;
 
     // Remove connection from tracker node (wxEventConnectionRef)
-    wxEvtHandler *eventSink = func.GetHandler();
+    wxEvtHandler *eventSink = func.GetEvtHandler();
     if ( eventSink && eventSink != this )
     {
         wxEventConnectionRef *evtConnRef = FindRefInTrackerList(eventSink);
     if ( eventSink && eventSink != this )
     {
         wxEventConnectionRef *evtConnRef = FindRefInTrackerList(eventSink);
@@ -1490,7 +1491,7 @@ bool wxEvtHandler::SearchDynamicEventTable( wxEvent& event )
 
         if ( event.GetEventType() == entry->m_eventType )
         {
 
         if ( event.GetEventType() == entry->m_eventType )
         {
-            wxEvtHandler *handler = entry->m_fn->GetHandler();
+            wxEvtHandler *handler = entry->m_fn->GetEvtHandler();
             if ( !handler )
                handler = this;
             if ( ProcessEventIfMatchesId(*entry, handler, event) )
             if ( !handler )
                handler = this;
             if ( ProcessEventIfMatchesId(*entry, handler, event) )
@@ -1571,7 +1572,7 @@ void wxEvtHandler::OnSinkDestroyed( wxEvtHandler *sink )
         wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)node->GetData();
         node_nxt = node->GetNext();
 
         wxDynamicEventTableEntry *entry = (wxDynamicEventTableEntry*)node->GetData();
         node_nxt = node->GetNext();
 
-        if ( entry->m_fn->GetHandler() == sink )
+        if ( entry->m_fn->GetEvtHandler() == sink )
         {
             delete entry->m_callbackUserData;
             m_dynamicEvents->Erase( node );
         {
             delete entry->m_callbackUserData;
             m_dynamicEvents->Erase( node );
index d19a1fde30e7b30e32ac4eb3527d83c2529999ce..137fe3e6e2996f2a7cd259a46925a1c5b229efc5 100644 (file)
     #pragma hdrstop
 #endif
 
     #pragma hdrstop
 #endif
 
-#ifndef WX_PRECOMP
-#endif // WX_PRECOMP
-
 #include "wx/event.h"
 
 #include "wx/event.h"
 
-
-// --------------------------------------------------------------------------
-// test class
-// --------------------------------------------------------------------------
-
-class EvtHandlerTestCase : public CppUnit::TestCase
-{
-public:
-    EvtHandlerTestCase() {}
-
-private:
-    CPPUNIT_TEST_SUITE( EvtHandlerTestCase );
-        CPPUNIT_TEST( TestConnectCompilation );
-        CPPUNIT_TEST( TestEventFunctorCompare );
-    CPPUNIT_TEST_SUITE_END();
-
-    void TestConnectCompilation();
-    void TestEventFunctorCompare();
-
-    DECLARE_NO_COPY_CLASS(EvtHandlerTestCase)
-};
-
-// register in the unnamed registry so that these tests are run by default
-CPPUNIT_TEST_SUITE_REGISTRATION( EvtHandlerTestCase );
-
-// also include in it's own registry so that these tests can be run alone
-CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( EvtHandlerTestCase, "EvtHandlerTestCase" );
+// ----------------------------------------------------------------------------
+// test events and their handlers
+// ----------------------------------------------------------------------------
 
 const wxEventType EVT_LEGACY = wxNewEventType();
 
 
 const wxEventType EVT_LEGACY = wxNewEventType();
 
@@ -93,44 +66,145 @@ void GlobalOnMyEvent(MyEvent&)
     g_called.function = true;
 }
 
     g_called.function = true;
 }
 
-class MyFunctor
+void GlobalOnAnotherEvent(AnotherEvent&);
+
+void GlobalOnIdle(wxIdleEvent&)
+{
+    g_called.function = true;
+}
+
+struct MyFunctor
 {
 {
-public:
     void operator()(MyEvent &) { g_called.functor = true; }
     void operator()(MyEvent &) { g_called.functor = true; }
+};
 
 
-    bool operator==(const MyFunctor &) const { return true; }
+struct IdleFunctor
+{
+    void operator()(wxIdleEvent &) { g_called.functor = true; }
 };
 
 class MyHandler : public wxEvtHandler
 {
 public:
 };
 
 class MyHandler : public wxEvtHandler
 {
 public:
+    static void StaticOnMyEvent(MyEvent &) { g_called.smethod = true; }
+    static void StaticOnAnotherEvent(AnotherEvent &);
+    static void StaticOnIdle(wxIdleEvent&) { g_called.smethod = true; }
+
     void OnMyEvent(MyEvent&) { g_called.method = true; }
     void OnMyEvent(MyEvent&) { g_called.method = true; }
+    void OnEvent(wxEvent&) { g_called.method = true; }
+    void OnAnotherEvent(AnotherEvent&);
+    void OnIdle(wxIdleEvent&) { g_called.method = true; }
+};
 
 
-    static void StaticOnMyEvent(MyEvent &) { g_called.smethod = true; }
+// we can also handle events in classes not deriving from wxEvtHandler
+struct MySink
+{
+    void OnMyEvent(MyEvent&) { g_called.method = true; }
+    void OnIdle(wxIdleEvent&) { g_called.method = true; }
+};
 
 
-    void OnEvent(wxEvent &) { }
-    void OnAnotherEvent(AnotherEvent&) { }
+// also test event table compilation
+class MyClassWithEventTable : public wxEvtHandler
+{
+public:
+    void OnMyEvent(MyEvent&) { g_called.method = true; }
+    void OnEvent(wxEvent&) { g_called.method = true; }
+    void OnAnotherEvent(AnotherEvent&);
+    void OnIdle(wxIdleEvent&) { g_called.method = true; }
+
+private:
+    DECLARE_EVENT_TABLE()
 };
 
 };
 
+BEGIN_EVENT_TABLE(MyClassWithEventTable, wxEvtHandler)
+    EVT_IDLE(MyClassWithEventTable::OnIdle)
+
+    // this shouldn't compile:
+    //EVT_IDLE(MyClassWithEventTable::OnAnotherEvent)
+END_EVENT_TABLE()
+
 } // anonymous namespace
 
 } // anonymous namespace
 
-void EvtHandlerTestCase::TestConnectCompilation()
+
+// --------------------------------------------------------------------------
+// test class
+// --------------------------------------------------------------------------
+
+class EvtHandlerTestCase : public CppUnit::TestCase
 {
 {
-    // Test that connecting the 'legacy' events still compiles:
+public:
+    EvtHandlerTestCase() {}
+
+private:
+    CPPUNIT_TEST_SUITE( EvtHandlerTestCase );
+        CPPUNIT_TEST( BuiltinConnect );
+        CPPUNIT_TEST( LegacyConnect );
+#if !wxEVENTS_COMPATIBILITY_2_8
+        CPPUNIT_TEST( ConnectFunction );
+        CPPUNIT_TEST( ConnectStaticMethod );
+        CPPUNIT_TEST( ConnectFunctor );
+        CPPUNIT_TEST( ConnectMethod );
+        CPPUNIT_TEST( ConnectMethodWithSink );
+        CPPUNIT_TEST( ConnectNonHandler );
+        CPPUNIT_TEST( StaticConnect );
+        CPPUNIT_TEST( InvalidConnect );
+#endif // !wxEVENTS_COMPATIBILITY_2_8
+    CPPUNIT_TEST_SUITE_END();
+
+    void BuiltinConnect();
+    void LegacyConnect();
+#if !wxEVENTS_COMPATIBILITY_2_8
+    void ConnectFunction();
+    void ConnectStaticMethod();
+    void ConnectFunctor();
+    void ConnectMethod();
+    void ConnectMethodWithSink();
+    void ConnectNonHandler();
+    void StaticConnect();
+    void InvalidConnect();
+#endif // !wxEVENTS_COMPATIBILITY_2_8
+
 
 
+    // these member variables exceptionally don't use "m_" prefix because
+    // they're used so many times
     MyHandler handler;
     MyEvent e;
 
     MyHandler handler;
     MyEvent e;
 
-    handler.Connect( EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
-    handler.Connect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
-    handler.Connect( 0, 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
+    DECLARE_NO_COPY_CLASS(EvtHandlerTestCase)
+};
 
 
-    handler.Disconnect( EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
-    handler.Disconnect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
-    handler.Disconnect( 0, 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
+// register in the unnamed registry so that these tests are run by default
+CPPUNIT_TEST_SUITE_REGISTRATION( EvtHandlerTestCase );
+
+// also include in it's own registry so that these tests can be run alone
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( EvtHandlerTestCase, "EvtHandlerTestCase" );
+
+void EvtHandlerTestCase::BuiltinConnect()
+{
+    handler.Connect(wxEVT_IDLE, wxIdleEventHandler(MyHandler::OnIdle));
+    handler.Disconnect(wxEVT_IDLE, wxIdleEventHandler(MyHandler::OnIdle));
+
+    handler.Connect(wxEVT_IDLE, wxIdleEventHandler(MyHandler::OnIdle), NULL, &handler);
+    handler.Disconnect(wxEVT_IDLE, wxIdleEventHandler(MyHandler::OnIdle), NULL, &handler);
 
 
+#if !wxEVENTS_COMPATIBILITY_2_8
+    handler.Connect(wxEVT_IDLE, GlobalOnIdle);
+    handler.Disconnect(wxEVT_IDLE, GlobalOnIdle);
 
 
+    IdleFunctor f;
+    handler.Connect(wxEVT_IDLE, f);
+    handler.Disconnect(wxEVT_IDLE, f);
 
 
+    handler.Connect(wxEVT_IDLE, &MyHandler::OnIdle);
+    handler.Disconnect(wxEVT_IDLE, &MyHandler::OnIdle);
+
+    handler.Connect(wxEVT_IDLE, &MyHandler::StaticOnIdle);
+    handler.Disconnect(wxEVT_IDLE, &MyHandler::StaticOnIdle);
+#endif // !wxEVENTS_COMPATIBILITY_2_8
+}
+
+void EvtHandlerTestCase::LegacyConnect()
+{
     handler.Connect( EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
     handler.Connect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
     handler.Connect( 0, 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
     handler.Connect( EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
     handler.Connect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
     handler.Connect( 0, 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
@@ -139,38 +213,99 @@ void EvtHandlerTestCase::TestConnectCompilation()
     handler.Disconnect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
     handler.Disconnect( 0, 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
 
     handler.Disconnect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
     handler.Disconnect( 0, 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent );
 
-    // Call (and therefore instantiate) all Connect() variants to detect template
-    // errors:
+
+    handler.Connect( EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
+    handler.Connect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
+    handler.Connect( 0, 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
+
+    handler.Disconnect( EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
+    handler.Disconnect( 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
+    handler.Disconnect( 0, 0, EVT_LEGACY, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
+}
 
 #if !wxEVENTS_COMPATIBILITY_2_8
 
 #if !wxEVENTS_COMPATIBILITY_2_8
+
+void EvtHandlerTestCase::ConnectFunction()
+{
+    // function tests
+    handler.Connect( EVT_MYEVENT, GlobalOnMyEvent );
+    g_called.Reset();
+    handler.ProcessEvent(e);
+    CPPUNIT_ASSERT( g_called.function );
+    handler.Disconnect( EVT_MYEVENT, GlobalOnMyEvent );
+    g_called.Reset();
+    handler.ProcessEvent(e);
+    CPPUNIT_ASSERT( !g_called.function ); // check that it was disconnected
+
+    handler.Connect( 0, EVT_MYEVENT, GlobalOnMyEvent );
+    handler.Disconnect( 0, EVT_MYEVENT, GlobalOnMyEvent );
+
+    handler.Connect( 0, 0, EVT_MYEVENT, GlobalOnMyEvent );
+    handler.Disconnect( 0, 0, EVT_MYEVENT, GlobalOnMyEvent );
+}
+
+void EvtHandlerTestCase::ConnectStaticMethod()
+{
+    // static method tests (this is same as functions but still test it just in
+    // case we hit some strange compiler bugs)
     handler.Connect( EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
     g_called.Reset();
     handler.ProcessEvent(e);
     CPPUNIT_ASSERT( g_called.smethod );
     handler.Disconnect( EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
     handler.Connect( EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
     g_called.Reset();
     handler.ProcessEvent(e);
     CPPUNIT_ASSERT( g_called.smethod );
     handler.Disconnect( EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
-
     g_called.Reset();
     handler.ProcessEvent(e);
     g_called.Reset();
     handler.ProcessEvent(e);
-    CPPUNIT_ASSERT( !g_called.smethod ); // check that it was disconnected
+    CPPUNIT_ASSERT( !g_called.smethod );
 
     handler.Connect( 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
     handler.Disconnect( 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
 
     handler.Connect( 0, 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
     handler.Disconnect( 0, 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
 
     handler.Connect( 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
     handler.Disconnect( 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
 
     handler.Connect( 0, 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
     handler.Disconnect( 0, 0, EVT_MYEVENT, &MyHandler::StaticOnMyEvent );
+}
 
 
+void EvtHandlerTestCase::ConnectFunctor()
+{
+    // generalized functor tests
+    MyFunctor functor;
 
 
+    handler.Connect( EVT_MYEVENT, functor );
+    g_called.Reset();
+    handler.ProcessEvent(e);
+    CPPUNIT_ASSERT( g_called.functor );
+    handler.Disconnect( EVT_MYEVENT, functor );
+    g_called.Reset();
+    handler.ProcessEvent(e);
+    CPPUNIT_ASSERT( !g_called.functor );
 
 
-    handler.Connect( EVT_MYEVENT, &MyHandler::OnMyEvent );
-    handler.Connect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent );
-    handler.Connect( 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent );
+    handler.Connect( 0, EVT_MYEVENT, functor );
+    handler.Disconnect( 0, EVT_MYEVENT, functor );
+
+    handler.Connect( 0, 0, EVT_MYEVENT, functor );
+    handler.Disconnect( 0, 0, EVT_MYEVENT, functor );
+}
 
 
+void EvtHandlerTestCase::ConnectMethod()
+{
+    // class method tests
+    handler.Connect( EVT_MYEVENT, &MyHandler::OnMyEvent );
+    g_called.Reset();
+    handler.ProcessEvent(e);
+    CPPUNIT_ASSERT( g_called.method );
     handler.Disconnect( EVT_MYEVENT, &MyHandler::OnMyEvent );
     handler.Disconnect( EVT_MYEVENT, &MyHandler::OnMyEvent );
-    handler.Disconnect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent );
-    handler.Disconnect( 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent );
+    g_called.Reset();
+    handler.ProcessEvent(e);
+    CPPUNIT_ASSERT( !g_called.method );
 
 
+    handler.Connect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent );
+    handler.Disconnect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent );
 
 
+    handler.Connect( 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent );
+    handler.Disconnect( 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent );
+}
 
 
+void EvtHandlerTestCase::ConnectMethodWithSink()
+{
     handler.Connect( EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     handler.Connect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     handler.Connect( 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     handler.Connect( EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     handler.Connect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     handler.Connect( 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
@@ -178,8 +313,25 @@ void EvtHandlerTestCase::TestConnectCompilation()
     handler.Disconnect( EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     handler.Disconnect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     handler.Disconnect( 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     handler.Disconnect( EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     handler.Disconnect( 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     handler.Disconnect( 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
+}
+
+void EvtHandlerTestCase::ConnectNonHandler()
+{
+    // class method tests for class not derived from wxEvtHandler
+    MySink sink;
 
 
+    handler.Connect( EVT_MYEVENT, &MySink::OnMyEvent, NULL, &sink );
+    g_called.Reset();
+    handler.ProcessEvent(e);
+    CPPUNIT_ASSERT( g_called.method );
+    handler.Disconnect( EVT_MYEVENT, &MySink::OnMyEvent, NULL, &sink );
+    g_called.Reset();
+    handler.ProcessEvent(e);
+    CPPUNIT_ASSERT( !g_called.method );
+}
 
 
+void EvtHandlerTestCase::StaticConnect()
+{
     wxEvtHandler::Connect( &handler, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     wxEvtHandler::Connect( &handler, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     wxEvtHandler::Connect( &handler, 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     wxEvtHandler::Connect( &handler, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     wxEvtHandler::Connect( &handler, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     wxEvtHandler::Connect( &handler, 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
@@ -187,43 +339,17 @@ void EvtHandlerTestCase::TestConnectCompilation()
     wxEvtHandler::Disconnect( &handler, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     wxEvtHandler::Disconnect( &handler, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     wxEvtHandler::Disconnect( &handler, 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     wxEvtHandler::Disconnect( &handler, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     wxEvtHandler::Disconnect( &handler, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
     wxEvtHandler::Disconnect( &handler, 0, 0, EVT_MYEVENT, &MyHandler::OnMyEvent, NULL, &handler );
+}
 
 
-
-
-    MyFunctor functor;
-
-    handler.Connect( EVT_MYEVENT, functor );
-    handler.Connect( 0, EVT_MYEVENT, functor );
-    handler.Connect( 0, 0, EVT_MYEVENT, functor );
-
-    handler.Disconnect( EVT_MYEVENT, functor );
-    handler.Disconnect( 0, EVT_MYEVENT, functor );
-    handler.Disconnect( 0, 0, EVT_MYEVENT, functor );
-
+void EvtHandlerTestCase::InvalidConnect()
+{
     // these calls shouldn't compile but we unfortunately can't check this
     // automatically, you need to uncomment them manually and test that
     // compilation does indeed fail
     // these calls shouldn't compile but we unfortunately can't check this
     // automatically, you need to uncomment them manually and test that
     // compilation does indeed fail
-    //handler.Connect(EVT_MYEVENT, &MyHandler::OnAnotherEvent, NULL, &handler);
-#endif // !wxEVENTS_COMPATIBILITY_2_8
-}
-
-void EvtHandlerTestCase::TestEventFunctorCompare()
-{
-//#if !wxEVENTS_COMPATIBILITY_2_8
-//    MyHandler handler1;
-//    wxEventFunctor *connectFunctor = wxNewEventFunctor( EVT_MYEVENT, &MyHandler::OnMyEvent, &handler1 );
-//    wxEventFunctor *disconnectFunctor = wxNewEventFunctor( EVT_MYEVENT, &MyHandler::OnMyEvent, &handler1 );
-//    wxEventFunctor *nullFunctor = wxNewEventFunctor( EVT_MYEVENT, &MyHandler::OnMyEvent );
-//   
-//    CPPUNIT_ASSERT( connectFunctor->Matches( *disconnectFunctor ));
-//    CPPUNIT_ASSERT( disconnectFunctor->Matches( *connectFunctor ));
-//
-//    CPPUNIT_ASSERT( connectFunctor->Matches( *nullFunctor ));
-//    CPPUNIT_ASSERT( nullFunctor->Matches( *connectFunctor ));
-//
-//    CPPUNIT_ASSERT( disconnectFunctor->Matches( *nullFunctor ));
-//    CPPUNIT_ASSERT( nullFunctor->Matches( *disconnectFunctor ));
-//#endif
+    //handler.Connect(EVT_MYEVENT, GlobalOnAnotherEvent);
+    //IdleFunctor f; handler.Connect(EVT_MYEVENT, f);
+    //handler.Connect(EVT_MYEVENT, &MyHandler::StaticOnAnotherEvent);
+    //handler.Connect(EVT_MYEVENT, &MyHandler::OnAnotherEvent);
 }
 
 }
 
-
+#endif // !wxEVENTS_COMPATIBILITY_2_8