分享
 
 
 

深入VCL源码研究DELPHI窗体的创建和关闭

王朝delphi·作者佚名  2006-09-15
窄屏简体版  字體: |||超大  

一、窗体的建立

在DELPHI中,我们通常使用Application.CreateForm(TForm2, Form2)和TForm.create来创建窗体,我们几乎无法区别这两种方法差异,更何况,我们更多的时候都是在使用TForm.create来生成子窗体。

不过,仔细观察VCL源码,你会发现,其实两者区别很大。

procedure TApplication.CreateForm(InstanceClass: TComponentClass; var Reference);

var

Instance: TComponent;

begin

Instance := TComponent(InstanceClass.NewInstance);

TComponent(Reference) := Instance;

try

Instance.Create(Self);

except

TComponent(Reference) := nil;

raise;

end;

if (FMainForm = nil) and (Instance is TForm) then

begin

TForm(Instance).HandleNeeded;

FMainForm := TForm(Instance);

end;

end;

constructor TCustomForm.Create(AOwner: TComponent);

begin

GlobalNameSpace.BeginWrite;

try

CreateNew(AOwner);

if (ClassType <> TForm) and not (csDesigning in ComponentState) then

begin

Include(FFormState, fsCreating);

try

if not InitInheritedComponent(Self, TForm) then

raise EResNotFound.CreateFmt(SResNotFound, [ClassName]);

finally

Exclude(FFormState, fsCreating);

end;

if OldCreateOrder then DoCreate;

end;

finally

GlobalNameSpace.EndWrite;

end;

end;

Form1 := TForm1.Create(Application); 是先调用TForm1的Create方法, 然后赋值 给Form1变量。而Application.CreateForm(TForm1, Form1); 他会先得到一个Instance的指针, 把这个指针赋值给Form1, 然后是Form1.Create(Application). 这Tform1.create的区别在于, 在TForm1的OnCreate事件中, 我们可以使用Form1这个变量。

千万不要小瞧这点区别。例如你的程序有多个窗体,各个子窗体都是在需要的时候通过Tform1.create动态生成的,你想在FormOnCreate事件中对窗体上的edit1赋值text属性,那么你不能直接使用Form1.edit1.text := 'wudi_1982',你可以使用self.edit1.text 或者直接使用edit1.text。此时,你可能会想,可以直接用edit1.text,我为什么要多写form1.edit1.text呢?这里除了了解两者的区别,更重要的在于,如果你的程序中有一个函数,函数并非写在窗体类中,此函数调用了form上的信息,而在初始化的时候,你又必须调用它,如果不明白此中道理,可能就这个问题,就要让你调试好长时间,关于这方面的例子我就不写了。在DELPHI的DEMO程序中,又一个关于ListView的,其中就有类似的情况,只不过那个DEMO程序只有一个窗体,用不到Tform.create,如果有兴趣,你可以把那个例程添加到一个已存在的工程中,然后用两种不同的方法生成,你就会发现问题了。

二、窗体的关闭

通常情况下,我们对于程序中子窗体的关闭,大多是使用close方法或者直接点击窗体右上角的关闭按钮。那么对于VCL的窗体,它真的“关闭”了吗?在默认情况下,答案是否定的。观察VCL源码,你会发现,那个关闭只能算做隐藏。至于怎么测试,我想你知道。

要彻底关闭窗体并释放资源,就要调用他的free方法(模式窗体的常用办法),或者在onclose事件中,设置Action := caFree(无模式窗体的常用办法),如果窗体还要通过并且将自身赋值为nil。关于为什么手动做form1 := nil的操作,我这里就不多说了,

TCloseAction = (caNone, caHide, caFree, caMinimize);

procedure TCustomForm.Close;

var

CloseAction: TCloseAction;

begin

if fsModal in FFormState then

ModalResult := mrCancel

else

if CloseQuery then

begin

if FormStyle = fsMDIChild then

if biMinimize in BorderIcons then

CloseAction := caMinimize else

CloseAction := caNone

else

CloseAction := caHide;

DoClose(CloseAction);

if CloseAction <> caNone then

if Application.MainForm = Self then Application.Terminate

else if CloseAction = caHide then Hide

else if CloseAction = caMinimize then WindowState := wsMinimized

else Release;

end;

end;

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有