unit Unit_main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, TypInfo; type TForm_main = class(TForm) Button1: TButton; Memo1: TMemo; Memo2: TMemo; Button2: TButton; Button3: TButton; Button4: TButton; Button5: TButton; Button6: TButton; Button7: TButton; Button8: TButton; Button9: TButton; Button10: TButton; Button11: TButton; Button12: TButton; Button13: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button5Click(Sender: TObject); procedure Button6Click(Sender: TObject); procedure Button7Click(Sender: TObject); procedure Button8Click(Sender: TObject); procedure Button9Click(Sender: TObject); procedure Button10Click(Sender: TObject); procedure Button11Click(Sender: TObject); procedure Button12Click(Sender: TObject); procedure Button13Click(Sender: TObject); private { Private declarations } public { Public declarations } end; PTKeyDog = ^TKeyDog; TKeyDog = record id: Integer; projectname: string; city: string; letter: string; hash: string; code: string; note: string; filepath: string; userid: Integer; end; { 自定义的类 } TMyClass = class(TComponent) public procedure msg(const str: string); function Add(const a, b: Integer): Integer; end; // 编译指令 Methodinfo 是 Delphi 2009 新增的, 只有它打开了, ObjAuto 才可以获取 public 区的信息. // 这样, ObjAuto 可以获取 TClass3 的 public、published 和默认区域的信息. {$M+} {$METHODINFO ON} TClass3 = class function Fun3: string; private function Fun3Private: string; protected function Fun3Protected: string; public function Fun3Public: string; published function Fun3Published: string; end; {$METHODINFO OFF} {$M-} var Form_main: TForm_main; implementation uses Rtti, ObjAuto; {$R *.dfm} // 获取对象的 RTTI 属性与事件的函数 function GetPropertyAndEventList(obj: TObject; pList, eList: TStringList): Boolean; var ClassTypeInfo: PTypeInfo; { 类的信息结构指针 } ClassDataInfo: PTypeData; { 类的数据结构指针 } propertyList: PPropList; { TPropInfo 是属性的数据结构; PPropList 是其指针; TPropList 是属性结构指针的列表数组; PPropList 是指向这个数组的指针 } num: Integer; { 记录属性的总数 } size: Integer; { 记录属性结构的大小 } i: Integer; begin ClassTypeInfo := obj.ClassInfo; { 先获取: 类的信息结构指针 } ClassDataInfo := GetTypeData(ClassTypeInfo); { 再获取: 类的数据结构指针 } num := ClassDataInfo.PropCount; { 属性总数 } size := SizeOf(TPropInfo); { 属性结构大小 } GetMem(propertyList, size * num); { 给属性数组分配内存 } GetPropInfos(ClassTypeInfo, propertyList); { 获取属性列表 } for i := 0 to num - 1 do begin if propertyList[i].PropType^.Kind = tkMethod then { 如果是事件; 事件也是属性吗, 给分出来 } eList.Add(propertyList[i].Name) else pList.Add(propertyList[i].Name); end; pList.Sort; eList.Sort; { 排序 } FreeMem(propertyList); { 释放属性数组的内存 } Result := True; end; procedure TForm_main.Button10Click(Sender: TObject); var obj: TMyClass; t: TRttiType; m1, m2: TRttiMethod; r: TValue; // TRttiMethod.Invoke 的返回类型 begin t := TRttiContext.Create.GetType(TMyClass); { 获取 TMyClass 类的两个方法 } m1 := t.GetMethod('msg'); { procedure } m2 := t.GetMethod('Add'); { function } obj := TMyClass.Create(Self); { 调用需要依赖一个已存在的对象 } { 调用 msg 过程 } m1.Invoke(obj, ['Delphi 2010']); { 将弹出信息框 } { 调用 Add 函数 } r := m2.Invoke(obj, [1, 2]); { 其返回值是个 TValue 类型的结构 } ShowMessage(IntToStr(r.AsInteger)); { 3 } obj.Free; end; procedure TForm_main.Button11Click(Sender: TObject); var obj: TMyClass; t: TRttiType; p: TRttiProperty; r: TValue; begin obj := TMyClass.Create(Self); t := TRttiContext.Create.GetType(TMyClass); p := t.GetProperty('Name'); // 继承自TComponent的name r := p.GetValue(obj); ShowMessage(r.AsString); { 原来的 } p.SetValue(obj, 'NewName'); r := p.GetValue(obj); ShowMessage(r.AsString); { NewName } obj.Free; end; procedure TForm_main.Button12Click(Sender: TObject); var t: TRttiType; p: TRttiProperty; r: TValue; begin t := TRttiContext.Create.GetType(TButton); p := t.GetProperty('Align'); p.SetValue(Button1, TValue.FromOrdinal(TypeInfo(TAlign), Ord(alLeft))); r := p.GetValue(Button1); ShowMessage(IntToStr(r.AsOrdinal)); { 3 } end; procedure TForm_main.Button13Click(Sender: TObject); var MiArr: TMethodInfoArray; Mi: PMethodInfoHeader; obj: TClass3; begin obj := TClass3.Create; MiArr := GetMethods(obj.ClassType); Memo1.Clear; for Mi in MiArr do Memo1.Lines.Add(string(Mi.Name)); obj.Free; end; procedure TForm_main.Button1Click(Sender: TObject); var propertyL, EventL: TStringList; begin // 属性 propertyL := TStringList.Create; // 事件 EventL := TStringList.Create; Memo1.Clear; Memo2.Clear; GetPropertyAndEventList(Self, propertyL, EventL); { 调用函数, 第一个参数是对象名 } Memo1.Lines := propertyL; Memo2.Lines := EventL; propertyL.Free; EventL.Free; end; procedure TForm_main.Button2Click(Sender: TObject); var ctx: TRttiContext; t: TRttiType; begin Memo1.Clear; for t in ctx.GetTypes do Memo1.Lines.Add(t.Name); end; procedure TForm_main.Button3Click(Sender: TObject); var ctx: TRttiContext; t: TRttiType; m: TRttiMethod; begin Memo1.Clear; t := ctx.GetType(TButton); // for m in t.GetMethods do Memo1.Lines.Add(m.Name); for m in t.GetMethods do Memo1.Lines.Add(m.ToString); end; procedure TForm_main.Button4Click(Sender: TObject); var ctx: TRttiContext; t: TRttiType; p: TRttiProperty; begin Memo1.Clear; t := ctx.GetType(TButton); // for p in t.GetProperties do Memo1.Lines.Add(p.Name); for p in t.GetProperties do Memo1.Lines.Add(p.ToString); end; procedure TForm_main.Button5Click(Sender: TObject); var ctx: TRttiContext; t: TRttiType; f: TRttiField; begin Memo1.Clear; t := ctx.GetType(TButton); // for f in t.GetFields do Memo1.Lines.Add(f.Name); for f in t.GetFields do Memo1.Lines.Add(f.ToString); end; // http://my.oschina.net/hermer/blog/320075 procedure TForm_main.Button6Click(Sender: TObject); var ctx: TRttiContext; t: TRttiType; ms: TArray<TRttiMethod>; ps: TArray<TRttiProperty>; fs: TArray<TRttiField>; begin Memo1.Clear; t := ctx.GetType(TButton); ms := t.GetMethods; ps := t.GetProperties; fs := t.GetFields; Memo1.Lines.Add(Format('%s 类共有 %d 个方法', [t.Name, Length(ms)])); Memo1.Lines.Add(Format('%s 类共有 %d 个属性', [t.Name, Length(ps)])); Memo1.Lines.Add(Format('%s 类共有 %d 个字段', [t.Name, Length(fs)])); end; procedure TForm_main.Button7Click(Sender: TObject); var t: TRttiRecordType; f: TRttiField; begin Memo1.Clear; t := TRttiContext.Create.GetType(TypeInfo(TPoint)).AsRecord; Memo1.Lines.Add(t.QualifiedName); Memo1.Lines.Add(Format('Size: %d', [t.TypeSize])); Memo1.Lines.Add(EmptyStr); Memo1.Lines.Add(Format('字段数: %d', [Length(t.GetFields)])); Memo1.Lines.Add(Format('方法数: %d', [Length(t.GetMethods)])); Memo1.Lines.Add(Format('属性数: %d', [Length(t.GetProperties)])); Memo1.Lines.Add(EmptyStr); Memo1.Lines.Add('全部字段:'); for f in t.GetFields do Memo1.Lines.Add(f.ToString); end; procedure TForm_main.Button8Click(Sender: TObject); var t: TRttiRecordType; f: TRttiField; begin Memo1.Clear; t := TRttiContext.Create.GetType(TypeInfo(TKeyDog)).AsRecord; Memo1.Lines.Add(t.QualifiedName); Memo1.Lines.Add(Format('Size: %d', [t.TypeSize])); Memo1.Lines.Add(EmptyStr); Memo1.Lines.Add(Format('字段数: %d', [Length(t.GetFields)])); Memo1.Lines.Add(Format('方法数: %d', [Length(t.GetMethods)])); Memo1.Lines.Add(Format('属性数: %d', [Length(t.GetProperties)])); Memo1.Lines.Add(EmptyStr); Memo1.Lines.Add('全部字段:'); for f in t.GetFields do Memo1.Lines.Add(f.ToString); end; procedure TForm_main.Button9Click(Sender: TObject); var t: TRttiOrdinalType; begin Memo1.Clear; // 先从类型名获取类型信息对象 t := TRttiContext.Create.GetType(TypeInfo(Byte)) as TRttiOrdinalType; Memo1.Lines.Add(Format('%s - %s', [t.Name, t.QualifiedName])); Memo1.Lines.Add(Format('Size: %d', [t.TypeSize])); Memo1.Lines.Add('QualifiedName: ' + t.QualifiedName); Memo1.Lines.Add(Format('Min,Max: %d , %d', [t.MinValue, t.MaxValue])); Memo1.Lines.Add(EmptyStr); // 空字串 // 可以用 AsOrdinal 方法代替前面的 as TRttiOrdinalType t := TRttiContext.Create.GetType(TypeInfo(Word)).AsOrdinal; Memo1.Lines.Add(Format('%s: %s', [t.Name, t.QualifiedName])); Memo1.Lines.Add(Format('Size: %d', [t.TypeSize])); Memo1.Lines.Add(Format('Min,Max: %d , %d', [t.MinValue, t.MaxValue])); Memo1.Lines.Add(EmptyStr); // 也可以直接强制转换 t := TRttiOrdinalType(TRttiContext.Create.GetType(TypeInfo(Integer))); Memo1.Lines.Add(Format('%s: %s', [t.Name, t.QualifiedName])); Memo1.Lines.Add(Format('Size: %d', [t.TypeSize])); Memo1.Lines.Add(Format('Min,Max: %d , %d', [t.MinValue, t.MaxValue])); Memo1.Lines.Add(EmptyStr); end; { TMyClass } function TMyClass.Add(const a, b: Integer): Integer; begin Result := a + b; end; procedure TMyClass.msg(const str: string); begin MessageDlg(str, mtInformation, [mbYes], 0); end; { TClass3 } function TClass3.Fun3: string; begin Result := 'Fun3'; end; function TClass3.Fun3Private: string; begin Result := 'Fun3Private'; end; function TClass3.Fun3Protected: string; begin Result := 'Fun3Protected'; end; function TClass3.Fun3Public: string; begin Result := 'Fun3Public'; end; function TClass3.Fun3Published: string; begin Result := 'Fun3Published'; end; end.
object Form_main: TForm_main Left = 0 Top = 0 Caption = 'delphi RTTI '#21453#23556#25216#26415 ClientHeight = 523 ClientWidth = 804 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False PixelsPerInch = 96 TextHeight = 13 object Button1: TButton Left = 8 Top = 8 Width = 97 Height = 25 Caption = 'rtti '#21453#23556 TabOrder = 0 OnClick = Button1Click end object Memo1: TMemo Left = 8 Top = 175 Width = 537 Height = 287 ScrollBars = ssBoth TabOrder = 1 end object Memo2: TMemo Left = 595 Top = 175 Width = 201 Height = 287 ScrollBars = ssBoth TabOrder = 2 end object Button2: TButton Left = 136 Top = 8 Width = 75 Height = 25 Caption = 'gettype' TabOrder = 3 OnClick = Button2Click end object Button3: TButton Left = 248 Top = 8 Width = 121 Height = 25 Caption = #33719#21462'TButton '#31867#30340#26041#27861 TabOrder = 4 OnClick = Button3Click end object Button4: TButton Left = 400 Top = 8 Width = 121 Height = 25 Caption = #33719#21462'TButton '#31867#30340#23646#24615 TabOrder = 5 OnClick = Button4Click end object Button5: TButton Left = 544 Top = 8 Width = 145 Height = 25 Caption = #33719#21462' TButton '#31867#30340#23383#27573 TabOrder = 6 OnClick = Button5Click end object Button6: TButton Left = 8 Top = 48 Width = 305 Height = 25 Caption = #33719#21462#33719#21462' TButton '#31867#30340#26041#27861#38598#21512#12289#23646#24615#38598#21512#12289#23383#27573#38598#21512 TabOrder = 7 OnClick = Button6Click end object Button7: TButton Left = 344 Top = 48 Width = 233 Height = 25 Caption = 'TRttiRecordType '#35835#21462#20102#32467#26500#30340#20449#24687'.' TabOrder = 8 OnClick = Button7Click end object Button8: TButton Left = 595 Top = 48 Width = 190 Height = 25 Caption = #35835#21462#33258#23450#20041#32467#26500#20307'TKeyDog'#20449#24687 TabOrder = 9 OnClick = Button8Click end object Button9: TButton Left = 8 Top = 96 Width = 185 Height = 25 Caption = #26377#24207#31867#22411'TRttiOrdinalType' TabOrder = 10 OnClick = Button9Click end object Button10: TButton Left = 224 Top = 96 Width = 161 Height = 25 Caption = 'Rtti '#21453#23556#35843#29992'TMyClass '#30340#26041#27861 TabOrder = 11 OnClick = Button10Click end object Button11: TButton Left = 408 Top = 96 Width = 185 Height = 25 Caption = 'Rtti '#21453#23556#20462#25913'TMyClass '#31867#30340#23646#24615#22495 TabOrder = 12 OnClick = Button11Click end object Button12: TButton Left = 614 Top = 96 Width = 155 Height = 25 Caption = 'rtti '#21453#23556#20462#25913#26522#20030#20540 TabOrder = 13 OnClick = Button12Click end object Button13: TButton Left = 8 Top = 127 Width = 169 Height = 25 Caption = 'ObjAuto'#33719#21462'TClass3 '#30340#20449#24687 TabOrder = 14 OnClick = Button13Click end end