delphi程序设计.2
4.4.1.2.打开无模式窗体
要打开一个无模式窗体,可以调用Show()。无模式窗体与有模式窗体的区别是,用户可以在无模式窗体和其他窗体之间切换。这样,用户就可以同时工作于一个应用程序的几个部分。下面的代码演示了怎样动态创建一个无模式的窗体:
上述代码同时演示了怎样防止一个窗体的多个实例存在。记住,无模式的窗体允许用户与应用程序的其他部分交互。这样,用户可以照常使用菜单命令,或者创建TModeless的另一个实例。因此,需要考虑这些实例的创建和删除问题。
要特别注意窗体的实例:当通过窗体的系统菜单或者窗体上的Close按钮关闭这个窗体时,窗体并没有真正从内存中释放。它仍然还在内存中,除非关闭了主窗体(即应用程序)。在上面这个程序示例中,then后面的语句只会执行一次,前提是这个窗体不是自动创建的。如果希望用户关闭了窗体就在内存中释放它,必须处理它的OnClose事件,并且把Action参数设为caFree,这样,VCL就会在这个窗体关闭时释放它。
上述代码解决了窗体实例在内存释放的问题。不过,还有一个问题,注意下面这行代码:
这行代码检查TModeless的实例是否已经由Modeless变量引用,这实际上就是检查Modeless是否为nil。尽管第一次进入例程的时候,Modeless可能是nil,但第二次进入这个例程的时候,它已经不是nil。这是因为VCL并没有把Modeless变量设为nil。因此,必须手工把这个变量设为nil。
与模式窗体不同的是,无法在代码中判断无模式窗体什么时候将删除。因此,无法在创建窗体实例的例程中删除窗体的实例。用户有可能在应用程序正在运行的任何时候关闭无模式窗体。因此,无模式窗体本身一定要把Modeless变量设为nil,而且最好在处理窗体的OnDestroy事件的处理过程中设置这个变量:
这样就能保证每次关闭窗体时,Modeless变量总是被设为nil,从而防止Assigned()函数失败。记住,同一时刻只能创建TModeless的一个实例。
注意:对于无模式窗体来说,要避免出现下列有缺陷的代码:
上述代码会导致每次都创建窗体的实例,重复了被Form1引用的以前的实例,从而消耗了大量的内存。尽管通过Screen.Forms可以访问这些实例,但最好还是尽量避免使用上述代码。向构造器Create()传递nil造成无法在Form1实例变量被覆盖后,无法再引用这个窗体实例指针。
4.4.1.3.管理窗体的图标和边框
TForm有一个BorderIcons属性,它是一个集合,包含下列元素:biSystemMenu、biMinimize、biMaximize和biHelp。只要让这个集合不包含其中的某个元素,就可以使窗体上不出现相应的系统菜单、最大化按钮和最小化按钮,但窗体上总是有关闭按钮。
还可以通过BorderStyle属性改变窗体的非客户区。BorderStyle属性的定义如下:
BorderStyle属性可以使窗体具有下列特征:
1. bsDialog不能重设大小,只有关闭按钮。
2. bsNone没有边框,不能重设大小,没有按钮。
3. bsSingle不能重设大小,有所有按钮。如果biMinimize和biMaximize中只有一个按钮被设为False,那么窗体上有两个按钮。但设为False的按钮不可用。如果二者均为False,那么没有按钮在窗体上显示。如果biSystemMenu,则没有按钮显示。
4. bsSizeable有边框,有所有按钮,按钮情况与bsSingle一样。
5. bsSizeToolWin可以重设大小,只有关闭按钮和标题栏。
6. bsToolWindow不能重设大小,只有关闭按钮和标题栏。
注意:在设计时修改BorderIcon和BorderStyle属性并不立即反映出来。这些变化要到运行期才能看到效果。其实,TForm的大部分属性都是这样的,这是因为在设计时修改窗体的外观没有多大意义。例如,假设把Visible属性设为False,如果窗体不再显示出来,那么就无法操作窗体上的组件。
粘上标题!
你可能注意到了,上面的选项没有一个选项能够创建一个没有标题但可以重设大小的窗体。要实现这种特殊窗体,需要覆盖窗体的CreateParams()方法,然后设置相关的风格。下面的代码演示了这一点:
第21章"编写自定义组件"将进一步介绍CreateParams()的用法。
清单4-2列出了怎样在运行时修改BorderIcon和BorderStyle属性的有关代码:
清单4-2BorderStyle/BorderIcon项目的主窗体单元
注意:TForm的部分属性用于设置窗体的外观,部分属性用于设置窗体的行为。要想进一步了解TForm的属性,请查找Delphi5帮助系统。
4.4.1.4.窗体重用性:可视化窗体继承
Delphi5的一个重要功能就是可视化窗体继承。在Delphi的第一个版本中,可以创建一个窗体,然后把它保存为模板,以后可以在模板的基础上创建新的窗体。但这并不是真正的继承,因为无法访问祖先窗体的组件、方法和属性。而对于真正的继承来说,派生的窗体与祖先窗体可以共享相同的代码。
继承的优势在于,应用程序可以做得比较精巧。另外,当祖先窗体的代码改变时,派生窗体会跟着改变。
对象库
Delphi5提供了对象管理功能,允许程序员共享窗体、对话框、数据模块和项目模板。这个功能称为"对象库(ObjectKepository)"。通过对象库,开发者可以共享其他项目的对象。另外,通过继承对象库中已有的对象,可以最大程度地实现代码重用。第4章讲到了对象库。最好要熟悉对象库的功能。
提示:在网络环境中,可能要与其他程序员共享窗体模板,这时需要创建一个共享的库。在Environment|Options对话框中,可以指定共享库的位置。每一个程序员必须把一个网络驱动器映射到这个位置。以后当程序员使用File|New菜单命令时,Delphi就会检查共享库所在的目录。
继承另一个窗体是很简单的,因为这已成为Delphi5环境内置的功能。要基于一个已有的窗体创建一个新的窗体,只要使用File|New菜单命令,Delphi将打开New Items对话框。这个对话框列出了对象库中的所有对象。翻到Forms页,这里列出了所有已经加到对象库中的窗体。
注意:不必在对象库中查找就能继承一个本项目中的窗体。使用File|New菜单命令,然后选择Project页。在那里,可以选择一个本项目中已有的窗体。显示在Project页中的窗体并不在对象库中。
有一些列出的窗体就是以前加入到对象库中的。可能注意到,有三个选项用于把窗体加到项目中:Copy、Inherit和Use。
如果选择Copy,则意味着把所选窗体的副本加到当前项目中。如果对象库中的窗体发生变化,不会影响到当前项目中的副本。
如果选择Inherit,则意味着从所选窗体派生出一个新的窗体加到当前项目中。如果对象库中的窗体发生变化,则派生的窗体也会跟着变化。
如果选择Use,则意味着所选的窗体直接加到当前项目中,就好像这个窗体是当前项目创建的一样。在设计时对这个窗体的任何修改都会影响以Inherit方式使用这个窗体的项目。
4.4.2TApplication类
任何基于窗体的Delphi5程序都包含一个全局变量Application,它的类型是TApplication。TApplication封装了一些属性和方法,使应用程序能够正确地在Windows环境下运行。这些方法中,有的用于建立窗口类定义,有的用于创建应用程序的主窗口、激活应用程序、处理消息、添加上下文敏感的帮助以及处理VCL的异常。
注意:只有基于窗体的Delphi应用程序才有全局Application对象,而控制台程序和服务程序没有Application对象。
一般不需要关心TApplication在背后到底做了些什么,不过,有时需要了解TApplication的详细情况。
由于TApplication并不在Object Inspector中出现,所以不能在设计时修改它的属性,但可以用Project|Options菜单命令,翻到Application页,设置一些有关TApplication的属性。在大多数情况下,只能在运行时工作于TApplication的实例即Application。也就是说,只能在运行时设置Application的属性、方法和事件过程。
4.4.2.1.TApplication的属性
TApplication具有几个属性,可以在运行时访问它们。下面将介绍这些属性以及怎样通过它们改变Application的默认行为。这些属性在Delphi5的在线帮助中也有介绍。
(1)TApplication.ExeName属性
ExeName属性能够返回应用程序的全路径和文件名。这个属性在运行时是只读的,不能修改它。但是可以读它,以使用户知道应用程序是从哪儿运行的。例如,下面的代码把ExeName属性的值显示在主窗体的标题栏上:
提示:使用ExtractFileName()函数可以从ExeName属性中得到文件名:
使用ExtractFilePath()函数可以从ExeName属性中得到全路径:
使用ExtractFileExt()函数可以从ExeName属性中得到文件扩展名:
(2)TApplication.MainForm属性
在前面的例子中,可以看到怎样访问MainForm来修改它的Caption属性以显示应用程序的ExeName值。MainForm的类型是TForm,可以通过MainForm访问TForm的任何属性和方法。也可以访问加到派生窗体的属性,只要把MainForm强制转换为该窗体的类型:
MainForm是一个只读的属性。只能在设计时通过Project Options对话框上的Forms页把一个窗体指定为主窗体。
(3)TApplication.Handle属性
Handle属性是一个HWND(一个用于Win32 API的窗口句柄)。一般情况下,用不着访问Handle属性,除非要修改Application的默认行为,而Delphi又没有提供相应的方法。此外,调用某些Win32 API时可能也需要用到Handle属性,因为那些API需要传递应用程序的窗口句柄。后面将更详细地讨论Handle属性。
(4)TAppllcation.Icon和TApplication.Title属性
Icon属性用于设置当应用程序最小化时代表应用程序的图标。可以修改Icon属性来改变应用程序的图标。后面的4.6.1节"在项目中添加资源"将详细介绍这一点。
在Windows95/98的任务栏上,显示在图标右边的文字通过Title属性设置。如果应用程序在Wndows NT下运行,则
补充:软件开发 , Delphi ,