元件的各属性的初值是怎么怎么得到的?(100分)

  • 主题发起人 主题发起人 j5203
  • 开始时间 开始时间
J

j5203

Unregistered / Unconfirmed
GUEST, unregistred user!
元件的Create过程只进行了把元件的有序字段设为0,字符串字段设为空,等等简单的操作
(如果在Create过程里只写一句showmessage(name)就可以看出来)。那么,当我们把一个
元件从元件选项板上选中并放到一个Form上时(此时dfm文件也还没有创建),元件的某些
默认属性(比如Name属性)是怎么被赋初值的呢?

为了试验,我在Create过程除了inherited外只写了一句showmessage(name),在Loaded过程
中除了inherited外也只写了一句showmessage(name+'Loaded'),当我把一个元件从元件选
项板上选中并放到一个Form上时,第一个showmessage执行了,但结果表示出name是'',
而loaded中的showmessage根本就没有执行。这也就是说明元件的初值既不是在create过程
赋的,也不是在loaded过程赋的。

这就是那个元件的代码:
unit NewTest;

interface

uses
Windows, Messages, SysUtils, Classes, Controls, Dialogs;

type
TNewTest = class(TCustomControl)
private
{ Private declarations }
protected
{ Protected declarations }
public
constructor Create(AOwner: TComponent);override;
procedure Loaded;override;
{ Public declarations }
published
{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Ke', [TNewTest]);
end;

{ TNewTest }

constructor TNewTest.Create(AOwner: TComponent);
begin
inherited;
showmessage(Name);


end;

procedure TNewTest.Loaded;
begin
inherited;

showmessage(name + 'Loaded');
end;

end.
 
Name是类名自动加1,如果存在1了,则加2,它是遍历的[:)]
 
初值都是在create里显式设置的.只要不断的向上分析控件的父类就可发现.你试一试.
 
在属性中Default中指定的,但Name是IDE分配的。
 
TO jiangxiancheng:
Default只是表示当前值不等于其后的指定值时保存当前值,而不表示是缺省值,缺省值是在Create中赋与的
 
同意YNTW,你看看一些VCL的源码就明白了。
 
既然初值已经被祖先类的Create过程赋了,为什么showmessage(name)只能
说明name是一个空字符串?
 
Create后的Name就是空字符串,在IDE中,元件创建后,IDE分配给元件一个Name
 
Fwidth和FHeight是Integer类型的,Delphi在声明的时候就已经把它们初始化为0
 
关键就在于你把一个控件放在Form上时,它的Height和Width并不为零,而在Create中也
没有对FHeight和FWidth赋值。你可以把我试验的那个类的父类换成TControl试试就
明白了。
 
呵呵,你举个控件的例子
 
你要把我一开始举的那个例子的父类TCustomControl改成TControl就知道了。
 
呵呵,那请老兄看看VCL中可视控件的CustomControl(如CustomForm、CustomEdit等)的Create过程,
看看有没有对Height等属性赋值。

BTW:写控件也要有规矩,对于已形成标准的东西,要学习,不要自做主张。话有些过激,不好意思,
不想再在这个问题上浪费时间了。
 
又一个刨坟的。
 
但是但是但是但是但是但是但是但是但是但是但是但是但是但是但是!!!!!!!!!
当你把一个直接从TControl继承的控件放在Form上时,它的Height和Width并不为
零,而在Create中也没有对FHeight和FWidth赋值。[/b]
然而,当你把他放到Form上时,Width和Height就是有非零值的!!!!!!

学东西就是应该把问题弄清楚,而不是不了了之!!!!!!!!
请拿底下这个元件试试!
unit NewTest;

interface

uses
Windows, Messages, SysUtils, Classes, Controls, Dialogs;

type
TNewTest = class(TControl)
private
{ Private declarations }
protected
{ Protected declarations }
public
constructor Create(AOwner: TComponent);override;
procedure Loaded;override;
{ Public declarations }
published
{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Ke', [TNewTest]);
end;

{ TNewTest }

constructor TNewTest.Create(AOwner: TComponent);
begin
inherited;
showmessage(Name);


end;

procedure TNewTest.Loaded;
begin
inherited;

showmessage(name + 'Loaded');
end;

end.
 
以下是CustomControl,Control,WinControl等类的Create过程。

constructor TControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FWindowProc := WndProc;
FControlStyle := [csCaptureMouse, csClickEvents, csSetCaption, csDoubleClicks];
FFont := TFont.Create;
FFont.OnChange := FontChanged;
FAnchors := [akLeft, akTop];
FConstraints := TSizeConstraints.Create(Self);
FConstraints.OnChange := DoConstraintsChange;
FColor := clWindow;
FVisible := True;
FEnabled := True;
FParentFont := True;
FParentColor := True;
FParentShowHint := True;
FParentBiDiMode := True;
FIsControl := False;
FDragCursor := crDrag;
FFloatingDockSiteClass := TCustomDockForm;
FHelpType := htContext;
end;

constructor TCustomControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCanvas := TControlCanvas.Create;
TControlCanvas(FCanvas).Control := Self;
end;


constructor TWinControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FObjectInstance := Classes.MakeObjectInstance(MainWndProc);
FBrush := TBrush.Create;
FBrush.Color := FColor;
FParentCtl3D := True;
FTabOrder := -1;
FImeMode := imDontCare;
if SysLocale.PriLangID = LANG_JAPANESE then
FImeName := ''
else
FImeName := Screen.DefaultIme;
FUseDockManager := False;
FBevelEdges := [beLeft, beTop, beRight, beBottom];
FBevelInner := bvRaised;
FBevelOuter := bvLowered;
FBevelWidth := 1;
FHelpType := htContext;
end;
 
关于 Name ,没那么复杂,IDE 在控件建立完成以后,根据 Typinfo.pas 单元的有关
函数获得类名,由于 ShowMessage 是在 Create 过程中,这时你的控件的实例,实际
上还处在建立过程中,怎么会有名字?可能你又问,那为什么是空串?由于 String 在
D 中的默认值使然,也就是说,只要你使用 String 类型,初始化就为空。
 
我也知道string类型的默认值是空。
但是TControl类的Width和Height是怎么赋值的。
 
Width defult:=100
就可以了
 
To 小雨哥
哇,妈妈的,你是真不懂,还是装糊涂呀!
首先,我现在说的是TControl!TControl!TControl!的Height和Width!
其次,TControlCanvas.Create我以前就看过。TControlCanvas本身没有重载Create,是
直接用的TCanvas的Create.
TCanvas 继承于TPersistent,TPersistent也没有Width和Height(到TPersistent的
孙子类才有这两个属性)。
以下是TCanvas的创建过程,您看看有对Width和Height的赋值吗。
constructor TCanvas.Create;
begin
inherited Create;
InitializeCriticalSection(FLock);
FFont := TFont.Create;
FFont.OnChange := FontChanged;
FFont.OwnerCriticalSection := @FLock;
FPen := TPen.Create;
FPen.OnChange := PenChanged;
FPen.OwnerCriticalSection := @FLock;
FBrush := TBrush.Create;
FBrush.OnChange := BrushChanged;
FBrush.OwnerCriticalSection := @FLock;
FCopyMode := cmSrcCopy;
State := [];
CanvasList.Add(Self);
end;

 
后退
顶部