有意思的RTL函数RegisterClass(在持久化中,你生成的一个新类的对象,系统并不知道他是如何来的,因此需要你注册)good
例子1:Delphi中使用纯正的面向对象方法(这个例子最直接)
Delphi的VCL技术使很多程序员能够非常快速的入门:程序员门只要简单的拖动再加上少量的几个Pascal语句,呵呵,一个可以运行得非常良好的Delphi程序!恭喜你,你已经可以进行程序开发这个伟大的事业了。不过,当你学了一段时间后也许就不这么想了哦。因为Delphi是支持面向对象的语言,其实所有的VCL Component都是基于面向对象的语言设计的,那么当我们用这些面向对象的东东来设计出一些不怎么面向对象的东东好象有些不伦不类的感觉,当然,这里不讨论用不用面向对象方法的好坏,也不想引起相关人士的抗议,毕竟“萝卜青菜”嘛。
在Delphi中,所有的控件都声明在Publish的关键字下,这也是利用组件编程的默认位置。这样,如果一个Form2想要引Form1(假如其为Unit1)中的某个控件时,只要Use Unit1就OK了,如果Form1要引用Form2的东东,也可以如法泡制。不过,如果哪天我不小心把Form2中的控件改了名,那岂不是Form1中调的的代码全部要重写了么?所以,我主张把这些控件作为Form类的专用元素,外部窗体可以通过Form类公布的属性来访问其中的控件。
比如:
TForm1=class(Tform)
privte
Button1:Tbutton
end;
不过,这样的设计是解决了成员的高度封装不过,编译会出现错误说Tbutton类找不到,原因是我们把Button1放到了Private中,Delphi不会自动帮我们注册Tbutton类,其实解决这个问题也很简单只要在
Initialization
中加入 RegisterClasses([Tbutton])
就OK了,当然如果有不同的类的控件都可以如法炮制放在RegisterClasses的参数中,因为其参数是一个控件数组。
当然,这样的面向对象的设计方法是要比以前那种“拖拉”的方法复杂,不过,我们得到了高度的封装性,我认为值得,各位呢?
参考:
http://www.delphifans.com/infoview/Article_338.html
----------------------------------------------------------------------
原理1:
因为在持久化中,你生成的一个新类的对象,系统并不知道他是如何来的,因此需要你注册!
就好像
CreateWindow 一樣,你需要讓操作系統有這樣一個窗口類才行。
比如說,有一個窗口沒有注冊前你只知道它的類名,你想直接建立窗口的話,通常操作:
getClass(className), 然後通過取得類名直接生成窗口,這個時候你就需要先用RegisterClass
RegisterClasses 說白了,就是循環執行:RegisterClass,直至全部注冊完。
procedure TForm1.Button2Click(Sender: TObject);
var
s:Tmemorystream;
ff:TFrame2;
begin
classes.RegisterClass(TFrame2);
classes.RegisterClass(Tlabel);
classes.RegisterClass(TButton); s:=Tmemorystream.Create ;
try
s.LoadFromFile('a');
ff := TFrame2(TFrame.Create(Self));
ff.Parent :=self;
s.ReadComponent(ff) ;
finally
s.Free;
end;
end;
参考
http://bbs.csdn.net/topics/300016429
----------------------------------------------------------------------
原理2:
类引用。这正是delphi强于c++的一点。
C++中的构造函数不可以是虚的,而delphi中却可以。
当由对象调用构造函数时,不能实现多态.
当由类调用构造函数时,同样不能实现多态
但当由类引用调用构造函数时,就可以实现多态了。
borland真伟大!
http://www.yourdelphi.com/topic_94574_ad00.htm
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1047021
----------------------------------------------------------------------
原理3:
正常的思路是注册一些类,就可以充分利用类的多态性来完成一些功能
你可以在程序运行的第一行代码,注册你所有的窗口类,用类常量
然后,在数据库中保存类名,在程序中根据类名查询类名和类的映射表GetClass
实现可以创建任意的已注册类的对象实例,
不是你说不清除,你说的再清楚,也不可能实现,只能用常量来注册
譬如: 你要根据类名获得类的指针,必须用GetClass,前提是此类已注册
而你获得了类指针,只不过是要注册它,但是,如果你能获得,那么它已经注册了
所以这不是自相矛盾吗?
http://www.yourdelphi.com/topic_61709_7db4_2.htm
----------------------------------------------------------------------
原理4(内部实现):
你可以去追蹤 RegisterClass 這個函式,實際上 Class 的註冊程序是藉著操作 RegGroups 這個私有變數來達成的,你再看看 Classes 內的 finalization 區段,已經有做釋放的動作。我想有很多 Class 是 Delphi 幫我們執行 Register 的,所以他會在程式結束時進行釋放的工作,因此如果使用者 Register 而未 UnRegister 在程式最後都會一併一起處理。至於你說那 UnRegisterClass 就不需要了,你可以看一下 Help 文件中的最後一行這應該能說明為何需要 UnRegister 這的程序了。
"After unregistering a class, its name can be reused to register another object class."
如果再深入去了解 RegisterClass 所做的事(FClassList.Add(AClass)),你會發現他是將 forbiddenclass 本身存放在一個 TList 中,這個說明了註冊的動作僅是做一個紀錄,並沒有在系統取得任何資源(TList 自己用的不算喔),舉例來說 TForm 的宣告也需要一些記憶體空間存放 VTable RTTI 等相關資訊,但因為這是由 Delphi 管理的,因此自然不需要我們去擔心。但 TForm.Create (nil) 所實體化的記憶體空間,就必須要由我們自行釋放(有 Owner 的就依任務需求而定囉)。我的意思是 RegisterClass 所註冊的東西本來就是 Delphi 所管理的,在程式結束時會將這些資源釋放掉。所以我覺得你的問題應該不是這兩個程序所造成的。
http://www.delphi-ktop-com-tw.my-hot.com/board.php?cid=30&fid=72&tid=56400
----------------------------------------------------------------------
例子2:只有事先注册的类才能动态生成,否则不行。比如TButton可以,但TEdit就不行。
procedure TForm2.Button1Click(Sender: TObject);
var
myRef: TControlClass;
testControl: TControl;
begin
//返回类型是一个类引用
myRef := TControlClass(Classes.GetClass(edit1.Text)); testControl := TControl(myRef.Create(self));
testControl.Parent := self;
testControl.Top := ;
testControl.Left := ;
testControl.Show;
end; //程序运行时就执行
initialization
//注册类
Classes.RegisterClasses([TIcon, TMemo, TButton,TMemo,TLabel]);
//程序关闭时执行
finalization
//删除注册的类
Classes.UnRegisterClasses([TIcon, TMemo, TButton,TMemo,TLabel]); end.
http://www.cnblogs.com/pengshaomin/archive/2012/02/05/2339136.html
----------------------------------------------------------------------
例子3:万一的例子
http://www.cnblogs.com/del/archive/2008/09/10/1137426.html
----------------------------------------------------------------------
例子4:官方的例子:
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Classes_RegisterClass.html
----------------------------------------------------------------------
其它例子或原理,欢迎补充~
有意思的RTL函数RegisterClass(在持久化中,你生成的一个新类的对象,系统并不知道他是如何来的,因此需要你注册)good的更多相关文章
- CAD在网页中绘图,并为新绘的对象写扩展数据和读取扩展数据
在网页中绘图,并为新绘的对象写扩展数据和读取扩展数据.下面帮助的完整例子,在控件安装目录的 Sample\Ie\iedemo.htm 中. 主要用到函数说明: _DMxDrawX::InsertBlo ...
- 一个java源文件中为什么只能有一个public类。
我们都遇到过一个源文件中有多个java类,但当第一个类使用public修饰时,如果下面还有类使用public修饰,会报错.也就是是说一个java源文件最多只能有一个public类. 当有一个publi ...
- 需求:lr需要在一串数字中随机位置插入一个新数字的实现方式
效果如下: 需要用到sscanf()函数: 从一个字符串中读进与指定格式相符的数据. Action() { ],s2[],s3[]; int n=atoi(lr_eval_string(" ...
- Java中BufferedReader到底是一个什么类?
1.java.io.BufferedReader 和 java.io.BufferedWriter 类各拥有8192字符的缓冲区.当BufferedReader在读取文本文件时,会先尽量从文件中读入字 ...
- 每日踩坑 2018-11-26 MVC Razor ActionLink 生成的URL中多生成了一个参数 ?length=n
RouteConfig 的路由注册如下: routes.MapRoute( name: "Default", url: "{controller}/{action}&qu ...
- java中使用反射做一个工具类,来为指定类中的成员变量进行赋值操作,使用与多个类对象的成员变量的赋值。
//------------------------------------------------我是代码的分割线 // 首选是一个工具类,在该工具类里面,定义了一个方法,public void s ...
- 给MySQL中某表增加一个新字段,设为主键值为自动增长。
alter table test_tb add ID int(10) primary key AUTO_INCREMENT; 设定完成后,原有记录的该字段会增加并自动设上值.以后的值会在已有记录的最 ...
- 今天代码中接触到了一个新的东西。js的上下自动滚动,无缝对接。
js的上下自动滚动,无缝对接.为什么会用到这个东西呢?因为我在做公司的官网项目的修改的时候.有一个产品介绍的页面,会有很多的产品出现在,中间部分的列表里.但是又不能够使用分页.所以我就在想如果,列表数 ...
- vue中使用router打开一个新的窗口
一个单页应用打开一个新的窗口不是很好控制,比如权限的处理,因为原先的页面不会自动刷新,方法很简单: let routeData = this.$router.resolve({ name: " ...
随机推荐
- css hack解决方案
现在大家做项目的时候估计很多都已经不怎么考虑兼容问题,大多数的公司都已经舍弃ie7.8了,都是从ie9+开始,所以说不会有那么多的兼容问题需要去解决了,但是由于本人力求完美的工作习惯,做项目的时候还是 ...
- 3D超炫酷旋转
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 笔试算法题(35):最长递增子序列 & 判定一个字符串是否可由另一个字符串旋转得到
出题:求数组中最长递增子序列的长度(递增子序列的元素可以不相连): 分析: 解法1:应用DP之前需要确定当前问题是否具有无后效性,也就是每个状态都是对之前状态的一个总结,之后的状态仅会受到前一个状态的 ...
- mysql8忘记登录密码时,修改密码方法
一.停止mysqld进程 systemctl stop mysqld.service 二.修改/etc/my.cnf(在mysqld选项添加skip-grant-tables),设置免密码登录: vi ...
- Linux命令学习(5):more和less
引子 平常工作中经常需要查看很大的文本文件,如果用vi打开的话会非常慢,所以平常都用less,但是并没有很系统地学习过less的用法,今天总结一下less和more的用法. 经过学习我发现less比m ...
- 12.Spring通过FactoryBean配置Bean
为啥要使用FactoryBean: 在配置Bean的时候,需要用到IOC容器中的其它Bean,这个时候使用FactoryBean配置最合适. public class Car { private St ...
- linux下的文档处理及tar命令
1.使用cat命令进行纵向合并 使用‘>’是将左边的内容覆盖到右边 使用‘>>’是将左边的内容追加到右边文档中 还可使用‘>’将不同文件进行合并 2.管道符‘|’统计行数 使用 ...
- C++ 类 直接定义对象与new对象的区别
new创建类对象与直接定义的区别 new创建对象的特点 new创建类对象需要指针接收,一处初始化,多处使用 new创建类对象使用完需delete销毁 new创建对象直接使用堆空间,而局部不用new定义 ...
- MySQL Connector/Python 接口 (三)
本文参见这里. 使用缓冲的 cursor,下例给从2000年加入公司并且还在公司的员工薪水从明天起加15% from __future__ import print_function from dec ...
- ORACLE数据库查看执行计划的方法
一.什么是执行计划(explain plan) 执行计划:一条查询语句在ORACLE中的执行过程或访问路径的描述. 二.如何查看执行计划 1: 在PL/SQL下按F5查看执行计划.第三方工具toad等 ...