Hi,
I´m messing around with the borland VCL and have to accomplish the following task: There are many types (like TStaticText, TLabel, TEdit ...) that have properties with the same name, but unfortunately there´s no common base class with these properties made public, so I can´t use
Example:Code:((TWinControl *) pObject)->Text = "Hello World";
I read component properties (text color, font style, etc.) from a file and have to assign these properties to different control types. My current naive approach is providing a function for each control type and perform customization inside that function:Code:class TWinControl { protected: AnsiString Caption; ... }; class TLabel : public TWinControl { public : AnsiString Caption; ... }; class TStaticText : public TWinControl { public: AnsiString Caption; };
My second approach is to use templates and traits to handle different control types:Code:void CustomizeLabel( TLabel *pLabel, TComponentProperties *pProps ) { pLabel->Text = pProps->Text; pLabel->Color = pProps->Color; ... } void CustomizeMenu( TMenu *pMenu, TComponentProperties *pProps ) { ... } void CustomizeButton( TButton *pButton, TComponentProperties *pProps ) { ... }
Now I can use the following constructs to assign text and/or color:Code:template<class TTarget> TNoOp { TNoOp( TObject *pTarget, TComponentProperties *pProps ) { } } template<class TTarget> TCaptionSetter { TCaptionSetter( TObject *pTarget, TComponentProperties *pProps ) { ((TTarget *) pTarget)->Caption = pProps->Text; } } template<class TTarget> TColorSetter { TColorSetter( TObject *pTarget, TComponentProperties *pProps ) { ((TTarget *) pTarget)->Color = pProps->Color; } template<class TTarget, class TTextHandler, class TColorHandler> class TCustomizer { TCustomizer( TObject *pTarget, TComponentProperties *pProps ) { TTextHandler( pTarget, pProps ); TColorHandler( pTarget, pProps ); } }
Using the code above I have to specify the type name for each of the traits, making the code less readable. The type names are redundant, because they´re already known by the class TCustomizer, so I want to get rid of the template spec for the traits. I´m quite new to templates and generic programming, is it possible to create a construct without specialized trait classes? LikeCode:// set caption and color TCustomizer<TLabel, TCaptionSetter<TLabel>, TColorSetter<TLabel> Cust( pObj, pProps ); // set caption only, ignore color TCustomizer<TMenu, TCaptionSetter<TMenu>, TNoOp<TMenu> Cust( pObj, pProps );
I want to use the template this way:Code:template<class TTarget, class TCaptionSetter, class TColorSetter> TCustomizer { TCustomizer( TObject *pObj, TComponentProperties *pProps ) { TCaptionSetter ts( pObj, pProps ); TColorSetter cs( pObj, pProps ); } }
Code:TCustomizer<TLabel, TCaptionSetter, TNoOp> Cust( pObj, pProps );
Third approach (just coming in mind, I don´t know if it will work):
Can I useCode:template<class TTarget, class TTextHandler, class TColorHandler> class TCustomizer { TTarget *m_pTarget; TComponentProperties *m_pProps; class TColorSetter( TCustomizer<TTarget> *pCustom ) { pCustom->Target->Color = pCustom->m_Props->Color; } class TCaptionSetter( TCustomizer<TTarget> *pCusom ) { pCustom->Target->Caption = pCustom->m_Props->Text; } TCustomizer( TObject *pTarget, TComponentProperties *pProps ) { m_pTarget = (TTarget *) pTarget; m_pProps = pProps; TTextHandler th( this ); TColorHandler tc( this ); } }
?Code:TCustomizer<TLabel, TCustomizer::TTextSetter,TCustomizer::TColorSetter> Cust( pObj, pProps );
Edit: Third approach can´t work, please ignore.
Thanks in advance,
Guido




Reply With Quote