简单测试运行时类信息(RTTI),附详细例子
新建一个单元文件,填写如下代码,然后保存为 ClassInfoUnit.pas,这里定义了一个结构,用来读取指定类的信息。
- unit ClassInfoUnit;
- interface
- uses
- Classes, TypInfo;
- type
- { 存放类属性的动态数组 }
- PropInfoArray = array of PPropInfo;
- { 用法:首先声明该结构的变量,然后通过 Create 函数或 Target 属性指定要获取 }
- { 信息的类,然后就可以通过 public 中的属性或方法来获取该类的各种信息了 }
- TClassInfo = record { use TypInfo }
- private
- { 属性:要获取其运行时信息(RTTI)的类 }
- FTarget: TClass;
- { 属性:指向存放类信息的指针 }
- FTypeInfo: PTypeInfo;
- { 属性:指向存放类数据的指针 }
- FDataInfo: PTypeData;
- { 类属性(property)的个数 }
- FPropertyCount: Cardinal;
- { 类属性列表(数组) }
- FPropertyList: PropInfoArray;
- { 设置 FTarget }
- procedure SetTarget(aClass: TClass);
- { 读取 PropertyTypes[Index] }
- function GetPropTypes(Index: Integer): PTypeInfo;
- public
- { 构造函数,用来设置要获取其信息的对象 }
- procedure Create(aObj: TObject); overload;
- { 构造函数,用来设置要获取其信息的类 }
- procedure Create(aClass: TClass); overload;
- { 获取类的所有属性和事件 }
- function GetAllProperties: string;
- { 获取类的所有属性 }
- function GetPropList: string;
- { 获取类的所有事件 }
- function GetMethodList: string;
- { 指向类信息的指针 }
- property TypeInfo: PTypeInfo read FTypeInfo;
- { 指向类数据的指针 }
- property DataInfo: PTypeData read FDataInfo;
- { 属性:要获取其运行时信息(RTTI)的类 }
- property Target: TClass read FTarget write SetTarget;
- { 类的所有属性信息列表 }
- property PropertyList: PropInfoArray read FPropertyList;
- { 类的所有属性类型列表 }
- property PropertyTypes[Index: Integer]: PTypeInfo read GetPropTypes;
- { 类的属性总个数 }
- property PropertyCount: Cardinal read FPropertyCount;
- end;
- implementation
- { 构造函数 }
- procedure TClassInfo.Create(aObj: TObject);
- begin
- if aObj = nil then
- Create(nil)
- else
- Create(aObj.ClassType);
- end;
- { 构造函数 }
- procedure TClassInfo.Create(aClass: TClass);
- begin
- Target := aClass;
- end;
- { 私有:更改要操作的类 }
- procedure TClassInfo.SetTarget(aClass: TClass);
- begin
- if FTarget = aClass then
- Exit;
- FTarget := aClass;
- if Assigned(FTarget) then
- begin
- FTypeInfo := aClass.ClassInfo;
- FDataInfo := GetTypeData(FTypeInfo);
- FPropertyCount := FDataInfo.PropCount;
- SetLength(FPropertyList, FPropertyCount);
- GetPropInfos(FTypeInfo, PPropList(FPropertyList));
- end
- else
- begin
- FTypeInfo := nil;
- FDataInfo := nil;
- FPropertyCount := 0;
- SetLength(FPropertyList,0);
- end;
- end;
- { 私有:获取属性的类型信息 }
- function TClassInfo.GetPropTypes(Index: Integer): PTypeInfo;
- begin
- Result := nil;
- if FPropertyCount = 0 then
- Exit;
- Result := FPropertyList[Index].PropType^;
- end;
- { 获取所有属性和事件列表 }
- function TClassInfo.GetAllProperties: string;
- var
- I: Integer;
- Strs: TStringList;
- begin
- if FPropertyCount = 0 then
- Exit;
- Strs := TStringList.Create;
- try
- for I := 0 to PropertyCount - 1 do
- Strs.Add(PropertyList[I].Name);
- Result := Strs.Text;
- finally
- Strs.Free;
- end;
- end;
- { 获取属性列表 }
- function TClassInfo.GetPropList: string;
- var
- I: Integer;
- Strs: TStringList;
- begin
- if FPropertyCount = 0 then
- Exit;
- Strs := TStringList.Create;
- try
- for I := 0 to PropertyCount - 1 do
- begin
- if PropertyTypes[I].Kind <> tkMethod then
- Strs.Add(PropertyList[I].Name);
- end;
- Result := Strs.Text;
- finally
- Strs.Free;
- end;
- end;
- { 获取事件列表 }
- function TClassInfo.GetMethodList: string;
- var
- I: Integer;
- Strs: TStringList;
- begin
- if FPropertyCount = 0 then
- Exit;
- Strs := TStringList.Create;
- try
- for I := 0 to PropertyCount - 1 do
- begin
- if PropertyTypes[I].Kind = tkMethod then
- Strs.Add(PropertyList[I].Name)
- end;
- Result := Strs.Text;
- finally
- Strs.Free;
- end;
- end;
- end.
然后创建一个空白窗体,窗体上创建两个 TMemo(mmo1、mmo2)和两个 TButton(btn1、btn2),双击 btn1 和 btn2 ,使用如下代码进行测试(测试在程序运行时 TControl 和 TButton 的 published 属性和方法):
- unit Form1Unit;
- interface
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls, ExtCtrls;
- type
- TForm1 = class(TForm)
- mmo1: TMemo;
- mmo2: TMemo;
- btn1: TButton;
- btn2: TButton;
- procedure btn1Click(Sender: TObject);
- procedure btn2Click(Sender: TObject);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
- var
- Form1: TForm1;
- implementation
- {$R *.dfm}
- uses
- ClassInfoUnit;
- { 获取 TControl 的运行时信息 }
- procedure TForm1.btn1Click(Sender: TObject);
- var
- CI: TClassInfo;
- begin
- Caption := 'TControl';
- CI.Create(TControl);
- mmo1.Text := CI.GetPropList;
- mmo2.Text := CI.GetMethodList;
- end;
- { 获取 TButton 的运行时信息 }
- procedure TForm1.btn2Click(Sender: TObject);
- var
- CI: TClassInfo;
- begin
- Caption := 'TButton';
- CI.Create(TButton);
- mmo1.Text := CI.GetPropList;
- mmo2.Text := CI.GetMethodList;
- end;
- end.
http://blog.csdn.net/stevenldj/article/details/7166455
简单测试运行时类信息(RTTI),附详细例子的更多相关文章
- MFC中关于运行时类信息及动态创建对象的两个宏的意义(转)
http://blog.csdn.net/ligand/article/details/49839507 MFC运行时类信息 用途: 程序在运行时,获取对象类的信息及类的继承关系 实现: 1.定义的类 ...
- 批处理bat脚本编写(附详细例子)
批处理bat脚本编写(附详细例子) 由于在项目开发的过程中经常需要编写bat脚本,而看大牛们编写 ...
- Java 序列化Serializable详解(附详细例子)
Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization ...
- Java 序列化Serializable详解(附详细例子)
Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是 ...
- 了解运行时类型信息(RTTI)
RTTI需要引用单元TypeInfo GetPropInfo 函数用于获得属性的 RTTI 指针 PPropInfo.它有四种重载形式,后面三种重载的实现都是调用第一种形式.AKinds 参数用于限制 ...
- android开发之java JDK环境变量配置的信息代码 附详细教程。
java环境变量配置: [用户变量]class_path .;%JAVA_HOME%\lib\tools;%JAVA_HOME%\jre PATH ;%JAVA_HOME%\ ...
- 【JavaSE】运行时类型信息(RTTI、反射)
运行时类型信息使得你可以在程序运行时发现和使用类型信息.--<Think in java 4th> **** 通常我们在面向对象的程序设计中我们经常使用多态特性使得大部分代码尽可能地少了解 ...
- C++ - RTTI(RunTime Type Information)执行时类型信息 具体解释
RTTI(RunTime Type Information)执行时类型信息 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details ...
- 是否含有RTTI(运行时类型信息)是动态语言与静态语言的主要区别
运行时类型信息代表类型信息和对内存的操作能力. 运行时类型信息是运行时系统的基础. 类型信息分为编译时类型信息和运行时类型信息两种: 静态语言的类型信息只在编译时使用和保留,在可执行文件中没有类型信息 ...
随机推荐
- ShowDialog()弹出的窗体,关闭后,主窗体会闪烁的BUG
如图,要实现下列等待界面时,等待界面是以ShowDialog弹出的,发现关闭后,主窗体会闪烁一下的BUG,搞半天没搞明白啥原因. 过了几天后,搜索了下发现,在fm.ShowDialog(),显示出来时 ...
- QF——对不同尺寸屏幕的适配(自动布局:AutoLayout)
对不同尺寸设备UI的适配: 很多时候,我们的App可能运行在不同尺寸的设备上,或者横竖屏时,呈现方法应该也不一样.这样便要求UI里各控件的位置和大小不能写死. 对于不同尺寸UI的适配,一般有三种对策: ...
- 管理node_modules
http://stackoverflow.com/questions/15225865/centralise-node-modules-in-project-with-subproject
- c语言 数组最小数
数组求一个数组的最小数 int number[20] = {0}; int min = 0; for (int i = 0; i < 20; i++) { number[i] = arc4ran ...
- Tempo 2.0
Tempo 2.0 Tempo is an easy, intuitive JavaScript rendering engine that enables you to craft data tem ...
- delphi新语法之泛型实现的对象池模板
现在的DELPHI因为支持泛型的语法,所以也能支持模板编程了. // 标准模板 unit UntPools; interface uses Classes, SysUtils, Unt ...
- android 用 XML 自定义边框(只上下边框有色)
直接上代码: <?xml version="1.0" encoding="UTF-8"?> <layer-list xmlns:android ...
- 调试qemu
最近需要给libvirt增加一个新feature,该feature基于qemu的最新代码. 我需要关心的: http://wiki.qemu.org/Features/Migration 需要自己编译 ...
- oracle初始安装大小
oracle初始安装大小 /ruiy/ocr/DBSoftware/app/oracle/ruiy/ocr/DBSoftware/app/oraInventory/ruiy/ocr/DBData/or ...
- Delphi XE7中新并行库
Delphi XE7中添加了新的并行库,和.NET的Task和Parellel相似度99%. 详细内容能够看以下的文章: http://www.delphifeeds.com/go/s/119574 ...