]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/event.h
streamlining code
[wxWidgets.git] / include / wx / event.h
index 4711b4d353c6e6b012593f89a530d9b07273b786..cc363146e4051f840de527e51cf3f99ad39210a3 100644 (file)
@@ -126,10 +126,6 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType();
     #define wxDECLARE_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:
@@ -155,13 +151,13 @@ extern WXDLLIMPEXP_BASE wxEventType wxNewEventType();
     #define wxDECLARE_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
 
+// Try to cast the given event handler to the correct handler type:
+
+#define wxEVENT_HANDLER_CAST( functype, func ) \
+    ( wxObjectEventFunction )( wxEventFunction )wxStaticCastEvent( functype, &func )
+
 // Template which associates the correct event object with the event type
 
 #if !wxEVENTS_COMPATIBILITY_2_8
@@ -237,12 +233,7 @@ public:
         m_method = method;
     }
 
-    virtual void operator()(wxEvtHandler *handler, wxEvent& event)
-    {
-        wxEvtHandler * const realHandler = m_handler ? m_handler : handler;
-
-        (realHandler->*m_method)(event);
-    }
+    virtual void operator()(wxEvtHandler *handler, wxEvent& event);
 
     virtual bool Matches(const wxEventFunctor& func) const
     {
@@ -390,7 +381,7 @@ struct HandlerImpl<T, A, false>
 // allowed to handle different events in the same handler taking wxEvent&, for
 // example
 template
-  <typename EventTag, typename Class, typename EventArg, typename ObjClass>
+  <typename EventTag, typename Class, typename EventArg, typename EventHandler>
 class wxEventFunctorMethod
     : public wxEventFunctor,
       private wxPrivate::HandlerImpl
@@ -408,7 +399,7 @@ public:
     typedef typename wxPrivate::EventClassOf<EventTag>::type EventClass;
 
 
-    wxEventFunctorMethod(void (Class::*method)(EventArg&), ObjClass *handler)
+    wxEventFunctorMethod(void (Class::*method)(EventArg&), EventHandler *handler)
     {
         wxASSERT_MSG( handler || this->IsEvtHandler(),
                       "handlers defined in non-wxEvtHandler-derived classes "
@@ -466,17 +457,15 @@ public:
     }
 
 private:
-    ObjClass *m_handler;
+    EventHandler *m_handler;
     void (Class::*m_method)(EventArg&);
 };
 
 
-//
 // Create functors for the templatized events, either allocated on the heap for
-// wxNewXXX() variants (this is needed in wxEvtHandler::Connect() to store them
+// wxNewXXX() variants (this is needed in wxEvtHandler::Bind<>() 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)
+// is enough for Unbind<>() and we avoid unnecessary heap allocation like this).
 
 
 // Create functors wrapping other functors (including functions):
@@ -497,29 +486,29 @@ wxMakeEventFunctor(const EventTag&, Functor func)
 
 // Create functors for methods:
 template
-  <typename EventTag, typename Class, typename EventArg, typename ObjClass>
-inline wxEventFunctorMethod<EventTag, Class, EventArg, ObjClass> *
+  <typename EventTag, typename Class, typename EventArg, typename EventHandler>
+inline wxEventFunctorMethod<EventTag, Class, EventArg, EventHandler> *
 wxNewEventFunctor(const EventTag&,
                   void (Class::*method)(EventArg&),
-                  ObjClass *handler)
+                  EventHandler *handler)
 {
-    return new wxEventFunctorMethod<EventTag, Class, EventArg, ObjClass>(
+    return new wxEventFunctorMethod<EventTag, Class, EventArg, EventHandler>(
                 method, handler);
 }
 
 template
-    <typename EventTag, typename Class, typename EventArg, typename ObjClass>
-inline wxEventFunctorMethod<EventTag, Class, EventArg, ObjClass>
+    <typename EventTag, typename Class, typename EventArg, typename EventHandler>
+inline wxEventFunctorMethod<EventTag, Class, EventArg, EventHandler>
 wxMakeEventFunctor(const EventTag&,
                    void (Class::*method)(EventArg&),
-                   ObjClass *handler)
+                   EventHandler *handler)
 {
-    return wxEventFunctorMethod<EventTag, Class, EventArg, ObjClass>(
+    return wxEventFunctorMethod<EventTag, Class, EventArg, EventHandler>(
                 method, 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
+// macros: they don't specify the handler so EventHandler can't be deduced
 template <typename EventTag, typename Class, typename EventArg>
 inline wxEventFunctorMethod<EventTag, Class, EventArg, Class> *
 wxNewEventFunctor(const EventTag&, void (Class::*method)(EventArg&))
@@ -529,7 +518,7 @@ wxNewEventFunctor(const EventTag&, void (Class::*method)(EventArg&))
 }
 
 template
-    <typename EventTag, typename Class, typename EventArg, typename ObjClass>
+    <typename EventTag, typename Class, typename EventArg, typename EventHandler>
 inline wxEventFunctorMethod<EventTag, Class, EventArg, Class>
 wxMakeEventFunctor(const EventTag&, void (Class::*method)(EventArg&))
 {
@@ -607,6 +596,8 @@ wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_COMBOBOX_SELECTED, wxCo
 wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_TOOL_RCLICKED, wxCommandEvent);
 wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED, wxCommandEvent);
 wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_TOOL_ENTER, wxCommandEvent);
+wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_COMBOBOX_DROPDOWN, wxCommandEvent);
+wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_COMBOBOX_CLOSEUP, wxCommandEvent);
 
     // Thread events
 wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_THREAD, wxThreadEvent);
@@ -820,7 +811,8 @@ enum wxEventCategory
     // used in wxEventLoopBase::YieldFor to specify all event categories should be processed:
     wxEVT_CATEGORY_ALL =
         wxEVT_CATEGORY_UI|wxEVT_CATEGORY_USER_INPUT|wxEVT_CATEGORY_SOCKET| \
-        wxEVT_CATEGORY_TIMER|wxEVT_CATEGORY_THREAD
+        wxEVT_CATEGORY_TIMER|wxEVT_CATEGORY_THREAD|wxEVT_CATEGORY_UNKNOWN| \
+        wxEVT_CATEGORY_CLIPBOARD
 };
 
 /*
@@ -1110,6 +1102,14 @@ public:
         : wxCommandEvent(eventType, id)
         { }
 
+    wxThreadEvent(const wxThreadEvent& event)
+        : wxCommandEvent(event)
+    {
+        // make sure our string member (which uses COW, aka refcounting) is not
+        // shared by other wxString instances:
+        SetString(GetString().c_str());
+    }
+
     virtual wxEvent *Clone() const
     {
         wxThreadEvent* ev = new wxThreadEvent(*this);
@@ -1636,7 +1636,9 @@ private:
  wxEVT_PAINT_ICON
  */
 
-#if defined(__WXDEBUG__) && (defined(__WXMSW__) || defined(__WXPM__))
+#if wxDEBUG_LEVEL && (defined(__WXMSW__) || defined(__WXPM__))
+    #define wxHAS_PAINT_DEBUG
+
     // see comments in src/msw|os2/dcclient.cpp where g_isPainting is defined
     extern WXDLLIMPEXP_CORE int g_isPainting;
 #endif // debug
@@ -1647,15 +1649,15 @@ public:
     wxPaintEvent(int Id = 0)
         : wxEvent(Id, wxEVT_PAINT)
     {
-#if defined(__WXDEBUG__) && (defined(__WXMSW__) || defined(__WXPM__))
-        // set the internal flag for the duration of processing of WM_PAINT
+#ifdef wxHAS_PAINT_DEBUG
+        // set the internal flag for the duration of redrawing
         g_isPainting++;
 #endif // debug
     }
 
     // default copy ctor and dtor are normally fine, we only need them to keep
     // g_isPainting updated in debug build
-#if defined(__WXDEBUG__) && (defined(__WXMSW__) || defined(__WXPM__))
+#ifdef wxHAS_PAINT_DEBUG
     wxPaintEvent(const wxPaintEvent& event)
             : wxEvent(event)
     {
@@ -2425,7 +2427,7 @@ public:
 
     virtual wxEvent *Clone() const { return new wxNavigationKeyEvent(*this); }
 
-    enum
+    enum wxNavigationKeyEventFlags
     {
         IsBackward = 0x0000,
         IsForward = 0x0001,
@@ -2804,10 +2806,11 @@ public:
     // Clear table
     void Clear();
 
-#if defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING
-    // Clear all tables
+#if wxUSE_MEMORY_TRACING
+    // Clear all tables: only used to work around problems in memory tracing
+    // code
     static void ClearAll();
-#endif // __WXDEBUG__ && wxUSE_MEMORY_TRACING
+#endif // wxUSE_MEMORY_TRACING
 
 protected:
     // Init the hash table with the entries of the static event table.
@@ -2865,7 +2868,6 @@ public:
     // 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.
@@ -2901,9 +2903,11 @@ public:
     void ProcessPendingEvents();
         // NOTE: uses ProcessEvent()
 
+    void DeletePendingEvents();
+
 #if wxUSE_THREADS
     bool ProcessThreadEvent(const wxEvent& event);
-        // NOTE: uses AddPendingEvent()
+        // NOTE: uses AddPendingEvent(); call only from secondary threads
 #endif
 
 
@@ -2974,259 +2978,63 @@ public:
         { return Disconnect(wxID_ANY, eventType, func, userData, eventSink); }
 
 #if !wxEVENTS_COMPATIBILITY_2_8
-    // Event handling in functions (including generalized functors):
-
+    // Bind arbitrary functor (including just a function) to an event:
     template <typename EventTag, typename Functor>
-    void Connect(int winid,
-                 int lastId,
-                 const EventTag& eventType,
-                 Functor func)
+    void Bind(const EventTag& eventType,
+              Functor functor,
+              int winid = wxID_ANY,
+              int lastId = wxID_ANY,
+              wxObject *userData = NULL)
     {
         DoConnect(winid, lastId, eventType,
-                  wxNewEventFunctor(eventType, func));
-    }
-
-    template <typename EventTag, typename Functor>
-    void Connect(int winid, const EventTag& eventType, Functor func)
-        { Connect(winid, wxID_ANY, eventType, func); }
-
-    template <typename EventTag, typename Functor>
-    void Connect(const EventTag& eventType, Functor func)
-        { Connect(wxID_ANY, eventType, func); }
-
-
-    template <typename EventTag, typename Functor>
-    bool Disconnect(int winid,
-                    int lastId,
-                    const EventTag& eventType,
-                    Functor func)
-    {
-        return DoDisconnect(winid, lastId, eventType,
-                           wxMakeEventFunctor(eventType, func));
-    }
-
-    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.
-    //
-    // 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,
-                 const EventTag& eventType,
-                 void (Class::*func)(EventArg&),
-                 wxObject *userData = NULL)
-    {
-        DoConnect(winid, lastId, eventType,
-                  wxNewEventFunctor(eventType, func, static_cast<Class *>(this)),
+                  wxNewEventFunctor(eventType, functor),
                   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 EventTag, typename Class, typename EventArg>
-    void Connect(const EventTag& eventType,
-                 void (Class::*func)(EventArg&),
-                 wxObject *userData = NULL)
-        { Connect(wxID_ANY, eventType, func, userData); }
 
-
-    template <typename EventTag, typename Class, typename EventArg>
-    bool Disconnect(int winid,
-                    int lastId,
-                    const EventTag& eventType,
-                    void (Class::*func)(EventArg&),
-                    wxObject *userData = NULL)
+    template <typename EventTag, typename Functor>
+    bool Unbind(const EventTag& eventType,
+                Functor functor,
+                int winid = wxID_ANY,
+                int lastId = wxID_ANY,
+                wxObject *userData = NULL)
     {
         return DoDisconnect(winid, lastId, eventType,
-                            wxMakeEventFunctor(eventType, func,
-                                               static_cast<Class *>(this)),
+                            wxMakeEventFunctor(eventType, functor),
                             userData);
     }
 
-    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 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
+    // Bind a method of a class (called on the specified handler which must
+    // be convertible to this class) object to an event:
 
-    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)
+    template <typename EventTag, typename Class, typename EventArg, typename EventHandler>
+    void Bind(const EventTag &eventType,
+              void (Class::*method)(EventArg &),
+              EventHandler *handler,
+              int winid = wxID_ANY,
+              int lastId = wxID_ANY,
+              wxObject *userData = NULL)
     {
         DoConnect(winid, lastId, eventType,
-                  wxNewEventFunctor(eventType, func, eventSink),
+                  wxNewEventFunctor(eventType, method, handler),
                   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 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); }
-
-
-    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)
+    template <typename EventTag, typename Class, typename EventArg, typename EventHandler>
+    bool Unbind(const EventTag &eventType,
+                void (Class::*method)(EventArg&),
+                EventHandler *handler,
+                int winid = wxID_ANY,
+                int lastId = wxID_ANY,
+                wxObject *userData = NULL )
     {
         return DoDisconnect(winid, lastId, eventType,
-                            wxMakeEventFunctor(eventType, func, eventSink),
+                            wxMakeEventFunctor(eventType, method, handler),
                             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); }
-
-
-
-    // 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)
-    {
-        eventSrc->Connect(winid, lastId, eventType, func, userData, eventSink);
-    }
-
-    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 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);
-    }
-
-
-    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)
-    {
-        return eventSrc->Disconnect(winid, lastId, eventType, func,
-                                    userData, eventSink);
-    }
-
-    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
 
-
     wxList* GetDynamicEventTable() const { return m_dynamicEvents ; }
 
     // User data can be associated with each wxEvtHandler
@@ -3262,7 +3070,7 @@ public:
     //
     // It is meant to be called from ProcessEvent() only and is not virtual,
     // additional event handlers can be hooked into the normal event processing
-    // logic using TryValidator() hook.
+    // logic using TryBefore() and TryAfter() hooks.
     bool ProcessEventHere(wxEvent& event);
 
 
@@ -3285,21 +3093,25 @@ protected:
     // hooks for wxWindow used by ProcessEvent()
     // -----------------------------------------
 
-    // This one is called before trying our own event table to allow plugging
-    // in the validators.
-    //
-    // NB: This method is intentionally *not* inside wxUSE_VALIDATORS!
-    //     It is part of wxBase which doesn't use validators and the code
-    //     is compiled out when building wxBase w/o GUI classes, which affects
-    //     binary compatibility and wxBase library can't be used by GUI
-    //     ports.
-    virtual bool TryValidator(wxEvent& WXUNUSED(event)) { return false; }
+    // this one is called before trying our own event table to allow plugging
+    // in the event handlers overriding the default logic, this is used by e.g.
+    // validators.
+    virtual bool TryBefore(wxEvent& event);
 
     // this one is called after failing to find the event handle in our own
     // table to give a chance to the other windows to process it
     //
     // base class implementation passes the event to wxTheApp
-    virtual bool TryParent(wxEvent& event);
+    virtual bool TryAfter(wxEvent& event);
+
+#ifdef WXWIN_COMPATIBILITY_2_8
+    // deprecated method: override TryBefore() instead of this one
+    wxDEPRECATED_BUT_USED_INTERNALLY_INLINE(
+        virtual bool TryValidator(wxEvent& WXUNUSED(event)), return false; )
+
+    wxDEPRECATED_BUT_USED_INTERNALLY_INLINE(
+        virtual bool TryParent(wxEvent& event), return DoTryApp(event); )
+#endif // WXWIN_COMPATIBILITY_2_8
 
 
     static const wxEventTable sm_eventTable;
@@ -3344,13 +3156,16 @@ protected:
     virtual void *DoGetClientData() const;
 
     // Search tracker objects for event connection with this sink
-    wxEventConnectionRef *FindRefInTrackerList(wxEvtHandler *eventSink);
+    wxEventConnectionRef *FindRefInTrackerList(wxEvtHandler *handler);
 
 private:
+    // pass the event to wxTheApp instance, called from TryAfter()
+    bool DoTryApp(wxEvent& event);
+
     DECLARE_DYNAMIC_CLASS_NO_COPY(wxEvtHandler)
 };
 
-WX_DEFINE_EXPORTED_ARRAY_PTR(wxEvtHandler*, wxEvtHandlerArray);
+WX_DEFINE_ARRAY_WITH_DECL_PTR(wxEvtHandler *, wxEvtHandlerArray, class WXDLLIMPEXP_BASE);
 
 // ----------------------------------------------------------------------------
 // wxEventConnectionRef represents all connections between two event handlers
@@ -3401,6 +3216,13 @@ private:
     wxDECLARE_NO_ASSIGN_CLASS(wxEventConnectionRef);
 };
 
+inline void wxObjectEventFunctor::operator()(wxEvtHandler *handler, wxEvent& event)
+{
+    wxEvtHandler * const realHandler = m_handler ? m_handler : handler;
+
+    (realHandler->*m_method)(event);
+}
+
 // Post a message to the given event handler which will be processed during the
 // next event loop iteration.
 //
@@ -3932,6 +3754,8 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent&
 #define EVT_TOOL_RCLICKED_RANGE(id1, id2, func) wx__DECLARE_EVT2(wxEVT_COMMAND_TOOL_RCLICKED, id1, id2, wxCommandEventHandler(func))
 #define EVT_TOOL_ENTER(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_TOOL_ENTER, winid, wxCommandEventHandler(func))
 #define EVT_CHECKLISTBOX(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, winid, wxCommandEventHandler(func))
+#define EVT_COMBOBOX_DROPDOWN(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_COMBOBOX_DROPDOWN, winid, wxCommandEventHandler(func))
+#define EVT_COMBOBOX_CLOSEUP(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_COMBOBOX_CLOSEUP, winid, wxCommandEventHandler(func))
 
 // Generic command events
 #define EVT_COMMAND_LEFT_CLICK(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_LEFT_CLICK, winid, wxCommandEventHandler(func))
@@ -3985,6 +3809,41 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent&
 // Helper functions
 // ----------------------------------------------------------------------------
 
+// This is an ugly hack to allow the use of Bind() instead of Connect() inside
+// the library code if the library was built with support for it, here is how
+// it is used:
+//
+// class SomeEventHandlingClass : wxBIND_OR_CONNECT_HACK_BASE_CLASS
+//                                public SomeBaseClass
+// {
+// public:
+//     SomeEventHandlingClass(wxWindow *win)
+//     {
+//         // connect to the event for the given window
+//         wxBIND_OR_CONNECT_HACK(win, wxEVT_SOMETHING, wxSomeEventHandler,
+//                                SomeEventHandlingClass::OnSomeEvent, this);
+//     }
+//
+// private:
+//     void OnSomeEvent(wxSomeEvent&) { ... }
+// };
+//
+// This is *not* meant to be used by library users, it is only defined here
+// (and not in a private header) because the base class must be visible from
+// other public headers, please do NOT use this in your code, it will be
+// removed from future wx versions without warning.
+#if wxEVENTS_COMPATIBILITY_2_8
+    #define wxBIND_OR_CONNECT_HACK_BASE_CLASS public wxEvtHandler,
+    #define wxBIND_OR_CONNECT_HACK_ONLY_BASE_CLASS : public wxEvtHandler
+    #define wxBIND_OR_CONNECT_HACK(w, evt, handler, func, obj) \
+        win->Connect(evt, handler(func), NULL, obj)
+#else // wxEVENTS_COMPATIBILITY_2_8
+    #define wxBIND_OR_CONNECT_HACK_BASE_CLASS
+    #define wxBIND_OR_CONNECT_HACK_ONLY_BASE_CLASS
+    #define wxBIND_OR_CONNECT_HACK(w, evt, handler, func, obj) \
+        win->Bind(evt, &func, obj)
+#endif // wxEVENTS_COMPATIBILITY_2_8/!wxEVENTS_COMPATIBILITY_2_8
+
 #if wxUSE_GUI
 
 // Find a window with the focus, that is also a descendant of the given window.