From 03f3617bf36573a7c368614191444364267ed718 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Mon, 12 Jan 2009 16:51:14 +0000
Subject: [PATCH] fix VC6 ICE; don't call the function which doesn't compare
 the objects operator==() (see #10000)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58049 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 include/wx/event.h   | 99 ++++++++++++++++++++++----------------------
 src/common/event.cpp | 24 +++++------
 2 files changed, 61 insertions(+), 62 deletions(-)

diff --git a/include/wx/event.h b/include/wx/event.h
index 6c77cf5467..a4d22914f7 100644
--- a/include/wx/event.h
+++ b/include/wx/event.h
@@ -199,9 +199,12 @@ class WXDLLIMPEXP_BASE wxEventFunctor
 public:
     virtual ~wxEventFunctor();
 
+    // this operator is used to actually invoke the event handler
     virtual void operator()(wxEvtHandler *, wxEvent &) = 0;
 
-    virtual bool operator==(const wxEventFunctor& other) 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; }
 
@@ -225,13 +228,12 @@ public:
         (realHandler->*m_method)(event);
     }
 
-    virtual bool operator==(const wxEventFunctor& other) const
+    virtual bool Matches(const wxEventFunctor& other) const
     {
         wxEvtHandler * const handler = other.GetHandler();
-        const wxObjectEventFunction method = other.GetMethod();
 
         return (m_handler == handler || !handler) &&
-               (m_method == method || !method);
+               (m_method == other.GetMethod());
     }
 
     virtual wxEvtHandler *GetHandler() const { return m_handler; }
@@ -242,6 +244,24 @@ private:
     wxObjectEventFunction m_method;
 };
 
+// Create a functor for the legacy events: handler can be NULL 
+
+inline wxObjectEventFunctor *
+wxNewEventFunctor(wxEventType WXUNUSED(evtType),
+                  wxObjectEventFunction method,
+                  wxEvtHandler *handler)
+{
+    return new wxObjectEventFunctor(method, handler);
+}
+
+inline wxObjectEventFunctor
+wxConstructEventFunctor(wxEventType WXUNUSED(evtType),
+                        wxObjectEventFunction method,
+                        wxEvtHandler *handler)
+{
+    return wxObjectEventFunctor(method, handler);
+}
+
 #if !wxEVENTS_COMPATIBILITY_2_8
 
 template <typename EventType>
@@ -262,7 +282,7 @@ public:
         ( *m_handler )( dynamic_cast< typename EventType::CorrespondingEvent & >( event ));
     }
 
-    virtual bool operator == ( const wxEventFunctor &right ) const
+    virtual bool Matches( const wxEventFunctor &right ) const
     {
         wxEventFunctorFunction const &other = dynamic_cast< wxEventFunctorFunction const & >( right );
 
@@ -307,7 +327,7 @@ public:
         ( realHandler->*m_method )( dynamic_cast< typename EventType::CorrespondingEvent & >( event ));
     }
 
-    virtual bool operator == ( const wxEventFunctor &right ) const
+    virtual bool Matches( const wxEventFunctor &right ) const
     {
         wxEventFunctorMethod const &other = dynamic_cast< wxEventFunctorMethod const & >( right );
 
@@ -355,7 +375,7 @@ public:
         m_functor( dynamic_cast< typename EventType::CorrespondingEvent & >( event ));
     }
 
-    virtual bool operator == ( const wxEventFunctor &right ) const
+    virtual bool Matches( const wxEventFunctor &right ) const
     {
         wxEventFunctorAdapter const &other = dynamic_cast< wxEventFunctorAdapter const & >( right );
 
@@ -366,28 +386,6 @@ private:
     Functor m_functor;
 };
 
-#endif // wxEVENTS_COMPATIBILITY_2_8
-
-// Create a functor for the legacy events:
-
-inline wxObjectEventFunctor *
-wxNewEventFunctor(wxEventType WXUNUSED(evtType),
-                  wxObjectEventFunction method,
-                  wxEvtHandler *handler = NULL)
-{
-    return new wxObjectEventFunctor(method, handler);
-}
-
-inline wxObjectEventFunctor
-wxConstructEventFunctor(wxEventType WXUNUSED(evtType),
-                        wxObjectEventFunction method,
-                        wxEvtHandler *handler = NULL)
-{
-    return wxObjectEventFunctor(method, handler);
-}
-
-#if !wxEVENTS_COMPATIBILITY_2_8
-
 //
 // Create functors for the templatized events (needed in wxEvtHandler::Connect):
 //
@@ -1495,7 +1493,7 @@ private:
 class WXDLLIMPEXP_CORE wxEraseEvent : public wxEvent
 {
 public:
-    wxEraseEvent(int Id = 0, wxDC *dc = (wxDC *) NULL)
+    wxEraseEvent(int Id = 0, wxDC *dc = NULL)
         : wxEvent(Id, wxEVT_ERASE_BACKGROUND),
           m_dc(dc)
         { }
@@ -1890,7 +1888,7 @@ public:
 
     wxDropFilesEvent(wxEventType type = wxEVT_NULL,
                      int noFiles = 0,
-                     wxString *files = (wxString *) NULL)
+                     wxString *files = NULL)
         : wxEvent(0, type),
           m_noFiles(noFiles),
           m_pos(),
@@ -2123,7 +2121,7 @@ class WXDLLIMPEXP_CORE wxPaletteChangedEvent : public wxEvent
 public:
     wxPaletteChangedEvent(wxWindowID winid = 0)
         : wxEvent(winid, wxEVT_PALETTE_CHANGED),
-          m_changedWindow((wxWindow *) NULL)
+          m_changedWindow(NULL)
         { }
 
     wxPaletteChangedEvent(const wxPaletteChangedEvent& event)
@@ -2184,7 +2182,7 @@ public:
     wxNavigationKeyEvent()
         : wxEvent(0, wxEVT_NAVIGATION_KEY),
           m_flags(IsForward | FromTab),    // defaults are for TAB
-          m_focus((wxWindow *)NULL)
+          m_focus(NULL)
         {
             m_propagationLevel = wxEVENT_PROPAGATE_NONE;
         }
@@ -2695,8 +2693,8 @@ public:
                  int lastId,
                  wxEventType eventType,
                  wxObjectEventFunction func,
-                 wxObject *userData = (wxObject *) NULL,
-                 wxEvtHandler *eventSink = (wxEvtHandler *) NULL)
+                 wxObject *userData = NULL,
+                 wxEvtHandler *eventSink = NULL)
     {
         wxObjectEventFunctor *functor = wxNewEventFunctor( eventType, func, eventSink );
 
@@ -2707,23 +2705,23 @@ public:
     void Connect(int winid,
                  wxEventType eventType,
                  wxObjectEventFunction func,
-                 wxObject *userData = (wxObject *) NULL,
-                 wxEvtHandler *eventSink = (wxEvtHandler *) NULL)
+                 wxObject *userData = NULL,
+                 wxEvtHandler *eventSink = NULL)
         { Connect(winid, wxID_ANY, eventType, func, userData, eventSink); }
 
     // Even more convenient: without id (same as using id of wxID_ANY)
     void Connect(wxEventType eventType,
                  wxObjectEventFunction func,
-                 wxObject *userData = (wxObject *) NULL,
-                 wxEvtHandler *eventSink = (wxEvtHandler *) NULL)
+                 wxObject *userData = NULL,
+                 wxEvtHandler *eventSink = NULL)
         { Connect(wxID_ANY, wxID_ANY, eventType, func, userData, eventSink); }
 
     bool Disconnect(int winid,
                     int lastId,
                     wxEventType eventType,
                     wxObjectEventFunction func = NULL,
-                    wxObject *userData = (wxObject *) NULL,
-                    wxEvtHandler *eventSink = (wxEvtHandler *) NULL)
+                    wxObject *userData = NULL,
+                    wxEvtHandler *eventSink = NULL)
     {
         wxObjectEventFunctor functor = wxConstructEventFunctor( eventType, func, eventSink );
 
@@ -2733,14 +2731,14 @@ public:
     bool Disconnect(int winid = wxID_ANY,
                     wxEventType eventType = wxEVT_NULL,
                     wxObjectEventFunction func = NULL,
-                    wxObject *userData = (wxObject *) NULL,
-                    wxEvtHandler *eventSink = (wxEvtHandler *) NULL)
+                    wxObject *userData = NULL,
+                    wxEvtHandler *eventSink = NULL)
         { return Disconnect(winid, wxID_ANY, eventType, func, userData, eventSink); }
 
     bool Disconnect(wxEventType eventType,
                     wxObjectEventFunction func,
-                    wxObject *userData = (wxObject *) NULL,
-                    wxEvtHandler *eventSink = (wxEvtHandler *) NULL)
+                    wxObject *userData = NULL,
+                    wxEvtHandler *eventSink = NULL)
         { return Disconnect(wxID_ANY, eventType, func, userData, eventSink); }
 
 
@@ -3059,14 +3057,15 @@ public:
     // implementation from now on
     // --------------------------
 
-    // check if the given event table entry matches this event and call the
-    // handler if it does
+    // check if the given event table entry matches this event by id (the check
+    // for the event type should be done by caller) and call the handler if it
+    // does
     //
     // return true if the event was processed, false otherwise (no match or the
     // handler decided to skip the event)
-    static bool ProcessEventIfMatches(const wxEventTableEntryBase& tableEntry,
-                                      wxEvtHandler *handler,
-                                      wxEvent& event);
+    static bool ProcessEventIfMatchesId(const wxEventTableEntryBase& tableEntry,
+                                        wxEvtHandler *handler,
+                                        wxEvent& event);
 
     virtual bool SearchEventTable(wxEventTable& table, wxEvent& event);
     bool SearchDynamicEventTable( wxEvent& event );
diff --git a/src/common/event.cpp b/src/common/event.cpp
index 9eb05a0bbf..700084e9cc 100644
--- a/src/common/event.cpp
+++ b/src/common/event.cpp
@@ -895,11 +895,9 @@ bool wxEventHashTable::HandleEvent(wxEvent &event, wxEvtHandler *self)
         const size_t count = eventEntryTable.GetCount();
         for (size_t n = 0; n < count; n++)
         {
-            if ( wxEvtHandler::
-                    ProcessEventIfMatches(*eventEntryTable[n], self, event) )
-            {
+            const wxEventTableEntry& entry = *eventEntryTable[n];
+            if ( wxEvtHandler::ProcessEventIfMatchesId(entry, self, event) )
                 return true;
-            }
         }
     }
 
@@ -1198,9 +1196,9 @@ void wxEvtHandler::ProcessPendingEvents()
  * Event table stuff
  */
 /* static */ bool
-wxEvtHandler::ProcessEventIfMatches(const wxEventTableEntryBase& entry,
-                                    wxEvtHandler *handler,
-                                    wxEvent& event)
+wxEvtHandler::ProcessEventIfMatchesId(const wxEventTableEntryBase& entry,
+                                      wxEvtHandler *handler,
+                                      wxEvent& event)
 {
     int tableId1 = entry.m_id,
         tableId2 = entry.m_lastId;
@@ -1358,7 +1356,7 @@ bool wxEvtHandler::SearchEventTable(wxEventTable& table, wxEvent& event)
         const wxEventTableEntry& entry = table.entries[i];
         if ( eventType == entry.m_eventType )
         {
-            if ( ProcessEventIfMatches(entry, this, event) )
+            if ( ProcessEventIfMatchesId(entry, this, event) )
                 return true;
         }
     }
@@ -1419,7 +1417,7 @@ wxEvtHandler::Unsubscribe(int id,
         if ((entry->m_id == id) &&
             ((entry->m_lastId == lastId) || (lastId == wxID_ANY)) &&
             ((entry->m_eventType == eventType) || (eventType == wxEVT_NULL)) &&
-            (*entry->m_fn == func) &&
+            entry->m_fn->Matches(func) &&
             ((entry->m_callbackUserData == userData) || !userData))
         {
             delete entry->m_callbackUserData;
@@ -1446,10 +1444,12 @@ bool wxEvtHandler::SearchDynamicEventTable( wxEvent& event )
         // call Disconnect() invalidating the current node
         node = node->GetNext();
 
-        if ((event.GetEventType() == entry->m_eventType) && (entry->m_fn != 0))
+        if ( event.GetEventType() == entry->m_eventType )
         {
-            wxEvtHandler *handler = entry->m_fn->GetHandler() ? entry->m_fn->GetHandler() : this;
-            if ( ProcessEventIfMatches(*entry, handler, event) )
+            wxEvtHandler *handler = entry->m_fn->GetHandler();
+            if ( !handler )
+               handler = this;
+            if ( ProcessEventIfMatchesId(*entry, handler, event) )
                 return true;
         }
     }
-- 
2.47.2