7

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 を使用しています。詳細が必要な場合はお知らせください。すべての助けに感謝します。

4

2 に答える 2

4

これは私にとってはうまくいきます。
重要なのは、渡された子 TypeInfo から親の 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;
于 2009-10-14T11:25:06.793 に答える
2

Delphi 2007 で利用可能な RTTI を使用してこれを見つけることができるかどうかはわかりません。TComponent ツリーのほとんどのプロパティは、元のクラスで保護されていると宣言され、さらに下にある公開済みとして再宣言されます。公開されたメンバーの RTTI しかありません。

Lieven のソリューションに非常によく似たものを説明しようとしたとき、彼が私を打ち負かしたことがわかりました。これは、探しているものであれば、プロパティが発行された最初のクラスを見つけますが、プロパティが最初に宣言された場所は見つけられません。必要な場合は、Delphi 2010 の拡張 RTTI が必要です。

于 2009-10-14T11:28:36.470 に答える