使用Typinfo单元,可以轻松枚举属性,如以下代码段所示:
procedure TYRPropertiesMap.InitFrom(AClass: TClass; InheritLevel: Integer = 0);
var
propInfo: PPropInfo;
propCount: Integer;
propList: PPropList;
propType: PPTypeInfo;
pm: TYRPropertyMap;
classInfo: TClassInfo;
ix: Integer;
begin
ClearMap;
propCount := GetPropList(PTypeInfo(AClass.ClassInfo), propList);
for ix := 0 to propCount - 1 do
begin
propInfo := propList^[ix];
propType := propInfo^.PropType;
if propType^.Kind = tkMethod then
Continue; // Skip methods
{ Need to get GetPropInheritenceIndex to work
if GetPropInheritenceIndex(propInfo) > InheritLevel then
Continue; // Dont include properties deeper than InheritLevel
}
pm := TYRPropertyMap.Create(propInfo.Name);
FList.Add(pm);
end;
end;
但是,我需要的是弄清楚每个属性继承的确切类。 例如,在TControl中,Tag属性来自TComponent,它给它的继承深度为1(0是在TControl本身中声明的属性,例如Cursor)。
如果我知道哪个类首先定义了属性,那么计算继承深度很容易。就我的目的而言,无论财产首次获得公布的知名度,它都是首次出现的地方。
我正在使用Delphi 2007.如果需要更多详细信息,请告诉我。所有帮助将不胜感激。
答案 0 :(得分:4)
这对我有用。
关键是从传递的子类型TypeInfo
procedure InheritanceLevel(AClassInfo: PTypeInfo; const AProperty: string; var level: Integer);
var
propInfo: PPropInfo;
propCount: Integer;
propList: PPropList;
ix: Integer;
begin
if not Assigned(AClassInfo) then Exit;
propCount := GetPropList(AClassInfo, propList);
for ix := 0 to propCount - 1 do
begin
propInfo := propList^[ix];
if propInfo^.Name = AProperty then
begin
Inc(level);
InheritanceLevel(GetTypeData(AClassInfo).ParentInfo^, AProperty, level)
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
level: Integer;
begin
level := 0;
InheritanceLevel(PTypeInfo(TForm.ClassInfo), 'Tag', level);
end;
答案 1 :(得分:2)
我不知道您是否可以使用Delphi 2007中提供的RTTI找到它.TComponent树中的大多数属性在原始类中声明为 protected ,然后重新声明为发布进一步向下,您只有已发布成员的RTTI。
当我看到他打败了我时,我正确地描述了与列文的解决方案非常相似的东西。这将找到发布该属性的第一个类,如果这是您要查找的内容,但它找不到该属性最初声明的位置。如果需要,您需要Delphi 2010的扩展RTTI。