Delphi and dynamic properties
[lang_it]
Linguaggio : Borland Delphi 7
Sistema Operativo : Win Xp Pro
Come premessa a volte è necessario rendere l’applicazione che si stà sviluppando il più flessibile possibile. Per evitare di avere migliaia di personalizzazioni per migliaia di clienti. Una cosa che può aiutare in questo è la modifica banale di alcune proprietà dei componenti dell’applicaiozne stessa a runtime in funzione di particolari parametri.
In Delphi è possibile fare questo in modo molto semplice senza dover scrivere granchè di codice, per rendere ancora più semplice la cosa ho preparato una banale applicazione d’esempio scaricabile da :Â [download id=”2″]
In particolare tale applicazione :
- mostra come sia possibile maneggiare un Componente (Oggetto) partendo dal nome dello stesso :
1 2 3 4 5 6 7 8 9 |
Var Comp : TComponent; Begin Comp := FindComponent(cbComponenti.Text); blablabla ....... |
- come ottenere l’elenco delle proprietà e, dei relativi nomi, da un definito componente
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
procedure TForm1.cbPropertyNameDropDown(Sender: TObject); var Comp : TComponent; PropInfo : PPropInfo; PropList : PPropList; I, PropCount,ListSize : Integer; begin Try cbPropertyName.Clear; Comp := FindComponent(cbComponenti.Text); If Comp = nil then Exit; (* ALLOCATING MEMORY FOR THE PROPERTY LIST *) PropCount := GetPropList(Comp.ClassInfo,tkAny,nil); ListSize := PropCount * SizeOf(Pointer); Getmem(PropList,ListSize); PropCount := GetPropList(Comp.ClassInfo,tkAny,PropList,true); If not assigned(PropList) then Exit; For I:=0 to PropCount -1 do begin PropInfo := PropList^[I]; If Assigned(PropInfo) then Begin if PropInfo^.PropType^.Kind in tkMethods then Begin // If is an avent handler do something end Else // if is a property Begin cbPropertyName.Items.Add(PropInfo^.Name); end; end; end; cbPropertyName.Update; Finally FreeMem(PropList); End; end; |
- impostare il valore di una proprietà partendo dal componente a cui appartiene e dal suo nome
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
procedure TForm1.btnDoItClick(Sender: TObject); var Comp : TComponent; PropInfo : PPropInfo; begin Comp := FindComponent(cbComponenti.Text); If Comp <> nil then Begin PropInfo := GetPropInfo(Comp.ClassInfo,cbPropertyName.Text); //SetVariantProp(); SetPropValue(Comp,cbPropertyName.Text,edPropValue.Text); (* exit; if Assigned(PropInfo) then Begin case PropInfo^.PropType^.Kind of tkInteger : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkChar : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkEnumeration : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkFloat : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkString : Begin SetStrProp(Comp,PropInfo,edPropValue.Text) end; tkSet : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkClass : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkMethod : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkWChar : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkLString : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkWString : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkVariant : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkArray : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkRecord : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkInterface : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkInt64 : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkDynArray : Begin ShowMessage(PropInfo^.PropType^.Name) end; end; end; *) End; end; |
[/lang_it]
[lang_en]
Linguaggio : Borland Delphi 7
Sistema Operativo : Win Xp Pro
Sometimes, you need to extend the flexibility of your application, to prevent managinig thousands release of an application for thousands customore.One of the most important feature is the posibility of modify a component property value at runtime.
With Delphi is possible and simple to do like in this demo application: [download id=”2″]
The core features of this demo application are : :
- get an object from his name ,using a string, that can be filled in a ini file or xml or db table :
1 2 3 4 5 6 7 8 9 |
Var Comp : TComponent; Begin Comp := FindComponent(cbComponenti.Text); blablabla ....... |
- obtain the list of properties and published methods/event of the selected object
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
procedure TForm1.cbPropertyNameDropDown(Sender: TObject); var Comp : TComponent; PropInfo : PPropInfo; PropList : PPropList; I, PropCount,ListSize : Integer; begin Try cbPropertyName.Clear; Comp := FindComponent(cbComponenti.Text); If Comp = nil then Exit; (* ALLOCATING MEMORY FOR THE PROPERTY LIST *) PropCount := GetPropList(Comp.ClassInfo,tkAny,nil); ListSize := PropCount * SizeOf(Pointer); Getmem(PropList,ListSize); PropCount := GetPropList(Comp.ClassInfo,tkAny,PropList,true); If not assigned(PropList) then Exit; For I:=0 to PropCount -1 do begin PropInfo := PropList^[I]; If Assigned(PropInfo) then Begin if PropInfo^.PropType^.Kind in tkMethods then Begin // If is an avent handler do something end Else // if is a property Begin cbPropertyName.Items.Add(PropInfo^.Name); end; end; end; cbPropertyName.Update; Finally FreeMem(PropList); End; end; |
- setting the value of a property, for simple we have used SetPropValue , an untyped method that use a variant as parameter to send to selected property of the object
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
procedure TForm1.btnDoItClick(Sender: TObject); var Comp : TComponent; PropInfo : PPropInfo; begin Comp := FindComponent(cbComponenti.Text); If Comp <> nil then Begin PropInfo := GetPropInfo(Comp.ClassInfo,cbPropertyName.Text); //SetVariantProp(); SetPropValue(Comp,cbPropertyName.Text,edPropValue.Text); (* exit; if Assigned(PropInfo) then Begin case PropInfo^.PropType^.Kind of tkInteger : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkChar : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkEnumeration : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkFloat : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkString : Begin SetStrProp(Comp,PropInfo,edPropValue.Text) end; tkSet : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkClass : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkMethod : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkWChar : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkLString : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkWString : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkVariant : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkArray : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkRecord : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkInterface : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkInt64 : Begin ShowMessage(PropInfo^.PropType^.Name) end; tkDynArray : Begin ShowMessage(PropInfo^.PropType^.Name) end; end; end; *) End; end; |
[/lang_en]