Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2016年12月23日] [更新 2016年12月23日] Delphi サンプルプログラム集
458_RTTI ( 実行時型情報 ) を使用したプロパティの列挙
動作確認等 Windows 7 U64(SP1) + Delphi XE5(UP2) Pro
458_RTTI_Properties.zip 904 KB] 2016年12月23日版 (EXE 同梱)







01_RTTI を使用して指定クラスのプロパティを列挙


RTTI を使用すると,クラスやレコードのメソッドのプロパティの情報の操作も可能です.以下は,指定クラスのプロパティの名前を列挙する例です.

このサンプルコードは,拙作の TplSetPrinter コンポーネントのプロパティを列挙します.このコードで取得可能なのは,public または published なプロパティだけです.Rtti.TRttiProperty のメンバを使用すると,プロパティの実装の有無を確認したり,プロパティの取得や設定ができます.



図1
TplSetPrinter コンポのプロパティ一覧
  • 設計時に拙作の TplSetPrinter コンポーネントをフォームに配置している
  • 継承元のプロパティも含まれている
図2
TplSetPrinter コンポで追加したプロパティだけを列挙した結果

リスト1
RTTI を使用して指定クラスのプロパティ名を列挙
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, plSetPrinter;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    Label1: TLabel;
    CheckBox1: TCheckBox;
    plSetPrinter1: TplSetPrinter;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  RTTI,
  TypInfo;

{$R *.DFM}

//=============================================================================
//  継承元のクラスのプロパティも含めて列挙
//  TRttiType.GetPropertiesでプロパティのリストを取得する
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LRttiContext  : TRttiContext;
  LRttiType     : TRttiType;
  LProperties   : TArray<TRttiProperty>;
  LRttiProperty : TRttiProperty;
  LCount        : Integer;
begin
  ListBox1.Items.Clear;
  LCount := 0;

  LRttiType := LRttiContext.GetType(TypeInfo(TplSetPrinter));

  ListBox1.Items.BeginUpdate;
  if Assigned(LRttiType) then begin
    LProperties := LRttiType.GetProperties;

    for LRttiProperty in LProperties do begin
      inc(LCount);
      if CheckBox1.Checked then begin
        ListBox1.Items.Add(LRttiProperty.Name);
      end else begin
        ListBox1.Items.Add(LRttiProperty.ToString);
      end;
    end;
  end;
  ListBox1.Items.EndUpdate;

  Label1.Caption := IntToStr(LCount);
end;

//=============================================================================
//  現在のクラスで追加したプロパティのみを取得
//  TRttiType.GetDeclaredPropertiesでプロパティのリストを取得する
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LRttiContext  : TRttiContext;
  LRttiType     : TRttiType;
  LProperties   : TArray<TRttiProperty>;
  LRttiProperty : TRttiProperty;
  LCount        : Integer;
begin
  ListBox1.Items.Clear;
  LCount := 0;

  LRttiType := LRttiContext.GetType(TypeInfo(TplSetPrinter));

  ListBox1.Items.BeginUpdate;
  if Assigned(LRttiType) then begin
    LProperties := LRttiType.GetDeclaredProperties;

    for LRttiProperty in LProperties do begin
      inc(LCount);
      if CheckBox1.Checked then begin
        ListBox1.Items.Add(LRttiProperty.Name);
      end else begin
        ListBox1.Items.Add(LRttiProperty.ToString);
      end;
    end;
  end;
  ListBox1.Items.EndUpdate;

  Label1.Caption := IntToStr(LCount);
end;

end.