cs_emge
Messages postés4Date d'inscriptionsamedi 18 janvier 2003StatutMembreDernière intervention27 mai 2010
-
27 mai 2010 à 09:52
cfardeau
Messages postés1Date d'inscriptionvendredi 4 avril 2003StatutMembreDernière intervention20 septembre 2010
-
20 sept. 2010 à 14:48
J'ai un héritage de classe, et j'aimerai "simplifier du code". En effet, ma classe TInfoCol peut contenir plusieurs property, et à la longue, celà peut parraitre fastidieux de déclarer tous les setter / getter. Pour cela, j'ai pensé à faire des methodes générique dans la classe TBaseDataSource (getString et setString), qui s'occuperai de tout faire, au moins pour les champs de type string. Le but est de retrouver le nom de la property qui a appelé ces methodes.
exemple :
si je fais
var
InfoCol : TInfoCol;
begin
InfoCol := TInfoCol.create;
InfoCol.Nom := 'Le Nom';
InfoCol.Prenom := 'Le Prénom';
end;
Lorsque l'on fait InfoCol.Nom := 'Le Nom', il faudrait passer dans le SetString en faisant celà :
procedure TBaseDataSource.setString(const Value: string);
begin
WriteProperty('Nom',Value);
end;
et pour le prénom :
procedure TBaseDataSource.setString(const Value: string);
begin
WriteProperty('Prenom',Value);
end;
J'ai pensé à utiliser la VMT, mais je ne sais pas du tout comment faire.
J'aimerai avoir un SetString qui ferai ceci :
procedure TBaseDataSource.setString(const Value: string);
begin
//Determination de la property ayant appelé le setString
//Nom lorsque l'on fait infoCol.Nom := ...
//Prenom lorsque l'on fait infoCol.prenom := ...
WriteProperty(<Nom de la property>,Value);
end;
Voilà le code de mes classes
TBaseDataSource = Class(TInfo)
private
FListeChamps: TListeChamps;
protected
function getString : string;
procedure setString(const Value : string);
public
constructor Create; override;
destructor Destroy; override;
procedure Copier(Source : TInfo); override;
property ListeChamps : TListeChamps read FListeChamps write FListeChamps;
Procedure AddProperty(Name : String; Valeur : Variant; typeProperty : TTypePropriete);
Function ReadProperty(Name : String) : TDataProperty;
procedure WriteProperty(Name : String; Valeur : Variant);
end;
TInfoCol = class(TBaseDataSource)
private
function getProgress : integer;
procedure setProgress(const Value : integer);
public
function Cle: string; override;
published
property Nom : string read getString write setString;
property Prenom : string read getString write setString;
property Progress : integer read getProgress write SetProgress;
end;
[...]
(*function TInfoCol.getNom : string;
begin
result := readProperty('Nom').Value;
end;
procedure TInfoCol.setNom(const Value: string);
begin
WriteProperty('Nom',Value);
end;*)
function TInfoCol.getProgress : integer;
begin
result := readProperty('Progress').Value;
end;
procedure TInfoCol.setProgress(const Value: integer);
begin
WriteProperty('Progress',Value);
end;
function TBaseDataSource.getString: string;
begin
[...]
end;
Pour infos, et pour que celà semble compréhensible, j'ai mis le code de la fonction copier. Pour celle-ci, j'ai utilisé les RTTI
procedure TBaseDataSource.Copier(Source: TInfo);
var
i : integer;
ListeProprietes: TPropList;
begin
GetPropInfos(ClassType.ClassInfo, @ListeProprietes);
for I := 0 to GetTypeData(ClassType.ClassInfo).PropCount-1 do
begin
case ListeProprietes[i]^.PropType^.Kind of
tkString,tkLString : WriteProperty(ListeProprietes[I]^.Name, GetStrProp(source,ListeProprietes[I]^.Name));
tkInteger : WriteProperty(ListeProprietes[I]^.Name, GetOrdProp(source,ListeProprietes[I]^.Name));
end;
end;
end;
cfardeau
Messages postés1Date d'inscriptionvendredi 4 avril 2003StatutMembreDernière intervention20 septembre 2010 20 sept. 2010 à 14:48
Salut,
Je ne suis pas sur que par les RTTI tu puisses réaliser cette opération dans la mesure que tu n'as pas connaissance de la propriété en cours d'écriture (si c'est le cas je suis prenneur).
Une solution serait d'appliquer un index sur tes propriétés.
interface
uses ...., Inifiles;
type
TMonItem = class(Tcomponent)
private
MemIni : TMemIniFile;
public
constructor create(aOwner : TComponent);override;
destructor Destroy;override;
function ReadString(Index : integer) : string;
procedure WriteString(Index : integer; Value : string);
end;
TMonDescendant = class(TMonItem)
private
function GetValue(const Index: Integer): string;
procedure SetValue(const Index: Integer; const Value: string);
public
published
property Nom : string index 0 read GetValue write SetValue;
property Prenom : string index 1 read GetValue write SetValue;
end;
J'utilise le TMemIniFile pour faciliter la gestion de l'accès au propriétés. Ce n'est pas la solution à utiliser sur de gros volumes.
implementation
{ TMonItem }
constructor TMonItem.create(aOwner: TComponent);
begin
inherited;
MemIni := TMemIniFile.Create('');
end;
destructor TMonItem.Destroy;
begin
MemIni.Free;
inherited;
end;
function TMonItem.ReadString(Index : integer): string;
begin
Result := MemIni.ReadString('STRING', inttostr(Index), '');
end;
procedure TMonItem.WriteString(Index : integer; Value: string);
begin
MemIni.WriteString('STRING', inttostr(Index), Value);
end;
{ TMonDescendant }
function TMonDescendant.GetValue(const Index: Integer): string;
begin
Result := ReadString(Index);
end;
procedure TMonDescendant.SetValue(const Index: Integer; const Value: string);
begin
WriteString(Index, Value);
end;