]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/xtistrm.cpp
move code ignoring VK_SPACE and VK_RETURN WM_CHAR messages to MSWDefWindowProc()...
[wxWidgets.git] / src / common / xtistrm.cpp
index 490c1493bd64d2f81ed6928580e0d912b5c36fcb..03d974f25ebfd8c34c24a652aa9be94290dc70f8 100644 (file)
 #endif
 
 #include "wx/tokenzr.h"
-#include "wx/xtistrm.h"
 #include "wx/txtstrm.h"
 #include "wx/event.h"
 
 #if wxUSE_EXTENDED_RTTI
 
+#include "wx/xtistrm.h"
+
 #include "wx/beforestd.h"
 #include <map>
 #include <vector>
@@ -151,26 +152,34 @@ void wxWriter::WriteAllProperties( const wxObject * obj , const wxClassInfo* ci
     {
         wxString name = ci->GetCreateParamName(i) ;
         const wxPropertyInfo* prop = map.find(name)->second ;
-        wxASSERT_MSG( prop , wxT("Create Parameter not found in declared RTTI Parameters") ) ;
-        WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
+        if ( prop )
+        {
+            WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
+        }
+        else
+        {
+            wxLogError( _("Create Parameter not found in declared RTTI Parameters") ) ;
+        }
         map.erase( name ) ;
     }
-
-    for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter )
-    {
-        const wxPropertyInfo* prop = iter->second ;
-        if ( prop->GetFlags() & wxPROP_OBJECT_GRAPH )
+    { // Extra block for broken compilers
+        for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter )
         {
-            WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
+            const wxPropertyInfo* prop = iter->second ;
+            if ( prop->GetFlags() & wxPROP_OBJECT_GRAPH )
+            {
+                WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
+            }
         }
     }
-
-    for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter )
-    {
-        const wxPropertyInfo* prop = iter->second ;
-        if ( !(prop->GetFlags() & wxPROP_OBJECT_GRAPH) )
+    { // Extra block for broken compilers
+        for( wxPropertyInfoMap::iterator iter = map.begin() ; iter != map.end() ; ++iter )
         {
-            WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
+            const wxPropertyInfo* prop = iter->second ;
+            if ( !(prop->GetFlags() & wxPROP_OBJECT_GRAPH) )
+            {
+                WriteOneProperty( obj , prop->GetDeclaringClass() , prop , persister , data ) ;
+            }
         }
     }
 }
@@ -185,7 +194,6 @@ void wxWriter::WriteOneProperty( const wxObject *obj , const wxClassInfo* ci , c
     if ( dynobj && (dynamic_cast<const wxDynamicClassInfo*>(ci) == NULL) )
         obj = dynobj->GetSuperClassInstance() ;
 
-    DoBeginWriteProperty( pi ) ;
     if ( pi->GetTypeInfo()->GetKind() == wxT_COLLECTION )
     {
         wxxVariantArray data ;
@@ -193,9 +201,12 @@ void wxWriter::WriteOneProperty( const wxObject *obj , const wxClassInfo* ci , c
         const wxTypeInfo * elementType = dynamic_cast< const wxCollectionTypeInfo* >( pi->GetTypeInfo() )->GetElementType() ;
         for ( size_t i = 0 ; i < data.GetCount() ; ++i )
         {
+            if ( i == 0 )
+                DoBeginWriteProperty( pi ) ;
+
             DoBeginWriteElement() ;
             wxxVariant value = data[i] ;
-            if ( persister->BeforeWriteProperty( this , pi , value ) )
+            if ( persister->BeforeWriteProperty( this , obj, pi , value ) )
             {
                 const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( elementType ) ;
                 if ( cti )
@@ -211,8 +222,10 @@ void wxWriter::WriteOneProperty( const wxObject *obj , const wxClassInfo* ci , c
                 }
             }
             DoEndWriteElement() ;
-        }
-    }
+            if ( i == data.GetCount() - 1 )
+                 DoEndWriteProperty( pi ) ;
+       }
+   }
     else
     {
         const wxDelegateTypeInfo* dti = dynamic_cast< const wxDelegateTypeInfo* > ( pi->GetTypeInfo() ) ;
@@ -222,46 +235,94 @@ void wxWriter::WriteOneProperty( const wxObject *obj , const wxClassInfo* ci , c
             const wxHandlerInfo *handler = NULL ;
 
             const wxEvtHandler * evSource = dynamic_cast<const wxEvtHandler *>(obj) ;
-            wxASSERT_MSG( evSource , wxT("Illegal Object Class (Non-wxEvtHandler) as Event Source") ) ;
-
-            FindConnectEntry( evSource , dti , sink , handler ) ;
-            if ( persister->BeforeWriteDelegate( this , obj , ci , pi , sink , handler ) )
+            if ( evSource )
             {
-                if ( sink != NULL && handler != NULL )
+                FindConnectEntry( evSource , dti , sink , handler ) ;
+                if ( persister->BeforeWriteDelegate( this , obj , ci , pi , sink , handler ) )
                 {
-                    wxASSERT_MSG( IsObjectKnown( sink ) , wxT("Streaming delegates for not already streamed objects not yet supported") ) ;
-                    DoWriteDelegate( obj , ci , pi , sink , GetObjectID( sink ) , sink->GetClassInfo() , handler ) ;
+                    if ( sink != NULL && handler != NULL )
+                    {
+                        DoBeginWriteProperty( pi ) ;
+                        if ( IsObjectKnown( sink ) )
+                        {
+                            DoWriteDelegate( obj , ci , pi , sink , GetObjectID( sink ) , sink->GetClassInfo() , handler ) ;
+                            DoEndWriteProperty( pi ) ;
+                        }
+                        else
+                        {
+                            wxLogError( _("Streaming delegates for not already streamed objects not yet supported") ) ;
+                        }
+                    }
                 }
             }
+            else
+            {
+                wxLogError(_("Illegal Object Class (Non-wxEvtHandler) as Event Source") ) ;
+            }
         }
         else
         {
             wxxVariant value ;
             pi->GetAccessor()->GetProperty(obj, value) ;
-            if ( persister->BeforeWriteProperty( this , pi , value ) )
+
+            // avoid streaming out void objects
+            if( value.IsEmpty() )
+                return ;
+
+            if ( pi->GetFlags() & wxPROP_ENUM_STORE_LONG )
+            {
+                const wxEnumTypeInfo *eti = dynamic_cast<const wxEnumTypeInfo*>( pi->GetTypeInfo() ) ;
+                if ( eti )
+                {
+                    eti->ConvertFromLong( value.wxTEMPLATED_MEMBER_CALL(Get , long) , value ) ;
+                }
+                else
+                {
+                    wxLogError( _("Type must have enum - long conversion") ) ;
+                }
+            }
+
+            // avoid streaming out default values
+            if ( pi->GetTypeInfo()->HasStringConverters() && !pi->GetDefaultValue().IsEmpty() )
             {
-                const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( pi->GetTypeInfo() ) ;
+                if ( value.GetAsString() == pi->GetDefaultValue().GetAsString() )
+                    return ;
+            }
+
+            // avoid streaming out null objects
+            const wxClassTypeInfo* cti = dynamic_cast< const wxClassTypeInfo* > ( pi->GetTypeInfo() ) ;
+
+            if ( cti && value.GetAsObject() == NULL )
+                return ;
+
+            if ( persister->BeforeWriteProperty( this , obj, pi , value ) )
+            {
+                DoBeginWriteProperty( pi ) ;
                 if ( cti )
                 {
                     const wxClassInfo* pci = cti->GetClassInfo() ;
                     wxObject *vobj = pci->VariantToInstance( value ) ;
-                    wxxVariantArray md ;
-                    WriteObject( vobj , (vobj ? vobj->GetClassInfo() : pci ) , persister , cti->GetKind()== wxT_OBJECT , md) ;
+                    if ( vobj && pi->GetTypeInfo()->HasStringConverters() )
+                    {
+                        wxString stringValue ;
+                        cti->ConvertToString( value , stringValue ) ;
+                        wxxVariant convertedValue(stringValue) ;
+                        DoWriteSimpleType( convertedValue ) ;
+                    }
+                    else
+                    {
+                        wxxVariantArray md ;
+                        WriteObject( vobj , (vobj ? vobj->GetClassInfo() : pci ) , persister , cti->GetKind()== wxT_OBJECT , md) ;
+                    }
                 }
                 else
                 {
-                    if ( pi->GetFlags() & wxPROP_ENUM_STORE_LONG )
-                    {
-                        const wxEnumTypeInfo *eti = dynamic_cast<const wxEnumTypeInfo*>( pi->GetTypeInfo() ) ;
-                        wxASSERT_MSG( eti , wxT("Type must have enum - long conversion") ) ;
-                        eti->ConvertFromLong( value.Get<long>() , value ) ;
-                    }
                     DoWriteSimpleType( value ) ;
                 }
+                DoEndWriteProperty( pi ) ;
             }
         }
     }
-    DoEndWriteProperty( pi ) ;
 }
 
 int wxWriter::GetObjectID(const wxObject *obj)
@@ -299,18 +360,41 @@ wxReader::~wxReader()
 
 wxClassInfo* wxReader::GetObjectClassInfo(int objectID)
 {
-    assert( m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end() );
+    if ( objectID == wxNullObjectID || objectID == wxInvalidObjectID )
+    {
+        wxLogError( _("Invalid or Null Object ID passed to GetObjectClassInfo" ) ) ;
+        return NULL ;
+    }
+    if ( m_data->m_classInfos.find(objectID) == m_data->m_classInfos.end() )
+    {
+        wxLogError( _("Unknown Object passed to GetObjectClassInfo" ) ) ;
+        return NULL ;
+    }
     return m_data->m_classInfos[objectID] ;
 }
 
 void wxReader::SetObjectClassInfo(int objectID, wxClassInfo *classInfo )
 {
-    assert(  m_data->m_classInfos.find(objectID) == m_data->m_classInfos.end()  ) ;
+    if ( objectID == wxNullObjectID || objectID == wxInvalidObjectID )
+    {
+        wxLogError( _("Invalid or Null Object ID passed to GetObjectClassInfo" ) ) ;
+        return ;
+    }
+    if ( m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end() )
+    {
+        wxLogError( _("Already Registered Object passed to SetObjectClassInfo" ) ) ;
+        return ;
+    }
     m_data->m_classInfos[objectID] = classInfo ;
 }
 
 bool wxReader::HasObjectClassInfo( int objectID )
 {
+    if ( objectID == wxNullObjectID || objectID == wxInvalidObjectID )
+    {
+        wxLogError( _("Invalid or Null Object ID passed to HasObjectClassInfo" ) ) ;
+        return NULL ;
+    }
     return m_data->m_classInfos.find(objectID) != m_data->m_classInfos.end() ;
 }
 
@@ -336,15 +420,23 @@ struct wxRuntimeDepersister::wxRuntimeDepersisterInternal
 
     void SetObject(int objectID, wxObject *obj )
     {
-        assert(  m_objects.find(objectID) == m_objects.end()  ) ;
+        if ( m_objects.find(objectID) != m_objects.end() )
+        {
+            wxLogError( _("Passing a already registered object to SetObject") ) ;
+            return  ;
+        }
         m_objects[objectID] = obj ;
     }
     wxObject* GetObject( int objectID )
     {
         if ( objectID == wxNullObjectID )
             return NULL ;
+        if ( m_objects.find(objectID) == m_objects.end() )
+        {
+            wxLogError( _("Passing an unkown object to GetObject") ) ;
+            return NULL ;
+        }
 
-        assert(  m_objects.find(objectID) != m_objects.end()  ) ;
         return m_objects[objectID] ;
     }
 } ;
@@ -396,6 +488,36 @@ void wxRuntimeDepersister::CreateObject(int objectID,
     classInfo->Create(o, paramCount, params);
 }
 
+void wxRuntimeDepersister::ConstructObject(int objectID,
+                                        const wxClassInfo *classInfo,
+                                        int paramCount,
+                                        wxxVariant *params,
+                                        int *objectIdValues,
+                                        const wxClassInfo **objectClassInfos ,
+                                        wxxVariantArray &WXUNUSED(metadata))
+{
+    wxObject *o;
+    for ( int i = 0 ; i < paramCount ; ++i )
+    {
+        if ( objectIdValues[i] != wxInvalidObjectID )
+        {
+            wxObject *o;
+            o = m_data->GetObject(objectIdValues[i]);
+            // if this is a dynamic object and we are asked for another class
+            // than wxDynamicObject we cast it down manually.
+            wxDynamicObject *dyno = dynamic_cast< wxDynamicObject * > (o) ;
+            if ( dyno!=NULL && (objectClassInfos[i] != dyno->GetClassInfo()) )
+            {
+                o = dyno->GetSuperClassInstance() ;
+            }
+            params[i] = objectClassInfos[i]->InstanceToVariant(o) ;
+        }
+    }
+    o = classInfo->ConstructObject(paramCount, params);
+    m_data->SetObject(objectID, o);
+}
+
+
 void wxRuntimeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo))
 {
     wxObject *o;
@@ -435,7 +557,7 @@ void wxRuntimeDepersister::SetPropertyAsObject(int objectID,
 
 void wxRuntimeDepersister::SetConnect(int eventSourceObjectID,
                                       const wxClassInfo *WXUNUSED(eventSourceClassInfo),
-                                      const wxDelegateTypeInfo *delegateInfo ,
+                                      const wxPropertyInfo *delegateInfo ,
                                       const wxClassInfo *WXUNUSED(eventSinkClassInfo) ,
                                       const wxHandlerInfo* handlerInfo ,
                                       int eventSinkObjectID )
@@ -445,9 +567,22 @@ void wxRuntimeDepersister::SetConnect(int eventSourceObjectID,
 
     if ( ehsource && ehsink )
     {
-        ehsource->Connect( -1 , delegateInfo->GetEventType() ,
-            handlerInfo->GetEventFunction() , NULL /*user data*/ ,
-            ehsink ) ;
+        const wxDelegateTypeInfo *delegateTypeInfo = dynamic_cast<const wxDelegateTypeInfo*>(delegateInfo->GetTypeInfo());
+        if( delegateTypeInfo && delegateTypeInfo->GetLastEventType() == -1 )
+        {
+            ehsource->Connect( -1 , delegateTypeInfo->GetEventType() ,
+                handlerInfo->GetEventFunction() , NULL /*user data*/ ,
+                ehsink ) ;
+        }
+        else
+        {
+            for ( wxEventType iter = delegateTypeInfo->GetEventType() ; iter <= delegateTypeInfo->GetLastEventType() ; ++iter )
+            {
+                ehsource->Connect( -1 , iter ,
+                    handlerInfo->GetEventFunction() , NULL /*user data*/ ,
+                    ehsink ) ;
+            }
+        }
     }
 }
 
@@ -495,19 +630,32 @@ void wxRuntimeDepersister::AddToPropertyCollectionAsObject(int objectID,
 
 struct wxCodeDepersister::wxCodeDepersisterInternal
 {
+#if wxUSE_UNICODE
+    map<int,wstring> m_objectNames ;
+#else
     map<int,string> m_objectNames ;
+#endif
 
     void SetObjectName(int objectID, const wxString &name )
     {
-        assert(  m_objectNames.find(objectID) == m_objectNames.end()  ) ;
-        m_objectNames[objectID] = (const char *)name;
+        if ( m_objectNames.find(objectID) != m_objectNames.end() )
+        {
+            wxLogError( _("Passing a already registered object to SetObjectName") ) ;
+            return  ;
+        }
+        m_objectNames[objectID] = (const wxChar *)name;
     }
+
     wxString GetObjectName( int objectID )
     {
         if ( objectID == wxNullObjectID )
-            return "NULL" ;
+            return wxT("NULL") ;
 
-        assert(  m_objectNames.find(objectID) != m_objectNames.end()  ) ;
+        if ( m_objectNames.find(objectID) == m_objectNames.end() )
+        {
+            wxLogError( _("Passing an unkown object to GetObject") ) ;
+            return wxEmptyString ;
+        }
         return wxString( m_objectNames[objectID].c_str() ) ;
     }
 } ;
@@ -526,8 +674,8 @@ wxCodeDepersister::~wxCodeDepersister()
 void wxCodeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo ,
                                        wxxVariantArray &WXUNUSED(metadata))
 {
-    wxString objectName = wxString::Format( "LocalObject_%d" , objectID ) ;
-    m_fp->WriteString( wxString::Format( "\t%s *%s = new %s;\n",
+    wxString objectName = wxString::Format( wxT("LocalObject_%d") , objectID ) ;
+    m_fp->WriteString( wxString::Format( wxT("\t%s *%s = new %s;\n"),
         classInfo->GetClassName(),
         objectName.c_str(),
         classInfo->GetClassName()) );
@@ -536,7 +684,7 @@ void wxCodeDepersister::AllocateObject(int objectID, wxClassInfo *classInfo ,
 
 void wxCodeDepersister::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo))
 {
-    m_fp->WriteString( wxString::Format( "\tdelete %s;\n",
+    m_fp->WriteString( wxString::Format( wxT("\tdelete %s;\n"),
         m_data->GetObjectName( objectID).c_str() ) );
 }
 
@@ -547,16 +695,22 @@ wxString wxCodeDepersister::ValueAsCode( const wxxVariant &param )
     if ( type->GetKind() == wxT_CUSTOM )
     {
         const wxCustomTypeInfo* cti = dynamic_cast<const wxCustomTypeInfo*>(type) ;
-        wxASSERT_MSG( cti , wxT("Internal error, illegal wxCustomTypeInfo") ) ;
-        value.Printf( "%s(%s)",cti->GetTypeName().c_str(),param.GetAsString().c_str() );
+        if ( cti )
+        {
+            value.Printf( wxT("%s(%s)"), cti->GetTypeName().c_str(),param.GetAsString().c_str() );
+        }
+        else
+        {
+            wxLogError ( _("Internal error, illegal wxCustomTypeInfo") ) ;
+        }
     }
     else if ( type->GetKind() == wxT_STRING )
     {
-        value.Printf( "\"%s\"",param.GetAsString().c_str() );
+        value.Printf( wxT("\"%s\""),param.GetAsString().c_str() );
     }
     else
     {
-        value.Printf( "%s", param.GetAsString().c_str() );
+        value.Printf( wxT("%s"), param.GetAsString().c_str() );
     }
     return value ;
 }
@@ -571,19 +725,50 @@ void wxCodeDepersister::CreateObject(int objectID,
                                      )
 {
     int i;
-    m_fp->WriteString( wxString::Format( "\t%s->Create(", m_data->GetObjectName(objectID).c_str() ) );
+    m_fp->WriteString( wxString::Format( wxT("\t%s->Create("), m_data->GetObjectName(objectID).c_str() ) );
+    for (i = 0; i < paramCount; i++)
+    {
+        if ( objectIDValues[i] != wxInvalidObjectID )
+            m_fp->WriteString( wxString::Format( wxT("%s"), m_data->GetObjectName( objectIDValues[i] ).c_str() ) );
+        else
+        {
+            m_fp->WriteString( wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) );
+        }
+        if (i < paramCount - 1)
+            m_fp->WriteString( wxT(", "));
+    }
+    m_fp->WriteString( wxT(");\n") );
+}
+
+void wxCodeDepersister::ConstructObject(int objectID,
+                                     const wxClassInfo *classInfo,
+                                     int paramCount,
+                                     wxxVariant *params,
+                                     int *objectIDValues,
+                                     const wxClassInfo **WXUNUSED(objectClassInfos) ,
+                                     wxxVariantArray &WXUNUSED(metadata)
+                                     )
+{
+    wxString objectName = wxString::Format( wxT("LocalObject_%d") , objectID ) ;
+    m_fp->WriteString( wxString::Format( wxT("\t%s *%s = new %s("),
+        classInfo->GetClassName(),
+        objectName.c_str(),
+        classInfo->GetClassName()) );
+    m_data->SetObjectName( objectID , objectName ) ;
+
+    int i;
     for (i = 0; i < paramCount; i++)
     {
         if ( objectIDValues[i] != wxInvalidObjectID )
-            m_fp->WriteString( wxString::Format( "%s", m_data->GetObjectName( objectIDValues[i] ).c_str() ) );
+            m_fp->WriteString( wxString::Format( wxT("%s"), m_data->GetObjectName( objectIDValues[i] ).c_str() ) );
         else
         {
-            m_fp->WriteString( wxString::Format( "%s", ValueAsCode(params[i]).c_str() ) );
+            m_fp->WriteString( wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) );
         }
         if (i < paramCount - 1)
-            m_fp->WriteString( ", ");
+            m_fp->WriteString( wxT(", ") );
     }
-    m_fp->WriteString( ");\n");
+    m_fp->WriteString( wxT(");\n") );
 }
 
 void wxCodeDepersister::SetProperty(int objectID,
@@ -591,7 +776,7 @@ void wxCodeDepersister::SetProperty(int objectID,
                                     const wxPropertyInfo* propertyInfo,
                                     const wxxVariant &value)
 {
-    m_fp->WriteString( wxString::Format( "\t%s->%s(%s);\n",
+    m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"),
         m_data->GetObjectName(objectID).c_str(),
         propertyInfo->GetAccessor()->GetSetterName().c_str(),
         ValueAsCode(value).c_str()) );
@@ -603,12 +788,12 @@ void wxCodeDepersister::SetPropertyAsObject(int objectID,
                                             int valueObjectId)
 {
     if ( propertyInfo->GetTypeInfo()->GetKind() == wxT_OBJECT )
-        m_fp->WriteString( wxString::Format( "\t%s->%s(*%s);\n",
+        m_fp->WriteString( wxString::Format( wxT("\t%s->%s(*%s);\n"),
         m_data->GetObjectName(objectID).c_str(),
         propertyInfo->GetAccessor()->GetSetterName().c_str(),
         m_data->GetObjectName( valueObjectId).c_str() ) );
     else
-        m_fp->WriteString( wxString::Format( "\t%s->%s(%s);\n",
+        m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"),
         m_data->GetObjectName(objectID).c_str(),
         propertyInfo->GetAccessor()->GetSetterName().c_str(),
         m_data->GetObjectName( valueObjectId).c_str() ) );
@@ -619,7 +804,7 @@ void wxCodeDepersister::AddToPropertyCollection( int objectID ,
                                                 const wxPropertyInfo* propertyInfo ,
                                                 const wxxVariant &value)
 {
-    m_fp->WriteString( wxString::Format( "\t%s->%s(%s);\n",
+    m_fp->WriteString( wxString::Format( wxT("\t%s->%s(%s);\n"),
         m_data->GetObjectName(objectID).c_str(),
         propertyInfo->GetAccessor()->GetAdderName().c_str(),
         ValueAsCode(value).c_str()) );
@@ -636,7 +821,7 @@ void wxCodeDepersister::AddToPropertyCollectionAsObject(int WXUNUSED(objectID),
 
 void wxCodeDepersister::SetConnect(int eventSourceObjectID,
                                    const wxClassInfo *WXUNUSED(eventSourceClassInfo),
-                                   const wxDelegateTypeInfo *delegateInfo ,
+                                   const wxPropertyInfo *delegateInfo ,
                                    const wxClassInfo *eventSinkClassInfo ,
                                    const wxHandlerInfo* handlerInfo ,
                                    int eventSinkObjectID )
@@ -644,11 +829,19 @@ void wxCodeDepersister::SetConnect(int eventSourceObjectID,
     wxString ehsource = m_data->GetObjectName( eventSourceObjectID ) ;
     wxString ehsink = m_data->GetObjectName(eventSinkObjectID) ;
     wxString ehsinkClass = eventSinkClassInfo->GetClassName() ;
-    int eventType = delegateInfo->GetEventType() ;
-    wxString handlerName = handlerInfo->GetName() ;
+    const wxDelegateTypeInfo *delegateTypeInfo = dynamic_cast<const wxDelegateTypeInfo*>(delegateInfo->GetTypeInfo());
+    if ( delegateTypeInfo )
+    {
+        int eventType = delegateTypeInfo->GetEventType() ;
+        wxString handlerName = handlerInfo->GetName() ;
 
-    m_fp->WriteString( wxString::Format(  "\t%s->Connect( %s->GetId() , %d , (wxObjectEventFunction)(wxEventFunction) & %s::%s , NULL , %s ) ;" ,
-        ehsource.c_str() , ehsource.c_str() , eventType , ehsinkClass.c_str() , handlerName.c_str() , ehsink.c_str() ) );
+        m_fp->WriteString( wxString::Format(  wxT("\t%s->Connect( %s->GetId() , %d , (wxObjectEventFunction)(wxEventFunction) & %s::%s , NULL , %s ) ;") ,
+            ehsource.c_str() , ehsource.c_str() , eventType , ehsinkClass.c_str() , handlerName.c_str() , ehsink.c_str() ) );
+    }
+    else
+    {
+        wxLogError(_("delegate has no type info"));
+    }
 }
 
 #include <wx/arrimpl.cpp>