为什么要RegisterClass?(50分)

  • 主题发起人 主题发起人 awfigsk
  • 开始时间 开始时间
A

awfigsk

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Unit2, ExtCtrls
type TForm1 = class(TForm) Button1: TButton
Button2: TButton
Panel1: TPanel
Label1: TLabel
procedure Button1Click(Sender: TObject)
procedure Button2Click(Sender: TObject)
private { Private declarations } public { Public declarations } end
var Form1: TForm1
implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject)
var s:Tmemorystream
rr:Twriter
ff:TFrame2
begin ff:=TFrame2.Create (self)
ff.Parent :=Panel1
s:=Tmemorystream.Create
s.WriteComponent(ff)
s.SaveToFile('a')
s.Free
end
procedure TForm1.Button2Click(Sender: TObject)
var s:Tmemorystream
ff:TFrame2
begin classes.RegisterClass(TFrame2)
s:=Tmemorystream.Create
s.LoadFromFile('a')
ff := TFrame2(TFrame.Create(Self))
ff.Parent :=self
s.ReadComponent(ff)
s.Free
end;

为什么要RegisterClass(TFrame2)?我在interface引用了Unit2呀,上述代码执行后,报错,提示'Class TLabel not found',这是为何?也要RegisterClass(TLabel)吗?为什么呢?在TForm的Publisher部分有TLabel呀
不明白,还请各位大侠指点,谢谢!
 
因为你的FRAME改变了,
先删除你的Frame,
你重新使用标准的Frame控件插入就复制代码就OK了,

不过你的也太乱了,看了有点晕..
 
Frame怎么改变了?我不是直接从文件中read吗?并且我引用了定义TFrame2类的单元。为什么还要用RegisterClass这个函数注册类?
 
如果你已经USES了,那么你可以不用RegisterClass(TFrame2),这里之所以要用到REGISTERCLASS,是因为如果你后面TFrame2这是一个字符串,而不是一个窗体类的时候用的。
而且RegisterClass过程在另外的一个DELPHI基本类里,你要手工引入才可以,具体那个忘记了。你可以查查全文搜索。
 
......咋都乱答呢....

看s.ReadComponent(ff)这句
ReadComponent方法里调用了TReader.ReadRootComponent
TReader.ReadRootComponent里有这么一句
Result := TComponentClass(FindClass(ReadStr)).Create(nil);
而FindClass函数只能找到被RegisterClass的类,否则会报错
 
但我不明白,上述代码中如果将classes.RegisterClass(TButton)和classes.RegisterClass(TLabel)去掉,就报错,说找不到TButton和Tlabel两个类,但前面又可以定义Button:TButton,label1:Tlabel,这怎么又可以呢?
这个RegisterClass()起个什么作用?为什么Button:TButton这个定义又可以?
不明白其中的原理,还请各位大侠指点,谢谢!
 
Button:TButton,label1:Tlabel,定义的时候,类信息注册到运行时信息库中,之所以需要RegisterClass()这个函数,因为要查询的是运行类信息,要注册的类的信息没有在运行时信息库中,当然不可以查到该类的信息。
 
按楼上大哥所说,定义时TButton和TLabel的类信息就注册到运行时信息库中了,但为何在后面还要用RegisterClass(TButton)和RegisterClass(TLabel)呢?
 
WriteComponent 通常是由 Delphi 的 IDE/编译器调用的,自己调用的时候应该不需要再注册这个类的。
建议不要用memorystream,用filestream试试,应该不用注册。
或者用TReader
 
try
R := TReader.Create(S, 1024);
try
R.OnSetName := ReaderSetName;
FOwner := AOwner;
FSelection := Components;
R.ReadComponents(AOwner, AParent, ComponentRead);
finally
R.Free;
end;
finally
S.Free;
end;

用TReader读,TWriter写,不需要另外注册类。
 
刚才看了一下delphi的源代码,发现wincontrol注册类的过程是CreateHandle--》CreateWnd,也许这些过程都是delphi在设计期就完成的,也许运行期从磁盘文件加载的控件没有经历这个过程,你可以运行期中用TReader读出,然后在TReader的OnFindComponentClass过程中注册该类,我测试过了,肯定没有问题。
 
还是不太明白。为什么在定义Button:TButton时,不要先注册TButton呢?
 
你把那些组件都存入了磁盘文件,然后从磁盘文件中LoadFromFile加载了这些组件,要知道,这些组件并没有经过编译,只是运行期装载的。
 
to fenian大哥:十分感谢您的回答,看了您上这张贴,感觉有点道理,但还是有些不明白,还望您指点一下,谢谢!

TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Panel1: TPanel;
Label1: TLabel;
在内存中不是已经有TButton和TLabel类的定义呀,这些组件也应该是已经编译了的呀。?
 
关注该帖
对此问题我也感兴趣。
 
因为你没有引用这些Tlabel,Tbutton的单元, 要使用这些类,必须注册, registryClass只能注册Tpresenst派生的类。
 
怎么没有呢?我在TForm1中定义button1时,不是引用了TButton类吗?并且在TFrame中也引用了TButton的单元。
 
定義只是一個定義啊,並沒有真正創建button,所以不會出錯,到運行時才開始創建.你可以看看master delphi 7的書
 
有点意思.有时间研究一下.
 
內存中還沒有註冊過tbutton類
 

Similar threads

后退
顶部