我们可以使用 GetPropList 获得所有属性信息的指针数组,数组用完以后要记得用 FreeMem 把数组的内存清除。
{ TypInfo.pas }
function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): Integer;
GetPropList 传入类的 TTypeInfo 指针和 TPropList 的指针,它为 PropList 分配一块内存后把该内存填充为指向 TPropInfo 的指针数组,最后返回属性的数量。
上面的例子演示了如何获得类的所有属性信息,也可以根据属性的名称单独获得属性信息:
{ TypInfo.pas }
function GetPropInfo(TypeInfo: PTypeInfo; const PropName: string): PPropInfo;
GetPropInfo 根据类的 RTTI 指针和属性的名称字符串,返回属性的信息 TPropInfo 的指针。如果没有找到该属性,则返回 nil。GetPropInfo 很容易使用,举个例子:
ShowMessage(GetPropInfo(TForm, ''Name'')^.PropType^.Name);
这句调用显示了 TForm 类的 Name 属性的类型名称:TComponentName。
===============================================================================
⊙ 获取方法(method)的类型信息
===============================================================================
所谓方法就是以 of object 关键字声明的函数指针,下面的函数可以显示一个方法的类型信息:
procedure GetMethodTypeInfo(ATypeInfo: PTypeInfo; AStrings: TStrings);
type
PParamData = ^TParamData;
TParamData = record // 函数参数的数据结构
Flags: TParamFlags; // 参数传递规则
ParamName: ShortString; // 参数的名称
TypeName: ShortString; // 参数的类型名称
end;
function GetParamFlagsName(AParamFlags: TParamFlags): string;
var
I: Integer;
begin
Result := '''';
for I := Integer(pfVar) to Integer(pfOut) do begin
if I = Integer(pfAddress) then Continue;
if TParamFlag(I) in AParamFlags then
Result := Result + '' '' + GetEnumName(TypeInfo(TParamFlag), I);
end;
end;
var
MethodTypeData: PTypeData;
ParamData: PParamData;
TypeStr: PShortString;
I: Integer;
begin
MethodTypeData := GetTypeData(ATypeInfo);
AStrings.Add(''---------------------------------'');
AStrings.Add(''Method Name: '' + ATypeInfo^.Name);
AStrings.Add(''Method Kind: '' + GetEnumName(TypeInfo(TMethodKind),
Integer(MethodTypeData^.MethodKind)));
AStrings.Add(''Params Count: ''+ IntToStr(MethodTypeData^.ParamCount));
AStrings.Add(''Params List:'');
ParamData := PParamData(@MethodTypeData^.ParamList);
for I := 1 to MethodTypeData^.ParamCount do
begin
TypeStr := Pointer(Integer(@ParamData^.ParamName) +
Length(ParamData^.ParamName) + 1);
AStrings.Add(Format('' [%s] %s: %s'',[GetParamFlagsName(ParamData^.Flags),
ParamData^.ParamName, TypeStr^]));
ParamData := PParamData(Integer(ParamData) + SizeOf(TParamFlags) +
Length(ParamData^.ParamName) + Length(TypeStr^) + 2);
end;
if MethodTypeData^.MethodKind = mkFunction then
AStrings.Add(''Result Value: '' + PShortString(ParamData)^);
end;
作为实验,在表单上放置一个 TListBox,然后执行以下代码,观察执行结果:
type
TMyMethod = function(A: array of Char; var B: TObject): Integer of object;
procedure TForm1.FormCreate(Sender: TObject);
begin
GetMethodTypeInfo(TypeInfo(TMyMethod), ListBox1.Items);
GetMethodTypeInfo(TypeInfo(TMouseEvent), ListBox1.Items);
GetMethodTypeInfo(TypeInfo(TKeyPressEvent), ListBox1.Items);
GetMethodTypeInfo(TypeInfo(