简单测试运行时类信息(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(运行时类型信息)是动态语言与静态语言的主要区别
运行时类型信息代表类型信息和对内存的操作能力. 运行时类型信息是运行时系统的基础. 类型信息分为编译时类型信息和运行时类型信息两种: 静态语言的类型信息只在编译时使用和保留,在可执行文件中没有类型信息 ...
随机推荐
- springFramework 源码学习之源码下载与编译
1.源码下载 Spring已经将源码从svn迁移到了git.对于习惯了svn的人来说依然可以svn checkout,最好checkout到英文路径下,本人中文路径编译不过,具体原因不明,路径: ht ...
- WARNING:Could not increase the asynch I/O limit to 64 for SQL direct I/O. It is set to 0
今天是2014-01-07,解决一下hp-unix异步I/O问题. 从trace日志中看: WARNING:Could not increase the asynch I/O limit to 32 ...
- 【转】MUD教程--巫师入门教程2
简单的人物原则上只要有 set_name<名字> . combat_exp <经验>就行了,当然我们总得稍微多添一点了.inherit NPC;void create(){ s ...
- codeforces 659D . Bicycle Race 几何
题目链接 对相邻的三个点叉积判断一下就好. #include <iostream> #include <vector> #include <cstdio> #inc ...
- 非阻塞IO
设置描述符非阻塞的两种方法: 1,调用 open 时,设置,O_NONBLOCK; 2,调用 fcntl设置: 具体如下: ,open("/xxx/file1",O_RDWR|O_ ...
- C++设计模式之建造模式
#include <iostream>using namespace std; class ApplePhone { public: virtual void buildCamera()= ...
- Oracle EBS-SQL (SYS-4):sys_职责查询.sql
select t.RESPONSIBILITY_NAME from apps.FND_RESPONSIBILITY_VL t where t.RESPONSIBILITY_NAME like '%MR ...
- 嵌入式davinci电路元素基础和PWM模块
1,DAC_OUT和DAC_OUTB是AD9912输出的差分信号. 2,电容器储存电荷的能力,常用的单位是F.uF.nF.pFUF大了好还是UF小了好,要根据电路自身需要而设计, 要看电路滤波是在高频 ...
- OpenNebula openldap集成
Preface: 当前写这篇post的心情可谓是即激动,又操蛋!............................ ruiy还是言归正传,人老了,赖的扯淡了,哥当前一心看向Tech(s),做个顾 ...
- c++链接数据库测试,中文有问题
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <Windows.h& ...