1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: runtime metadata information (extended class info)
4 // Author: Stefan Csomor
5 // Modified by: Francesco Montorsi
8 // Copyright: (c) 1997 Julian Smart
9 // (c) 2003 Stefan Csomor
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
16 // We want to support properties, event sources and events sinks through
17 // explicit declarations, using templates and specialization to make the
18 // effort as painless as possible.
20 // This means we have the following domains :
22 // - Type Information for categorizing built in types as well as custom types
23 // this includes information about enums, their values and names
24 // - Type safe value storage : a kind of wxVariant, called right now wxVariantBase
25 // which will be merged with wxVariant
26 // - Property Information and Property Accessors providing access to a class'
27 // values and exposed event delegates
28 // - Information about event handlers
29 // - extended Class Information for accessing all these
31 // ----------------------------------------------------------------------------
33 // ----------------------------------------------------------------------------
37 #if wxUSE_EXTENDED_RTTI
39 // include definitions of other XTI structures
40 #include "wx/variantbase.h"
41 #include "wx/xtitypes.h"
42 #include "wx/xtictor.h"
43 #include "wx/xtiprop.h"
44 #include "wx/xtihandler.h"
46 // ----------------------------------------------------------------------------
48 // ----------------------------------------------------------------------------
50 class WXDLLIMPEXP_BASE wxObject
;
51 class WXDLLIMPEXP_BASE wxVariantBase
;
52 class WXDLLIMPEXP_BASE wxVariantBaseArray
;
54 typedef wxObject
*(*wxObjectConstructorFn
)(void);
55 typedef wxObject
* (*wxVariantToObjectConverter
)( wxVariantBase
&data
);
56 typedef wxVariantBase (*wxObjectToVariantConverter
)( wxObject
* );
58 class WXDLLIMPEXP_BASE wxObjectWriter
;
59 class WXDLLIMPEXP_BASE wxObjectReaderCallback
;
61 typedef bool (*wxObjectStreamingCallback
) ( const wxObject
*, wxObjectWriter
*, \
62 wxObjectReaderCallback
*, wxVariantBaseArray
& );
64 class WXDLLIMPEXP_BASE wxClassInfo
66 friend class WXDLLIMPEXP_BASE wxPropertyInfo
;
67 friend class WXDLLIMPEXP_BASE wxHandlerInfo
;
68 friend wxObject
*wxCreateDynamicObject(const wxChar
*name
);
71 wxClassInfo(const wxClassInfo
**_Parents
,
72 const wxChar
*_UnitName
,
73 const wxChar
*_ClassName
,
75 wxObjectConstructorFn ctor
,
76 wxPropertyInfo
*_Props
,
77 wxHandlerInfo
*_Handlers
,
78 wxObjectAllocatorAndCreator
* _Constructor
,
79 const wxChar
** _ConstructorProperties
,
80 const int _ConstructorPropertiesCount
,
81 wxVariantToObjectConverter _PtrConverter1
,
82 wxVariantToObjectConverter _Converter2
,
83 wxObjectToVariantConverter _Converter3
,
84 wxObjectStreamingCallback _streamingCallback
= NULL
) :
85 m_className(_ClassName
),
87 m_objectConstructor(ctor
),
89 m_firstProperty(_Props
),
90 m_firstHandler(_Handlers
),
92 m_unitName(_UnitName
),
93 m_constructor(_Constructor
),
94 m_constructorProperties(_ConstructorProperties
),
95 m_constructorPropertiesCount(_ConstructorPropertiesCount
),
96 m_variantOfPtrToObjectConverter(_PtrConverter1
),
97 m_variantToObjectConverter(_Converter2
),
98 m_objectToVariantConverter(_Converter3
),
99 m_streamingCallback(_streamingCallback
)
105 wxClassInfo(const wxChar
*_UnitName
, const wxChar
*_ClassName
,
106 const wxClassInfo
**_Parents
) :
107 m_className(_ClassName
),
109 m_objectConstructor(NULL
),
111 m_firstProperty(NULL
),
112 m_firstHandler(NULL
),
114 m_unitName(_UnitName
),
116 m_constructorProperties(NULL
),
117 m_constructorPropertiesCount(0),
118 m_variantOfPtrToObjectConverter(NULL
),
119 m_variantToObjectConverter(NULL
),
120 m_objectToVariantConverter(NULL
),
121 m_streamingCallback(NULL
)
127 // ctor compatible with old RTTI system
128 wxClassInfo(const wxChar
*_ClassName
,
129 const wxClassInfo
*_Parent1
,
130 const wxClassInfo
*_Parent2
,
132 wxObjectConstructorFn ctor
) :
133 m_className(_ClassName
),
135 m_objectConstructor(ctor
),
137 m_firstProperty(NULL
),
138 m_firstHandler(NULL
),
142 m_constructorProperties(NULL
),
143 m_constructorPropertiesCount(0),
144 m_variantOfPtrToObjectConverter(NULL
),
145 m_variantToObjectConverter(NULL
),
146 m_objectToVariantConverter(NULL
),
147 m_streamingCallback(NULL
)
150 m_parents
[0] = _Parent1
;
151 m_parents
[1] = _Parent2
;
156 virtual ~wxClassInfo();
158 // allocates an instance of this class, this object does not have to be
159 // initialized or fully constructed as this call will be followed by a call to Create
160 virtual wxObject
*AllocateObject() const
161 { return m_objectConstructor
? (*m_objectConstructor
)() : 0; }
163 // 'old naming' for AllocateObject staying here for backward compatibility
164 wxObject
*CreateObject() const { return AllocateObject(); }
166 // direct construction call for classes that cannot construct instances via alloc/create
167 wxObject
*ConstructObject(int ParamCount
, wxVariantBase
*Params
) const;
169 bool NeedsDirectConstruction() const
170 { return wx_dynamic_cast(wxObjectAllocator
*, m_constructor
) != NULL
; }
172 const wxChar
*GetClassName() const
173 { return m_className
; }
174 const wxChar
*GetBaseClassName1() const
175 { return m_parents
[0] ? m_parents
[0]->GetClassName() : NULL
; }
176 const wxChar
*GetBaseClassName2() const
177 { return (m_parents
[0] && m_parents
[1]) ? m_parents
[1]->GetClassName() : NULL
; }
179 const wxClassInfo
*GetBaseClass1() const
180 { return m_parents
[0]; }
181 const wxClassInfo
*GetBaseClass2() const
182 { return m_parents
[0] ? m_parents
[1] : NULL
; }
184 const wxChar
*GetIncludeName() const
185 { return m_unitName
; }
186 const wxClassInfo
**GetParents() const
187 { return m_parents
; }
189 { return m_objectSize
; }
190 bool IsDynamic() const
191 { return (NULL
!= m_objectConstructor
); }
193 wxObjectConstructorFn
GetConstructor() const
194 { return m_objectConstructor
; }
195 const wxClassInfo
*GetNext() const
200 static void CleanUp();
201 static wxClassInfo
*FindClass(const wxChar
*className
);
202 static const wxClassInfo
*GetFirst()
206 // Climb upwards through inheritance hierarchy.
207 // Dual inheritance is catered for.
209 bool IsKindOf(const wxClassInfo
*info
) const;
211 wxDECLARE_CLASS_INFO_ITERATORS()
213 // if there is a callback registered with that class it will be called
214 // before this object will be written to disk, it can veto streaming out
215 // this object by returning false, if this class has not registered a
216 // callback, the search will go up the inheritance tree if no callback has
217 // been registered true will be returned by default
218 bool BeforeWriteObject( const wxObject
*obj
, wxObjectWriter
*streamer
, \
219 wxObjectReaderCallback
*persister
, wxVariantBaseArray
&metadata
) const;
221 // gets the streaming callback from this class or any superclass
222 wxObjectStreamingCallback
GetStreamingCallback() const;
224 // returns the first property
225 const wxPropertyInfo
* GetFirstProperty() const
226 { return m_firstProperty
; }
228 // returns the first handler
229 const wxHandlerInfo
* GetFirstHandler() const
230 { return m_firstHandler
; }
232 // Call the Create upon an instance of the class, in the end the object is fully
234 virtual bool Create (wxObject
*object
, int ParamCount
, wxVariantBase
*Params
) const;
236 // get number of parameters for constructor
237 virtual int GetCreateParamCount() const
238 { return m_constructorPropertiesCount
; }
240 // get n-th constructor parameter
241 virtual const wxChar
* GetCreateParamName(int n
) const
242 { return m_constructorProperties
[n
]; }
244 // Runtime access to objects for simple properties (get/set) by property
245 // name and variant data
246 virtual void SetProperty (wxObject
*object
, const wxChar
*propertyName
,
247 const wxVariantBase
&value
) const;
248 virtual wxVariantBase
GetProperty (wxObject
*object
, const wxChar
*propertyName
) const;
250 // Runtime access to objects for collection properties by property name
251 virtual wxVariantBaseArray
GetPropertyCollection(wxObject
*object
,
252 const wxChar
*propertyName
) const;
253 virtual void AddToPropertyCollection(wxObject
*object
, const wxChar
*propertyName
,
254 const wxVariantBase
& value
) const;
256 // we must be able to cast variants to wxObject pointers, templates seem
257 // not to be suitable
258 wxObject
* VariantToInstance( wxVariantBase
&data
) const
260 if ( data
.GetTypeInfo()->GetKind() == wxT_OBJECT
)
261 return m_variantToObjectConverter( data
);
263 return m_variantOfPtrToObjectConverter( data
);
266 wxVariantBase
InstanceToVariant( wxObject
*object
) const
267 { return m_objectToVariantConverter( object
); }
269 // find property by name
270 virtual const wxPropertyInfo
*FindPropertyInfo (const wxChar
*PropertyName
) const;
272 // find handler by name
273 virtual const wxHandlerInfo
*FindHandlerInfo (const wxChar
*handlerName
) const;
275 // find property by name
276 virtual wxPropertyInfo
*FindPropertyInfoInThisClass (const wxChar
*PropertyName
) const;
278 // find handler by name
279 virtual wxHandlerInfo
*FindHandlerInfoInThisClass (const wxChar
*handlerName
) const;
281 // puts all the properties of this class and its superclasses in the map,
282 // as long as there is not yet an entry with the same name (overriding mechanism)
283 void GetProperties( wxPropertyInfoMap
&map
) const;
286 const wxChar
*m_className
;
288 wxObjectConstructorFn m_objectConstructor
;
290 // class info object live in a linked list:
291 // pointers to its head and the next element in it
293 static wxClassInfo
*sm_first
;
296 static wxHashTable
*sm_classTable
;
299 wxPropertyInfo
* m_firstProperty
;
300 wxHandlerInfo
* m_firstHandler
;
303 const wxClassInfo
** m_parents
;
304 const wxChar
* m_unitName
;
306 wxObjectAllocatorAndCreator
* m_constructor
;
307 const wxChar
** m_constructorProperties
;
308 const int m_constructorPropertiesCount
;
309 wxVariantToObjectConverter m_variantOfPtrToObjectConverter
;
310 wxVariantToObjectConverter m_variantToObjectConverter
;
311 wxObjectToVariantConverter m_objectToVariantConverter
;
312 wxObjectStreamingCallback m_streamingCallback
;
314 const wxPropertyAccessor
*FindAccessor (const wxChar
*propertyName
) const;
317 // registers the class
321 DECLARE_NO_COPY_CLASS(wxClassInfo
)
324 WXDLLIMPEXP_BASE wxObject
*wxCreateDynamicObject(const wxChar
*name
);
327 // ----------------------------------------------------------------------------
328 // wxDynamicClassInfo
329 // ----------------------------------------------------------------------------
331 // this object leads to having a pure runtime-instantiation
333 class WXDLLIMPEXP_BASE wxDynamicClassInfo
: public wxClassInfo
335 friend class WXDLLIMPEXP_BASE wxDynamicObject
;
338 wxDynamicClassInfo( const wxChar
*_UnitName
, const wxChar
*_ClassName
,
339 const wxClassInfo
* superClass
);
340 virtual ~wxDynamicClassInfo();
342 // constructs a wxDynamicObject with an instance
343 virtual wxObject
*AllocateObject() const;
345 // Call the Create method for a class
346 virtual bool Create (wxObject
*object
, int ParamCount
, wxVariantBase
*Params
) const;
348 // get number of parameters for constructor
349 virtual int GetCreateParamCount() const;
351 // get i-th constructor parameter
352 virtual const wxChar
* GetCreateParamName(int i
) const;
354 // Runtime access to objects by property name, and variant data
355 virtual void SetProperty (wxObject
*object
, const wxChar
*PropertyName
,
356 const wxVariantBase
&Value
) const;
357 virtual wxVariantBase
GetProperty (wxObject
*object
, const wxChar
*PropertyName
) const;
359 // adds a property to this class at runtime
360 void AddProperty( const wxChar
*propertyName
, const wxTypeInfo
* typeInfo
);
362 // removes an existing runtime-property
363 void RemoveProperty( const wxChar
*propertyName
);
365 // renames an existing runtime-property
366 void RenameProperty( const wxChar
*oldPropertyName
, const wxChar
*newPropertyName
);
368 // as a handler to this class at runtime
369 void AddHandler( const wxChar
*handlerName
, wxObjectEventFunction address
,
370 const wxClassInfo
* eventClassInfo
);
372 // removes an existing runtime-handler
373 void RemoveHandler( const wxChar
*handlerName
);
375 // renames an existing runtime-handler
376 void RenameHandler( const wxChar
*oldHandlerName
, const wxChar
*newHandlerName
);
379 struct wxDynamicClassInfoInternal
;
380 wxDynamicClassInfoInternal
* m_data
;
384 // ----------------------------------------------------------------------------
385 // wxDECLARE class macros
386 // ----------------------------------------------------------------------------
388 #define _DECLARE_DYNAMIC_CLASS(name) \
390 static wxClassInfo ms_classInfo; \
391 static const wxClassInfo* ms_classParents[]; \
392 static wxPropertyInfo* GetPropertiesStatic(); \
393 static wxHandlerInfo* GetHandlersStatic(); \
394 static wxClassInfo *GetClassInfoStatic() \
395 { return &name::ms_classInfo; } \
396 virtual wxClassInfo *GetClassInfo() const \
397 { return &name::ms_classInfo; }
399 #define wxDECLARE_DYNAMIC_CLASS(name) \
400 static wxObjectAllocatorAndCreator* ms_constructor; \
401 static const wxChar * ms_constructorProperties[]; \
402 static const int ms_constructorPropertiesCount; \
403 _DECLARE_DYNAMIC_CLASS(name)
405 #define wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(name) \
406 wxDECLARE_NO_ASSIGN_CLASS(name) \
407 wxDECLARE_DYNAMIC_CLASS(name)
409 #define wxDECLARE_DYNAMIC_CLASS_NO_COPY(name) \
410 wxDECLARE_NO_COPY_CLASS(name) \
411 wxDECLARE_DYNAMIC_CLASS(name)
413 #define wxDECLARE_ABSTRACT_CLASS(name) _DECLARE_DYNAMIC_CLASS(name)
414 #define wxCLASSINFO(name) (&name::ms_classInfo)
417 // ----------------------------------------------------------------------------
418 // wxIMPLEMENT class macros for concrete classes
419 // ----------------------------------------------------------------------------
421 // Single inheritance with one base class
423 #define _TYPEINFO_CLASSES(n, toString, fromString ) \
424 wxClassTypeInfo s_typeInfo##n(wxT_OBJECT, &n::ms_classInfo, \
425 toString, fromString, typeid(n).name()); \
426 wxClassTypeInfo s_typeInfoPtr##n(wxT_OBJECT_PTR, &n::ms_classInfo, \
427 toString, fromString, typeid(n*).name());
429 #define _IMPLEMENT_DYNAMIC_CLASS(name, basename, unit, callback) \
430 wxObject* wxConstructorFor##name() \
431 { return new name; } \
432 wxObject* wxVariantOfPtrToObjectConverter##name ( wxVariantBase &data ) \
433 { return data.wxTEMPLATED_MEMBER_CALL(Get, name*); } \
434 wxVariantBase wxObjectToVariantConverter##name ( wxObject *data ) \
435 { return wxVariantBase( wx_dynamic_cast(name*, data) ); } \
437 const wxClassInfo* name::ms_classParents[] = \
438 { &basename::ms_classInfo, NULL }; \
439 wxClassInfo name::ms_classInfo(name::ms_classParents, wxT(unit), \
440 wxT(#name), (int) sizeof(name), (wxObjectConstructorFn) wxConstructorFor##name, \
441 name::GetPropertiesStatic(), name::GetHandlersStatic(), name::ms_constructor, \
442 name::ms_constructorProperties, name::ms_constructorPropertiesCount, \
443 wxVariantOfPtrToObjectConverter##name, NULL, wxObjectToVariantConverter##name, \
446 #define _IMPLEMENT_DYNAMIC_CLASS_WITH_COPY(name, basename, unit, callback ) \
447 wxObject* wxConstructorFor##name() \
448 { return new name; } \
449 wxObject* wxVariantToObjectConverter##name ( wxVariantBase &data ) \
450 { return &data.wxTEMPLATED_MEMBER_CALL(Get, name); } \
451 wxObject* wxVariantOfPtrToObjectConverter##name ( wxVariantBase &data ) \
452 { return data.wxTEMPLATED_MEMBER_CALL(Get, name*); } \
453 wxVariantBase wxObjectToVariantConverter##name ( wxObject *data ) \
454 { return wxVariantBase( wx_dynamic_cast(name*, data) ); } \
456 const wxClassInfo* name::ms_classParents[] = { &basename::ms_classInfo,NULL }; \
457 wxClassInfo name::ms_classInfo(name::ms_classParents, wxT(unit), \
458 wxT(#name), (int) sizeof(name), (wxObjectConstructorFn) wxConstructorFor##name, \
459 name::GetPropertiesStatic(),name::GetHandlersStatic(),name::ms_constructor, \
460 name::ms_constructorProperties, name::ms_constructorPropertiesCount, \
461 wxVariantOfPtrToObjectConverter##name, wxVariantToObjectConverter##name, \
462 wxObjectToVariantConverter##name, callback);
464 #define wxIMPLEMENT_DYNAMIC_CLASS_WITH_COPY( name, basename ) \
465 _IMPLEMENT_DYNAMIC_CLASS_WITH_COPY( name, basename, "", NULL ) \
466 _TYPEINFO_CLASSES(name, NULL, NULL) \
467 const wxPropertyInfo *name::GetPropertiesStatic() \
468 { return (wxPropertyInfo*) NULL; } \
469 const wxHandlerInfo *name::GetHandlersStatic() \
470 { return (wxHandlerInfo*) NULL; } \
471 wxCONSTRUCTOR_DUMMY( name )
473 #define wxIMPLEMENT_DYNAMIC_CLASS( name, basename ) \
474 _IMPLEMENT_DYNAMIC_CLASS( name, basename, "", NULL ) \
475 _TYPEINFO_CLASSES(name, NULL, NULL) \
476 wxPropertyInfo *name::GetPropertiesStatic() \
477 { return (wxPropertyInfo*) NULL; } \
478 wxHandlerInfo *name::GetHandlersStatic() \
479 { return (wxHandlerInfo*) NULL; } \
480 wxCONSTRUCTOR_DUMMY( name )
482 #define wxIMPLEMENT_DYNAMIC_CLASS_XTI( name, basename, unit ) \
483 _IMPLEMENT_DYNAMIC_CLASS( name, basename, unit, NULL ) \
484 _TYPEINFO_CLASSES(name, NULL, NULL)
486 #define wxIMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK( name, basename, unit, callback )\
487 _IMPLEMENT_DYNAMIC_CLASS( name, basename, unit, &callback ) \
488 _TYPEINFO_CLASSES(name, NULL, NULL)
490 #define wxIMPLEMENT_DYNAMIC_CLASS_WITH_COPY_XTI( name, basename, unit ) \
491 _IMPLEMENT_DYNAMIC_CLASS_WITH_COPY( name, basename, unit, NULL ) \
492 _TYPEINFO_CLASSES(name, NULL, NULL)
494 #define wxIMPLEMENT_DYNAMIC_CLASS_WITH_COPY_AND_STREAMERS_XTI( name, basename, \
497 _IMPLEMENT_DYNAMIC_CLASS_WITH_COPY( name, basename, unit, NULL ) \
498 _TYPEINFO_CLASSES(name, toString, fromString)
500 // this is for classes that do not derive from wxObject, there are no creators for these
502 #define wxIMPLEMENT_DYNAMIC_CLASS_NO_WXOBJECT_NO_BASE_XTI( name, unit ) \
503 const wxClassInfo* name::ms_classParents[] = { NULL }; \
504 wxClassInfo name::ms_classInfo(name::ms_classParents, wxEmptyString, \
505 wxT(#name), (int) sizeof(name), (wxObjectConstructorFn) 0, \
506 name::GetPropertiesStatic(),name::GetHandlersStatic(), 0, 0, \
508 _TYPEINFO_CLASSES(name, NULL, NULL)
510 // this is for subclasses that still do not derive from wxObject
512 #define wxIMPLEMENT_DYNAMIC_CLASS_NO_WXOBJECT_XTI( name, basename, unit ) \
513 const wxClassInfo* name::ms_classParents[] = { &basename::ms_classInfo, NULL }; \
514 wxClassInfo name::ms_classInfo(name::ms_classParents, wxEmptyString, \
515 wxT(#name), (int) sizeof(name), (wxObjectConstructorFn) 0, \
516 name::GetPropertiesStatic(),name::GetHandlersStatic(), 0, 0, \
518 _TYPEINFO_CLASSES(name, NULL, NULL)
521 // Multiple inheritance with two base classes
523 #define _IMPLEMENT_DYNAMIC_CLASS2(name, basename, basename2, unit, callback) \
524 wxObject* wxConstructorFor##name() { return new name; } \
525 wxObject* wxVariantOfPtrToObjectConverter##name ( wxVariantBase &data ) \
526 { return data.wxTEMPLATED_MEMBER_CALL(Get, name*); } \
527 wxVariantBase wxObjectToVariantConverter##name ( wxObject *data ) \
528 { return wxVariantBase( wx_dynamic_cast(name*, data) ); } \
530 const wxClassInfo* name::ms_classParents[] = \
531 { &basename::ms_classInfo,&basename2::ms_classInfo, NULL }; \
532 wxClassInfo name::ms_classInfo(name::ms_classParents, wxT(unit), \
533 wxT(#name), (int) sizeof(name), (wxObjectConstructorFn) wxConstructorFor##name, \
534 name::GetPropertiesStatic(),name::GetHandlersStatic(),name::ms_constructor, \
535 name::ms_constructorProperties, name::ms_constructorPropertiesCount, \
536 wxVariantOfPtrToObjectConverter##name, NULL, wxObjectToVariantConverter##name, \
539 #define wxIMPLEMENT_DYNAMIC_CLASS2( name, basename, basename2) \
540 _IMPLEMENT_DYNAMIC_CLASS2( name, basename, basename2, "", NULL) \
541 _TYPEINFO_CLASSES(name, NULL, NULL) \
542 wxPropertyInfo *name::GetPropertiesStatic() { return (wxPropertyInfo*) NULL; } \
543 wxHandlerInfo *name::GetHandlersStatic() { return (wxHandlerInfo*) NULL; } \
544 wxCONSTRUCTOR_DUMMY( name )
546 #define wxIMPLEMENT_DYNAMIC_CLASS2_XTI( name, basename, basename2, unit) \
547 _IMPLEMENT_DYNAMIC_CLASS2( name, basename, basename2, unit, NULL) \
548 _TYPEINFO_CLASSES(name, NULL, NULL)
552 // ----------------------------------------------------------------------------
553 // wxIMPLEMENT class macros for abstract classes
554 // ----------------------------------------------------------------------------
556 // Single inheritance with one base class
558 #define _IMPLEMENT_ABSTRACT_CLASS(name, basename) \
559 wxObject* wxVariantToObjectConverter##name ( wxVariantBase &data ) \
560 { return data.wxTEMPLATED_MEMBER_CALL(Get, name*); } \
561 wxObject* wxVariantOfPtrToObjectConverter##name ( wxVariantBase &data ) \
562 { return data.wxTEMPLATED_MEMBER_CALL(Get, name*); } \
563 wxVariantBase wxObjectToVariantConverter##name ( wxObject *data ) \
564 { return wxVariantBase( wx_dynamic_cast(name*, data) ); } \
566 const wxClassInfo* name::ms_classParents[] = \
567 { &basename::ms_classInfo,NULL }; \
568 wxClassInfo name::ms_classInfo(name::ms_classParents, wxEmptyString, \
569 wxT(#name), (int) sizeof(name), (wxObjectConstructorFn) 0, \
570 name::GetPropertiesStatic(),name::GetHandlersStatic(), 0, 0, \
571 0, wxVariantOfPtrToObjectConverter##name,wxVariantToObjectConverter##name, \
572 wxObjectToVariantConverter##name); \
573 _TYPEINFO_CLASSES(name, NULL, NULL)
575 #define wxIMPLEMENT_ABSTRACT_CLASS( name, basename ) \
576 _IMPLEMENT_ABSTRACT_CLASS( name, basename ) \
577 wxHandlerInfo *name::GetHandlersStatic() { return (wxHandlerInfo*) NULL; } \
578 wxPropertyInfo *name::GetPropertiesStatic() { return (wxPropertyInfo*) NULL; }
580 // Multiple inheritance with two base classes
582 #define wxIMPLEMENT_ABSTRACT_CLASS2(name, basename1, basename2) \
583 wxClassInfo name::ms_classInfo(wxT(#name), wxT(#basename1), \
584 wxT(#basename2), (int) sizeof(name), \
585 (wxObjectConstructorFn) 0);
589 // --------------------------------------------------------------------------
590 // Collection Support
591 // --------------------------------------------------------------------------
593 template<typename iter
, typename collection_t
> void wxListCollectionToVariantArray(
594 const collection_t
& coll
, wxVariantBaseArray
&value
)
596 iter current
= coll
.GetFirst();
599 value
.Add( new wxVariantBase(current
->GetData()) );
600 current
= current
->GetNext();
604 template<typename collection_t
> void wxArrayCollectionToVariantArray(
605 const collection_t
& coll
, wxVariantBaseArray
&value
)
607 for( size_t i
= 0; i
< coll
.GetCount(); i
++ )
609 value
.Add( new wxVariantBase(coll
[i
]) );
613 #endif // wxUSE_EXTENDED_RTTI