Manchmal kann es ganz interessant sein, während der Laufzeit des Programms die Properties eines Objektes zu ermitteln. Stellt Euch einmal vor, Ihr habt z.B. ein Fenster mit verschiedenen Properties, die z.B. in der Registry gespeichert werden sollen. Natürlich kann man alle Properties per Hand auslesen und dann in der Registry speichern. Diese Möglichkeit halte ich aber nicht für allzu elegant, weil man dann unter Umständen das Problem hat, dass sobald man eine neue Property hinzufügt auch Code für das Schreiben/Lesen in die Registry hinzufügen muss. Da Programmierer bekanntlich faul sind und ausserdem auch sehr vergesslich habe ich einen anderen Weg gesucht und gefunden:
Wenn ein Objekt nun in der Lage wäre, seine eigenen Properties zu bestimmen, dann muss man nur eine einfache kleine Schleife schreiben, die Property für Property duchgeht und schwupps ist man für alle Zeiten fertig mit dem Problem. Natürlich sollte die Schleife auch für abgeleitete Klassen funktionieren. Diese können auch neue Properties enthalten, die natürlich auch in die Registry (oder wohin auch immer) gespeichert werden sollen. Gehen muss das irgendwie, denn die
IDE von Delphi macht ja im Prinzip nichts anderes (ich meine jetzt das Auslesen von Properties zur Laufzeit).
Zunächst habe ich einfach eine Klasse TPropObj erzeugt, die als "Eltern-Klasse" die dir "Properties-Auslese Prozedur" implementier. Um das Beispiel so einfach wie möglich zu halten, sehe ich mal von der Registry oder so ab und implementiere einfach eine Funktion, die die Properties mit zugehörigem Typ in eine List-Box schreibt:
Delphi-Quellcode:
unit UPropObj;
interface
uses
Classes,
SysUtils,
TypInfo,
StdCtrls;
type
TPropObj =
class(TPersistent)
private
FHallo: Integer;
procedure SetHallo(
const Value: Integer);
protected
public
procedure FillPropsInListBox (myLB : TListBox);
virtual;
published
// das hier ist einfach eine Property des Eltenobjekts
property Hallo : Integer
read FHallo
write SetHallo;
end;
implementation
{ TPropObj }
procedure TPropObj.FillPropsInListBox(myLB: TListBox);
var
i : Integer;
PropCount : Integer;
PropList : PPropList;
begin
// Listbox leeren
myLB.Clear;
// Anzahl der Properties holen; Wir müssen hier mit
// Self.ClassInfo arbeiten, da die Prozedur ja auch
// für abgeleitete Klassen funktionieren soll
PropCount := GetPropList(Self.ClassInfo, PropList);
// Hier ist die Schleife, die die Properties durchgeht
for i := 0
to PropCount-1
do
begin
// ab in die Listbox mit dem Zeug...
myLB.AddItem(PropList^[i].
Name+'
- '+PropList^[i].PropType^.
Name,
nil);
end;
end;
procedure TPropObj.SetHallo(
const Value: Integer);
begin
FHallo := Value;
end;
end.
Nun müssen wir noch eine abgeleitete Klasse definieren, die auch noch ein paar Properties deklariert:
Delphi-Quellcode:
unit UPropChild;
interface
uses
UPropObj;
type
TPropChild =
class(TPropObj)
private
FTest1: Integer;
FmyProp:
String;
procedure SetmyProp(
const Value:
String);
procedure SetTest1(
const Value: Integer);
protected
public
published
// einfach noch mal ein paar Properties...
property Test1 : Integer
read FTest1
write SetTest1;
property myProp :
String read FmyProp
write SetmyProp;
end;
implementation
{ TPropChild }
procedure TPropChild.SetmyProp(
const Value:
String);
begin
FmyProp := Value;
end;
procedure TPropChild.SetTest1(
const Value: Integer);
begin
FTest1 := Value;
end;
end.
Das ganze wird nun in einem Fenster (natürlich mit Listbox und Button) aufgerufen (Ich habe hier nur mal den interessanten Code eingefügt):
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
// wir nehmen direkt die abgeleitete Klasse
myPropChild : TPropChild;
begin
// erstmal das Objekt erzeugen
myPropChild := TPropChild.Create;
// Listbox füllen
myPropChild.FillPropsInListBox(ListBox1);
// Objekt freigeben
myPropChild.Free;
end;
Damit Ihr den ganzen Spass mal zu Hause ausprobieren könnt habe ich das Beispielprojekt einfach mal an diesen Beitrag gehängt.
Frank
[edit=Matze]Code formatiert. Mfg, Matze[/edit]