Listando as propriedades de uma classe
Segue um código (pascal/Delphi) que criei para listar as propriedades que pertencem a uma classe.
O código usa a RTTI do Delphi para “percorrer” as propriedades. A procedure é recursiva, ou seja, se uma das propriedades for também um classe, a procedure chama ela mesma passando como parâmetro a classe da propriedade encontrada.
Para compilar o código abaixo, crie uma nova aplicação VCL e no form principal coloque um TMemo e um TButton, e configure os eventos conforme o código abaixo.
Substitua o segundo parâmetro da chamada a getPropList pela classe que deseja “vasculhar”. O terceiro parâmetro é o quão “profundo” você deseja ir em relação as iterações quando uma propriedade encontrada for uma classe.
Clique no botão e o Memo será preenchido com as propriedades da classe TButton, obtendo o seguinte resultado para um máximo de uma iteração:
Action Align Anchors BiDiMode Cancel Caption CommandLinkHint Constraints Default DisabledImageIndex DoubleBuffered DragCursor DragKind DragMode DropDownMenu ElevationRequired Enabled Font HotImageIndex ImageAlignment ImageIndex ImageMargins Images ModalResult ParentBiDiMode ParentDoubleBuffered ParentFont ParentShowHint PopupMenu PressedImageIndex SelectedImageIndex ShowHint Style StylusHotImageIndex TabOrder TabStop Visible WordWrap StyleElements
E para o máximo de 2 iterações:
Action Action.ActionComponent Align Anchors BiDiMode Cancel Caption CommandLinkHint Constraints Constraints.MaxHeight Constraints.MaxWidth Constraints.MinHeight Constraints.MinWidth Default DisabledImageIndex DoubleBuffered DragCursor DragKind DragMode DropDownMenu DropDownMenu.PopupComponent DropDownMenu.PopupPoint DropDownMenu.Alignment DropDownMenu.AutoHotkeys DropDownMenu.AutoLineReduction DropDownMenu.AutoPopup DropDownMenu.BiDiMode DropDownMenu.HelpContext DropDownMenu.Images DropDownMenu.MenuAnimation DropDownMenu.OwnerDraw DropDownMenu.ParentBiDiMode DropDownMenu.TrackButton ElevationRequired Enabled Font Font.FontAdapter Font.Handle Font.PixelsPerInch Font.Charset Font.Color Font.Height Font.Name Font.Orientation Font.Pitch Font.Size Font.Style Font.Quality HotImageIndex ImageAlignment ImageIndex ImageMargins ImageMargins.Left ImageMargins.Top ImageMargins.Right ImageMargins.Bottom Images Images.Handle Images.AllocBy Images.BlendColor Images.GrayscaleFactor Images.BkColor Images.DrawingStyle Images.Height Images.ImageType Images.Masked Images.ShareImages Images.Width Images.ColorDepth ModalResult ParentBiDiMode ParentDoubleBuffered ParentFont ParentShowHint PopupMenu PopupMenu.PopupComponent PopupMenu.PopupPoint PopupMenu.Alignment PopupMenu.AutoHotkeys PopupMenu.AutoLineReduction PopupMenu.AutoPopup PopupMenu.BiDiMode PopupMenu.HelpContext PopupMenu.Images PopupMenu.MenuAnimation PopupMenu.OwnerDraw PopupMenu.ParentBiDiMode PopupMenu.TrackButton PressedImageIndex SelectedImageIndex ShowHint Style StylusHotImageIndex TabOrder TabStop Visible WordWrap StyleElements
Espero que seja útil para alguém 🙂
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
procedure getPropList(Base: string; Classe: TClass; MaxIterations: integer);
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
System.RTTI;
var
Ctx: TRttiContext;
procedure TForm1.FormCreate(Sender: TObject);
begin
Ctx := TRttiContext.Create;
Memo1.Lines.Clear;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Ctx.free;
end;
function Formata(Base, s: string): string;
begin
if Base <> '' then
Result := Base + '.' + s
else
Result := s;
end;
procedure TForm1.getPropList(Base: string; Classe: TClass; MaxIterations: integer);
var
T: TRttiType;
P: TRttiProperty;
begin
T := Ctx.GetType(Classe);
for P in T.GetDeclaredProperties do
begin
if P.PropertyType.TypeKind = tkMethod then // Não queremos extrair os métodos
continue;
Memo1.Lines.Add(Formata(Base, P.Name));
if (P.PropertyType.TypeKind = tkClass) and (P.Name <> 'Owner') and (P.Name <> 'Parent') then
begin
Dec(MaxIterations);
if MaxIterations > 0 then
getPropList(Formata(Base, P.Name), P.PropertyType.AsInstance.MetaclassType, MaxIterations);
Inc(MaxIterations);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
getPropList('', TButton { Coloque a classe que deseja extrair as propriedades }, 2 {Qual o máximo de interações});
end;
end.