怎么样在Delphi中用程序实现自定义窗体的创建和显示顺序?
在Delphi 中用程序实现自定义窗体的创建和显示顺序(1)
摘要:本文介绍了一种简单而实用的方法用来动态创建和显示窗体,在Project.dpr中编写代码实现窗体的动态选择创建,同时对Delphi的窗体创建,应用程序的创建,运行和结束的机制作了深入的探讨。
关键字:Delphi 窗体 创建 显示 动态选择
一. 问题的提出
在Delphi 中我们可以通过两种方法创建多个窗体并设置他们的创建顺序,第一种方法是在新添加了多个窗体后,按Delphi 工具栏上的Project->Options… , 在出现的Forms 一页设置窗体的创建顺序。如下图:
第二中方法是在Delphi的工程文件中修改,在这里假设是Project1.dpr,其代码将显示如下:
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2},
Unit3 in 'Unit3.pas' {Form3};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.CreateForm(TForm3, Form3);
Application.Run;
end.
(代码1)
可以通过调整上面代码中语句的顺序来调整创建3个窗体的顺序,效果跟第一种方法一样。
但是上面这两种方法都存在一个缺陷,就是Delphi编译器默认会把排在第一位创建的窗体作为主窗体,每次程序启动都会首先显示主窗体,并且窗体的加载顺序是不变的。
如何做成可以根据需要动态改变程序加载顺序呢?
二. Delphi窗体创建大揭密
1. 窗体权限的转移实验
新建3个Form , 在Project->Options… 中的Forms 一页把Form2和Form3 放置在Available forms中,保留Form1在Auto-create forms中,让Form1在程序一开始运行就创建。
在Form1(主窗体)中的OnCreate()事件函数中加入以下代码:
procedure TForm1.FormCreate(Sender: TObject);
begin
Label1.Caption:='Form1 Create Completed!';
Form1.Show;
Application.CreateForm(TForm2, Form2);
end;
(代码2)
在Form2的OnCreate()事件函数中加入以下代码:
procedure TForm2.FormCreate(Sender: TObject);
begin
Label1.Caption:='Form2 Create Completed!';
Form2.Show;
Application.CreateForm(TForm3,Form3);
end;
(代码3)
在Form3的OnCreate()事件函数中加入以下代码:
procedure TForm2.FormCreate(Sender: TObject);
begin
Label1.Caption:='Form3 Create Completed!';
Form3.Show;
end;
(代码4)
这个程序在运行后将显示三个窗体,分别是Form1,Form2,和Form3。你可能在想,如果要关闭程序,只要关闭Form1这个主窗体就可以了。然而你错了,应该是关闭Form3才能将整个程序关闭。为什么呢?关键在CreateForm()这个窗体创建函数,查一下Delphi的随机帮助文件就清楚了。帮助文件有关CreateForm()函数的说明如下:
Call CreateForm to dynamically create a form at runtime. Developers do not need to add code for creating most forms, because typically one or more calls to CreateForm are added automatically to the project's main source when using the form designer.
CreateForm creates a new form of the type specified by the FormClass parameter and assigns it to the variable given by the Reference parameter. The owner of the new form is the Application object.
Note: By default, the form created by the first call to CreateForm in a project becomes the application’s main form.
特别注意最后一句,默认地,在一个Project中第一个由CreateForm调用创建的窗体就成为应用程序的主窗体。这样就不难解释为什么需要关闭Form3才能关闭应用程序了。因为程序中第一个使用CreateForm的是在Project1.dpr中的一段代码:
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
这段代码是在Project.dpr中自动生成的,然后我们在Form1中的OnCreate()事件函数第二次使用CreateForm,这时Form1的创建还没结束( 因为OnCreate事件还没完成 ),程序的主窗体就已经改变了,变成了Form2 , 然后我们又在Form2中的OnCreate()事件函数第三次使用CreateForm,这时程序的主窗体变成了Form3 ,也就是说程序的生杀大权已经掌握在Form3手中。绝对不要再在Form3的OnCreate()事件函数中加入Application.CreateForm(TForm1,Form1),否则,程序将进入一个资源创建的死循环,一点一点地耗尽你的机器的内存。
从这里也可以看出Delphi并不是完全的面向对象,它不像Java那样可以随时随地创建一个窗体。
2.窗体权限的保留
如果我们想在Form1中保留程序的权限,则需要新建一个Button,然后把Form1中的OnCreate()事件函数的代码放在Button的OnClick()事件中。这时则只有关闭Form1,才能关闭整个程序。
3.动态选择创建窗体
回到我们一开始提出的问题,如何动态的有选择地创建窗体呢?我们用一个随机数模拟实际可能出现的动态情况,实际情况可能是程序在初始化时动态判断一个文件或数据库的一个值,由这个值决定是先显示Form2还是先显示Form3,还是只显示Form1 。代码如下:
procedure TForm1.FormCreate(Sender: TObject);
var
randomnum:Integer;
begin
Label1.Caption:='Form1 Create Complete!';
Randomize;//设置随机器
randomnum:=Random(10);//在0到10之间取随机值
if (randomnum>0)and (randomnum<=4) then//如果随机值在0到4之间
Begin
Form1.Show;
Application.CreateForm(TForm2, Form2);
End
else if (randomnum>4)and (randomnum<=8) then//如果随机数在4到8之间
Begin
Form1.Show;
Application.CreateForm(TForm3, Form3);
End
Else //如果随机数在8到10之间
Form1.Show;
end;
本文地址:http://www.45fan.com/dnjc/73479.html