Delphi RTTI でプロパティ名や型を再帰で取得

RTTIを用いて、プロパティの設定値をそのままファイルなどへ保存しようとしたが、項目がTFont等のクラスだったりすると中身を取得する必要があるので、再帰で取得
まぁ、できるにはできたんですが、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;

コメント