有意思的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: " ...
随机推荐
- 五段实用的js高级技巧
技巧一之setTimeout. 应用案例:比如你想一个函数循环执行10次,怎么办?以前通常是先setInterval,然后clearInterval,技巧一就是克服这个问题 复制代码 代码如下: (f ...
- JavaScript小技巧整理篇(非常全)
能够为大家提供这些简短而实用的JavaScript技巧来提高大家编程能力,这对于我来说是件很开心的事.每天仅花上不到2分钟的时间中,你将可 以读遍JavaScript这门可怕的语言所呈现给我们的特性: ...
- linux netstat-查看Linux中网络系统状态信息
博主推荐:更多网络测试相关命令关注 网络测试 收藏linux命令大全 netstat命令用来打印Linux中网络系统的状态信息,可让你得知整个Linux系统的网络情况. 语法 netstat(选项) ...
- 创建Tensor
目录 创建Tensor numpy, list numpy list zeros, ones, fill zeros ones fill random 打乱idx后,a和b的索引不变 constant ...
- GPIO——端口位设置/清除寄存器BSRR,端口位清除寄存器BRR
端口位设置/复位寄存器BSRR: 注:如果同时设置了BSy和BRy的对应位,BSy位起作用. 位31:16 BRy: 清除端口x的位y (y = 0…15) 这些位只能写入并只能以字(16 ...
- UVa 1599 理想路径(反向BFS 求最短路径 )
题意: 给定一个有重边有自环的无向图,n个点(2 <= n <= 100000), m条边(1 <= m <= 200000), 每条边有一个权值, 求从第一个点到n的最少步数 ...
- c#读取MySQL数据表中的内容
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- HDU 5458 Stability
Stability Time Limit: 2000ms Memory Limit: 102400KB This problem will be judged on HDU. Original ID: ...
- caca需要用到x11作为图形输出
编译错误:no output drivers were selected!. yum -y install xcb-proto yum -y install libxcb-devel.x86_64 l ...
- [luoguP1272] 重建道路
传送门 奇奇怪怪的分组背包. #include <cstdio> #include <cstring> #include <iostream> #define N ...