Delphi RTTI でプロパティ名や型を再帰で取得
RTTIを用いて、プロパティの設定値をそのままファイルなどへ保存しようとしたが、項目がTFont等のクラスだったりすると中身を取得する必要があるので、再帰で取得
まぁ、できるにはできたんですが、Parent Child のような互いに参照する項目があると、循環が起きてしまうので、レベル(深さ)制限や除外リストなどが用途によって必要かもしれません
また、値がnilの項目は型を特定できないため、配下を参照できません(取得時には問題ないかも)
フォームへ Memo1(TMemo) と Button1(TButton)を貼り付けて、作成した ListProperties 関数で Button1 のプロパティを参照しています
uses へ System.Rtti を追加してください
まぁ、できるにはできたんですが、Parent Child のような互いに参照する項目があると、循環が起きてしまうので、レベル(深さ)制限や除外リストなどが用途によって必要かもしれません
また、値がnilの項目は型を特定できないため、配下を参照できません(取得時には問題ないかも)
フォームへ Memo1(TMemo) と Button1(TButton)を貼り付けて、作成した ListProperties 関数で Button1 のプロパティを参照しています
uses へ System.Rtti を追加してください
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Lines.Clear;
ListProperties(Button1);
end;
procedure TForm1.ListProperties(Obj: TObject; Level: Integer = 0);
var
RttiContext: TRttiContext;
RttiType: TRttiType;
RttiProp: TRttiProperty;
begin
if (Obj = nil) then begin
Exit;
end;
if (Level > 3) then begin
// Exit;
end;
RttiContext := TRttiContext.Create;
try
RttiType := RttiContext.GetType(Obj.ClassInfo);
for RttiProp in RttiType.GetProperties do begin
Memo1.Lines.Add(StringOfChar(#9, Level) + RttiProp.Name + ': ' + RttiProp.PropertyType.ToString);
// 除外
if SameStr(RttiProp.PropertyType.ToString, 'TComponent') then Continue;
if SameStr(RttiProp.PropertyType.ToString, 'TWinControl') then Continue;
// tkClass は再帰
if (RttiProp.PropertyType.TypeKind = tkClass) then begin
ListProperties(RttiProp.GetValue(Obj).AsObject, Level + 1);
end;
end;
finally
RttiContext.Free;
end;
end;

コメント