procedure GetClassProperties(AClass: TObject; AStrings: TStrings); var PropList: PPropList; ClassTypeInfo: PTypeInfo; ClassTypeData: PTypeData; I: integer; NumProps: Integer; begin ClassTypeInfo := AClass.ClassInfo; ClassTypeData := GetTypeData(ClassTypeInfo); if ClassTypeData.PropCount <> 0 then begin GetMem(PropList, SizeOf(PPropInfo) * ClassTypeData.PropCount); try GetPropInfos(AClass.ClassInfo, PropList); for I := 0 to ClassTypeData.PropCount - 1 do if not (PropList[I]^.PropType^.Kind = tkMethod) then AStrings.Add(Format('%s: %s(%s)', [PropList[I]^.Name, PropList[I]^.PropType^.Name, VarToStr(GetPropValue(AClass, PropList[I]^.Name))])); NumProps := GetPropList(AClass.ClassInfo, [tkMethod], PropList); if NumProps <> 0 then begin AStrings.Add(''); AStrings.Add(' EVENTS ================ '); AStrings.Add(''); end;
for I := 0 to NumProps - 1 do begin AStrings.Add(Format('%s: %s(%s)', [PropList[I]^.Name, PropList[I]^.PropType^.Name, AClass.MethodName(GetMethodProp(AClass, PropList[I]).Code)])); end; finally FreeMem(PropList, SizeOf(PPropInfo) * ClassTypeData.PropCount); end; end; end;
恩,就是RTTI的机制了。 给一段以前参考别人代码写的得到类事件函数头的代码 function GetEventHandle(EventObj: TObject; EventName: string): string; type TParamRec = record Flags: TParamFlags; ParamName: ShortString; TypeName: ShortString; end; pParamRec = ^TParamRec; function GetFlags(Flags: TParamFlags): string; var i: integer; begin for i := 0 to 5 do begin if i = 3 then Continue; if TParamFlag(i) in Flags then Result := Copy(GetEnumName(TypeInfo(TParamFlag),i),3,MaxInt) + ' '; end; end; var propInfo: PPropInfo; TypeData: PTypeData; pTypeStr: PShortString; Param: pParamRec; i: integer; begin propInfo := GetPropInfo(EventObj,EventName); if propInfo <> nil then begin TypeData := GetTypeData(PropInfo^.PropType^); if TypeData <> nil then begin Param := pParamRec(@TypeData^.ParamList); result := 'Procedure '+PropInfo^.Name+'('; for i := 0 to TypeData^.ParamCount - 1 do begin result := Result + GetFlags(Param^.Flags) + Param^.ParamName; pTypeStr := pShortString(Integer(@Param^.ParamName)+Length(Param^.ParamName)+1); result := Result + ': '+ pTypeStr^ ; if i <> TypeData^.ParamCount - 1 then result := result + '; ' else result := Result + ');'; Param := PParamRec(Integer(@Param^.ParamName)+Length(Param^.ParamName) + Length(pTypeStr^)+2); end; end; end; end;
procedure GetClassProperties(AClass: TObject; AStrings: TStrings);
var
PropList: PPropList;
ClassTypeInfo: PTypeInfo;
ClassTypeData: PTypeData;
I: integer;
NumProps: Integer;
begin
ClassTypeInfo := AClass.ClassInfo;
ClassTypeData := GetTypeData(ClassTypeInfo);
if ClassTypeData.PropCount <> 0 then
begin
GetMem(PropList, SizeOf(PPropInfo) * ClassTypeData.PropCount);
try
GetPropInfos(AClass.ClassInfo, PropList);
for I := 0 to ClassTypeData.PropCount - 1 do
if not (PropList[I]^.PropType^.Kind = tkMethod) then
AStrings.Add(Format('%s: %s(%s)',
[PropList[I]^.Name, PropList[I]^.PropType^.Name,
VarToStr(GetPropValue(AClass, PropList[I]^.Name))]));
NumProps := GetPropList(AClass.ClassInfo, [tkMethod], PropList);
if NumProps <> 0 then
begin
AStrings.Add('');
AStrings.Add(' EVENTS ================ ');
AStrings.Add('');
end;
for I := 0 to NumProps - 1 do
begin
AStrings.Add(Format('%s: %s(%s)', [PropList[I]^.Name,
PropList[I]^.PropType^.Name,
AClass.MethodName(GetMethodProp(AClass, PropList[I]).Code)]));
end;
finally
FreeMem(PropList, SizeOf(PPropInfo) * ClassTypeData.PropCount);
end;
end;
end;
Delphi 的RTTI机制浅探
给一段以前参考别人代码写的得到类事件函数头的代码
function GetEventHandle(EventObj: TObject; EventName: string): string;
type
TParamRec = record
Flags: TParamFlags;
ParamName: ShortString;
TypeName: ShortString;
end;
pParamRec = ^TParamRec;
function GetFlags(Flags: TParamFlags): string;
var
i: integer;
begin
for i := 0 to 5 do
begin
if i = 3 then Continue;
if TParamFlag(i) in Flags then
Result := Copy(GetEnumName(TypeInfo(TParamFlag),i),3,MaxInt) + ' ';
end;
end;
var
propInfo: PPropInfo;
TypeData: PTypeData;
pTypeStr: PShortString;
Param: pParamRec;
i: integer;
begin
propInfo := GetPropInfo(EventObj,EventName);
if propInfo <> nil then
begin
TypeData := GetTypeData(PropInfo^.PropType^);
if TypeData <> nil then
begin
Param := pParamRec(@TypeData^.ParamList);
result := 'Procedure '+PropInfo^.Name+'(';
for i := 0 to TypeData^.ParamCount - 1 do
begin
result := Result + GetFlags(Param^.Flags) + Param^.ParamName;
pTypeStr := pShortString(Integer(@Param^.ParamName)+Length(Param^.ParamName)+1);
result := Result + ': '+ pTypeStr^ ;
if i <> TypeData^.ParamCount - 1 then
result := result + '; '
else result := Result + ');';
Param := PParamRec(Integer(@Param^.ParamName)+Length(Param^.ParamName) + Length(pTypeStr^)+2);
end;
end;
end;
end;
并把所有的相关事件列出来(例:Tbutton.onClick列表下可能有Button1Click,Button2Click,Button3Click等).
请各位CSND高手解答一下,谢谢.
我在8楼已经将一个事件过程的过程头如
procedure BtnClick(Sender: TObject);
这样的过程头写出来了,应该匹配起来不是难事吧!