Reputation: 1117
When I define a class like this in Delphi 7:
TPerson = class(TObject)
private
FLName: string;
FFName: string;
FAge: integer;
FBDate: TDate;
public
published
property FName: string read FFName write FFName;
property LName: string read FLName write FLName;
property Age: integer read FAge write FAge;
property BDate: TDate read FBDate write FBDate;
end;
procedure ListComponentProperties(AObject: TObject; Strings: TStrings);
var
Count, Size, I: Integer;
List: PPropList;
PropInfo: PPropInfo;
PropValue: string;
begin
Count := GetPropList(AObject.ClassInfo, tkAny, List);
Size := Count * SizeOf(Pointer);
GetMem(List, Size);
try
Count := GetPropList(AObject.ClassInfo, tkAny, List);
for I := 0 to Count - 1 do
begin
PropInfo := List^[I];
PropValue := VarToStr(GetPropValue(AObject, PropInfo^.Name));
end;
finally
FreeMem(List);
end;
end;
and I want to get a list of its published properties with ListComponentProperties an error message will be displayed.The error is related to the following command and AObject.ClassInfo:
Count := GetPropList(AObject.ClassInfo, tkAny, List);
Any help would be greatly appreciated.
Upvotes: 0
Views: 2069
Reputation: 28540
In addition to using $M
compiler directive, you can derive your classes from any class that has RTTI info enabled.
One of such classes is TPersistent that should be used as base class for any class that needs to have assignment and streaming capabilities.
TPersistent encapsulates the behavior common to all objects that can be assigned to other objects, and that can read and write their properties to and from a form file (.xfm or .dfm file).
Do not create instances of TPersistent. Use TPersistent as a base class when declaring objects that are not components, but that need to be saved to a stream or have their properties assigned to other objects.
In practice that means that if you want to use TPerson
class as published property of some component that can be edited in IDE via Object Inspector and streamed to form file (.dfm
) your class must have TPersistent
as ancestor in it's class hierarchy.
type
TPersonComponent = class(TComponent)
protected
FPerson: TPerson;
procedure SetPerson(AValue: TPerson);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Person: TPerson read FPerson write SetPerson;
end;
constructor TPersonComponent.Create(AOwner: TComponent);
begin
inherited;
FPerson := TPerson.Create;
end;
destructor TPersonComponent.Destroy;
begin
FPerson.Free;
inherited;
end;
procedure TPersonComponent.SetPerson(AValue: TPerson);
begin
FPerson.Assign(AValue);
end;
If you use class declared as TPerson = class(TObject)
in above example, its properties (even though published and with RTTI information turned on) will not be saved into .dfm
file when TPersonComponent
is edited in Object Inspector.
Upvotes: 2
Reputation: 613461
You have to enable RTTI for that type. By default it is not enabled. Declare the type like this:
type
{$M+}
TPerson = class(TObject)
....
end;
{$M-}
Your initial call to GetPropList
is also wrong. It must read:
Count := GetPropList(AObject.ClassInfo, tkAny, nil);
If you enabled warnings the compiler would have told you that you were passing an uninitialized variable.
I've not checked any more of your code. There may be more errors.
Upvotes: 2