大多数 Delphi 7 的应用程序至少有一个 TForm的实例。Delphi 7 VCL 应用程序也只能有一个 TApplication 的实例和一个 TScreen 的实例。TForm、TApplication、TScreen 3 个类在 Delphi 7 中起着举足轻重的作用。可根据需要修改它们的默认功能。
1. TForm类
TForm 类(即窗体类)是Delphi 7 应用程序的焦点。
大多数情况下,整个应用程序都是围绕窗体操作的。从主窗体中可以打开其他窗体,通常要通过菜单命令或按钮。可以自动创建窗体,也可以选择在运行期间动态创建窗体。
注意:Delphi 可以创建不使用窗体的程序(例如控制台程序、服务和COM服务器),在这种情况下,TForm 就不再是应用程序的焦点。
显示给用户的窗体有两种:有模式的和无模式的。具体使用哪一种窗体,取决于用户是否希望能够同时用这个窗体和其他窗体交互。
1.1 显示一个模式窗体
当打开一个模式窗体后,用户无法与应用程序的其他部分交互,直到用户关闭了这个窗体。模式窗体通常是对话框,就像Delphi 7 本身自带的对话框一样。事实上,大多数情况下应当使用模式窗体。
要显示一个模式窗体,只要调用 ShowModal 就可以了。下面的代码演示了如何创建 TModalForm,并把它作为模式窗体打开。
var
ModalForm:TModalForm;
begin //创建 TModalForm 的实例
ModalForm:=TModalForm.Create(Application);
try
if ModalForm.ShowModal=mrOk then //显示这个窗体
{执行一些代码}
finally
ModalForm.Free;
ModalForm:=nil;
end; end;
上面的代码演示了如何动态地创建TModalForm 以及把实例赋值给ModalForm 变量。
注意:如果需要动态创建一个窗体的实例,就要把这个窗体从“Project Options”对话框中的“Auto-Create forms”框中去掉。
如果窗体的实例已经存在,可以调用ShowModal 函数打开它,其他代码可以删掉,缩减代码如下:
begin
if ModalForm.ShowModal = mrOk then //如果 ModalForm 已经存在
{执行一些代码}
end;
ShowModal函数的返回值是ModalForm 的ModalResult属性值。默认情况下,ModalResult 属性
的值为0,相当于预定义的常量mrNone。如果ModalResult 属性被赋值为其他非零值,则窗体将关闭。
可以在运行时对窗体的ModalResult 属性进行赋值,代码如下:
begin
ModalForm.ModalResult := 100;
end;
表 --1 所示为预定义的 ModalResult值。
常量 值
mrNone 0
mrOk idOk
mrCancel idCancel
mrAbort idAbort
mrRetry idRetry
mrIgnore idIgnore
mrYes idYes
mrNo idNo
mrAll mrNo+1
2.打开一个无模式窗体
要打开一个无模式窗体,可以调用Show 方法。无模式窗体与有模式窗体的区别在于用户可以在无模式窗体和其他窗体之间切换。这样,用户就可以同时工作于一个应用程序的几个部分。下面的代码演示了怎样动态地创建一个无模式的窗体。
var
Modeless:TModeless;
begin
if not Assigned(Modeless) then //检查无模式窗体的实例是否已经存在
Modeless:=TModeless.Create(Application); //创建窗体
Modeless.Show; //显示无模式窗体 end;
上述代码同时演示了怎样防止一个窗体的多个实例存在。注意,无模式的窗体允许用户与应用程序的其他部分交互,这样,用户可以照常使用菜单命令,或者创建TModeless 的另一个实例。因此,需要考虑这些实例的创建和删除问题。
要特别注意窗体的实例:当通过窗体的系统菜单或者窗体上的Close 按钮关闭这个窗体时,窗体并没有真正从内存中释放,它仍然还在内存中,除非关闭了主窗体(即应用程序)。在上述程序示例中,then 后面的语句只会执行一次,前提是这个窗体不是自动创建的。如果希望用户关闭了窗体就在内存中释放它,必须处理它的OnClose 事件,并且把Action 参数设为caFree,这样,VCL 就会在这个窗体关闭时释放它。
procedure
TModeless.FormClose(Sender:TObject;var Action:TCloseAction); begin
Action:=caFree; //当关闭时释放窗体实例
end;
上述代码就可以解决窗体实例在内存释放的问题了。还有一个问题,注意下面这行代码:
if not Assigned(Modeless) then
上述代码检查TModeless 的实例是否已经有Modeless 变量引用,这实际上就是检查Modeless 是否为nil。尽管第1 次进入例程的时候,Modeless 可能是nil,但第2 次进入这个例程的时候,它已经不是nil。这是因为VCL 并没有把Modeless变量设为nil,因此,必须手工把这个变量设为nil。
与模式窗体不同的是,无法在代码中判断无模式窗体什么时候将删除,这样就无法在创建窗体实例的例程中删除窗体的实例。用户有可能在应用程序正在运行的任何时候关闭无模式窗体。因此,无模式窗体本身一定要把Modeless 变量设为nil,而且最好在处理窗体的OnDestroy 事件的处理过程中设置这个变量:
procedure
TModeless.FormDestroy(Sender: TObject);
begin
Modeless:=nil; //把Modeless
变量设置为nil
end;
这样就能保证每次关闭窗体时,Modeless 变量总是被设为nil,从而防止Assigned()函数失败。注意,同一时刻只能创建TModeless的一个实例。
注意,对于无模式窗体来说,要避免出现下列有缺陷的代码:
begin
Modeless:=TModeless.Create(Application);
Modeless.Show;
end;
上述代码会导致每次创建窗体的实例,重复以前被Modeless 引用的实例,从而消耗了大量的内存。
尽管通过Screen.Forms可以访问这些实例,但最好还是尽量避免使用上述代码。向构造器Create()传递nil造成无法在Modeless 实例变量被覆盖后,无法再引用这个窗体实例指针。
3.窗体的图标和边框
TForm 有一个BorderIcons属性,包含下列元素:biSystemMenu、biMinimize、biMaximize 和biHelp。只要让这个集合不包含其中的某个元素,就可以使窗体上不出现相应的系统菜单、最大化按钮和最小化按钮,但窗体上总是有关闭按钮。
还可以通过BorderStyle 属性改变窗体的非客户区。BorderStyle 有6 个值供用户选择,具体如下:
[if !supportLists]• [endif]bsNone:无边框,尺寸的大小不可以改变。
[if !supportLists]• [endif]bsSingle:单线边框,尺寸的大小不可以改变。
[if !supportLists]• [endif]bsDialog:标准的对话框边框,尺寸的大小不可以改变。
[if !supportLists]• [endif]bsSizeable:标准的可变尺寸边框。
[if !supportLists]• [endif]bsToolWindow:和bsSingle 相同,但标题只有一个小的“关闭”按钮。
[if !supportLists]• [endif]bsSizeToolWin:和bsSizeable 相同,但标题只有一个小的“关闭”按钮。
注意:窗体属性BorderIcons 的设置与属性BorderStyle 的设置可能会发生互斥,例如属性BorderIcons 的biMinimize 和biMaximize会与属性BorderStyle 的bsDialog 冲突,属性BorderIcons 的biHelp 会与属性BorderStyle的bsSizeable 冲突。