第3章d体系结构的_第1页
第3章d体系结构的_第2页
第3章d体系结构的_第3页
第3章d体系结构的_第4页
第3章d体系结构的_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第 3 章Delphi 体系结构的关键类好的软件开发工具的标志是:它是面向对象的、可自行扩展的、并可以促进好的软件开发实践。Delphi 满足了所有的要求。Delphi 使用 Object Pascal 语言,它本身也是用该语言建立的。Delphi 可以自行扩展(请参照附录 A“使用 OPENTOOLS API 的 Delphi 扩展示例”)。高质量的语言和体系结构促进了好的实践。由Delphi 的类的特征可以看出:它是相容的、一致的、均衡的。为建立出色的应用程序,了解工作所用的体系结构框架是有益的;模仿的例子也是明智的。本章强调了的 Delphi 类,它们可以极大地加强对 Delphi 的理

2、解,而且有助于建立的软件。尽管本章。无法详尽地展示 Delphi 的类,但其中将包含关键性的类并给出有助于您获取信息的3.1浏览 Delphi 的体系结构在 Project Browser 中,可以看到 Delphi 的所有类。即时获取所有这些类的知识是一项惊人的技能,然而如果不理解 Delphi 的基本结构,这也是个代价高昂的错误。总是可以通过按键 Alt+V,B 来显示 Project Browser(见图 3.1),它就是 View 菜单上的 Browser 菜单项。注意:在本书写作时,Project Browser 中的类和属性无法与帮助文档交叉在 Delphi 6 发布时将得到解决。

3、这个问题Project Browser 将向您提供组成 Delphi 的所有类的层次化视图。在层次树中,每个较低层的类都是上一个较类的子类。这意味着该类的所有一切,或者是在该类中定义的,或者是由树中较次的祖先类继承而来。有了类或属性的名字,就可以帮助文档中相应的项。您可以很快找到类或属性在 VCL 中定义的位置。可遵循如下步骤进行:1. 在 Delphi 中单击 View 菜单,Browser 菜单项。2. 在 Project Browser(见图 3.1)中找到 TObject 类。3. 双击 TObject。这将打开 Symbol Explorer,如图 3.2 所示。4. 在 Symbo

4、l Explorer 中当前对象为 TObject,双击 Dispatch 方法。这样 Symbol Explorer 就会转到包含Dispatch 方法的单元。5. 在 Symbol Browser 中双击 Dispatch 方法。这将打开 systems.pas 单元,光标停留在 Dispatch 方法上。图 3.1 按键Alt+V,B 可显示 Project Browser,它第 3 章 Delphi 体系结构的关键类65提供了对所有的Delphi 类的层次化视图图 3.2 Symbol Explorer 可以迅速到当前符号,对其双击即可提示:保存并编译工程,即可将译都会更新浏览器中的符

5、号。的类和符号加入到 Project Browser 中。Delphi 每次编以这种方式配置和使用 Project Browser,可以获取任何需要的类或属性的信息。加入自定义的类或属性后,编译应用程序后 Delphi 将把这些信息加入到 Project Browser,而且每次编译后都进行更新。出于示范目的,打开一个默认工程,添加一个名为 TAAA 的类,该类有一个过程 Foo。class TAAAprocedure Foo; end;编译默认工程,即可看到 TAAA 类;如果不明确指出,则在默认情况下它继承了 TObject,在 Symbol Browser 中可以看到 Foo 过程。双击

6、 Foo 将打开包含 TAAA 类的单元,光标置于 Foo。3.1.1Project Browser 选项通过修改配置选项,可以改变在 Project Browser 中可见的细节层次。浏览器的行为由 Explorer Options的状态所决定(见图3.3)。打开Project Browser,单击右键显示Project Browser 上下文菜单,再单击Properties,即可看到 Explorer Options。第 3 章 Delphi 体系结构的关键类66图 3.3 Explorer Options 将对显示在 Project Browser 中的信息进行过滤请阅读下面的各个小节,

7、其中包含了Explorer Options中的各个组对Project Browser 的影响的有关信息。表 3.1 描述了 Explorer Options 中的每个选项对 Project Browser 的影响。表 3.1 Project Browser 的选项过滤了在浏览器中可的数据选项组选项描述Explorer Options Explorer Options Explorer OptionsExplorer SortingAutomatically show Explorer Highlight incomplete class items Show declaration synta

8、xAlphabetical若选中,浏览器显示时停靠在代码编辑器旁若选中,整的属性以黑体显示若选中,语法将与符号一同显示以字母顺序列出源代码单元(续表)选项组选项描述Explorer SortingClass Completion OptionSourceFinish incomplete properties以顺序列出源代码单元若选中,当在代码编辑器上下文菜单中选择Complete Class at Cursor 时,则自动完成read 和write 方法及其默认实现单选按钮组,决定了当打开Project Browser 时, 默认选择了三个属性页classes、units、globals 中

9、的哪一个只显示工程的符号不仅显示工程的符号,也显示 VCL 的所有符号Explorer Categories 中的每个复选框都决定了是否显示对应类型的符号。可以对项的数目和种类进行过滤,以简化特定项的查找Initial Browser ViewClasses, Units, or GlobalsBrowser Scope Browser ScopeExplorer CategoriesProject symbols onlyAll symbols (VCL included) (复选框列表)表 3.1 中属于 Explorer Options 的所有选项都很有用,如果一定要说某些选项比其他更为

10、有用的话,Finish Incomplete Properties 确实可以帮助您编写代码。如果选中该选项,则 Delphi 将自动完成特性的和实现。对于简单类型,Delphi 将写出代码。对于较为复杂的类型,Delphi 将完成特性的的函数体。按下列示范的各个步骤即可进行。并写出实现1在默认工程的 Unit1 单元中,添加类 TFoo(请确认已经选中 Project Browser 的Finish Incomplete Properties第 3 章 Delphi 体系结构的关键类67选项)。2在 TFoo 中如下定义私有字段:FI:Array1.10 of String;3部分定义如下的公

11、有特性:property IIndex : Integer : String;4. 单击右键显示代码编辑器上下文菜单。5. 单击 Complete Class at Cursor。Delphi 将自动写出如下代码。interface typeTFoo = class privateFI : array1.10 of string; function GetI(I: Integer): String;procedure SetI(I: Integer; const Value: String); publicProperty II: Integer : String read GetI writ

12、e SetI; end;implementation TFoo function TFoo.GetI(I: Integer): beginend;procedure TFoo.SetI(I: Integer; beginend;String;const Value: String);可以注意到 read 和 write 已添加到特性。对应的 get 和 set 方法已经在 TFoo 类中,而实现部信息请参见分也添加了方法体的定义。自动完成类是最近才添加到 Delphi 中的特性(关于索引特性的第 8 章)。3.1.2理解Project Browser 中的作用域、继承和在 Project Br

13、owser 中,Scope、Inheritance 和 References 三个属性页各自提供了不同而重要的信息。Scope属性页列出了具有选定的类的作用域的属性,它们是该类的成员。Inheritance 属性页只显示了从 Project Browser 左侧选定的类继承而来的那些类。例如在默认的新工程中,Delphi 创建了类 TForm1,它继承了TForm 类。选定 TForm,则 TForm1 将显示在 Inheritance 属性页中,它从属于 TForm。References 属性页显示了特定项的单元。例如,(本书写作时)TForm 在 forms.pas 第 25 行有一个向前

14、,其定义位于该单元的 672 行。对于想快速解决问题时查找已有的类和方法,Project Browser 是个有效的工具。使用 Project Browser, 专业程序员是很快就可以发现 Delphi 一些高级功能的实现细节。3.2根类在 Delphi 中有三个根类:TObject、IInterface 和 IUnknown。IInterface 和 IUnknown 是为了支持 COM 和 DCOM 编程的子类化。对 Delphi 体系结构中的所有子类而言,TObject 是主要的根类。在理解了 TObject 之后,在 Delphi 环境中设计新系统的体系结构可能会更容易。3.2.1TO

15、bject 类Delphi 中的所有类都由 TObject 继承而来。无论子类显式的继承了 TObject,还是没有显式的父类,或第 3 章 Delphi 体系结构的关键类68者继承了一个现存的类,这一点都是正确的。使用动态类型检查,(AnyClass is TObject)测试总是得到真值。BooleanResult := AnyClass Is TObject;有四个基本性的方法确保所有的类都表现出基本的行为。第一种行为是,所有的类都有默认的构造函数,可以创建实例。第二种行为是,所有的类都有析构函数,可以删除创建的实例。第三种基本的行为是,所有的类都可以调用继承而来的 Free 方法而从内

16、存中,Free 方法将检测对 Nil 对象的调用以避免错误。第四种基本行为是,所有的类都可以响应 Windows 消息。默认构造函数TObject 根类中的默认构造函数是 Create。TObject 类定义于 systems.pas 单元中。所有的单元都默认地使用 systems.pas 单元,在任何单元的 Uses 语句中systems.pas 都是不必要也不可能的。默认构造函数是静态的,即没有任何虚函数,如下所示:constructor Create;可以注意到没有任何指令,这说明构造函数既不是动态的也不是虚的。这意味着根类的构造函数无法在子类中重载(对于继承、多态、方法的重载的详细内容

17、请参见第 6 章)。但对于新类仍然可以定义额外的构造函数,包括与默认构造函数原型相同的构造函数。默认析构函数在 TObject 类中,默认析构函数定义为空的虚方法。TObject 类中的说明使用了 destructor 关键字。destructor Destroy; virtual;类可以有多于一个的析构函数,但只能重载默认析构函数而不能向其传递参数。如果调用 Free 的对象非空,析构函数将由 Free 调用(关于析构函数请参见第 6 章)。TObject 类的 Free 方法过程 Free 定义于 TObject 类中。从技术上说,Free 可以重载,但不应该这样做。在 TObject 类

18、中,Free 定义为内嵌汇编过程;它首先确认调用者是有效对象,即不是 nil 对象;然后直接索引虚方法表来调用正确的 Destroy 方法。为了避免不必要的错误,在删除一个对象时,总是调用 Free 或FreeAndNil。提示:可将任何对象实例传递给 FreeAndNil 过程,它将调用对象的 Free 方法然后将实例赋值为 Nil。Dispatch 方法为 Delphi 提供了明显的优势Dispatch 方法经常被开发者忽略。它在 TObject 类中引入,为 Delphi 提供了额外的在其他工具中不存在的响应性。Windows 只向 Windows 控件消息,如列表框、组合框、编辑控件等

19、,这些控件都有句柄。因此像 Visual Basic 中的等控件是无法直接响应 WM_PAINT 之类的 Windows 消息的。由于 Delphi 中的每个类都是 TObject,因此 Delphi 中的每个类都可以响应 Windows 消息。警告:Delphi 6 可能会废弃 Dispatch 方法,以避免与 Kylix 的不兼容问题。Kylix 运行在UNIX 操作系统中,其消息系统与 Windows 并不相同。在本书写作时,Dispatch 方法在Delphi 6 的beta 版中仍然存在并可用。每个应用程序都包裹在 TApplication 对象的实例中。在工程源文件中,Applic

20、ation.Initialize 调用前, 将为Application 对象创建一个Windows 句柄。然后Application.CreateHandle 调用API 函数SetWindowLong, 将一个 WndProc 过程的地址作为参数传递。应用程序的消息被到 Application.WndProc 过程。所有的TControl 控件都继承了 WndProc 方法,使得它们可以继承 Windows 消息( 下面的代码列出了SetWindowLong,WndProc,Dispatch 的)。LONG SetWindowLong( HWND hWnd, int nIndex, LONG

21、 dwNewLong );第 3 章 Delphi 体系结构的关键类69Procedure WndProc( var Message : TMessage );Procedure Dispatch(var Message);TControl.WndProc 过程在WndProc 方法的结尾处调用 Dispatch 方法。Dispatch 方法将检查控件是否响应该类型的消息,消息类型由 Message 参数中的消息 ID 指定。如果对象不直接响应该消息,则检查其所有祖先是否响应该消息。如果对象中没有响应该消息的部分,则调用 DefaultHandler。例如,当对 TButton 控件按下鼠标左

22、键,则调用了该控件的 WndProc 过程。该过程调用 Dispatch 方法来查看按钮的虚方法表。实际上,消息 WM_LBUTTON 有消息处理程序 WMLButtonDown,因此调用该消息处理程序。这个特定的消息处理程序定义为调用 DoMouseDown 过程。由于 Dispatch 是在 TObject 中引入的,即使没有 WndProc 过程的控件也可通过 Dispatch 接收消息(关于如何利用消息处理程序和 Dispatch 方法,请参阅第 6 章)。3.2.2COM 接口IInterface 是 IUnknown 接口的别名。在 Delphi 中,IUnknown 是所有 CO

23、M 接口的根接口。IUnknown接口了三个方法:QueryInterface、AddRef 和Release。QueryInterface 确保接口的用户可以向对象实例接口属性。AddRef 在每次中活动。Release 用于为对象的中删除。调用 QueryInterface 后对计数加 1,确保当存在时对象在内存计数减 1。当计数到达零时,对象或通过接口的对象被从内存3.3组件的继承Delphi 中的所有组件都由 TPersistent 类继承而来。这意味着不一定每个类都是组件,但每个组件都具有 TObject 和 TPersistent 类的的基本功能。本节中,通用的基础知识。浏览 TP

24、ersistent 类及其后代,了解组件的一些3.3.1TPersistent 类众所周知,增长与迭代是面向对象的标语。这意味采取婴儿学步的方法。对体系结构采用小而逐步的改动是最好的。当子类中的改动以微小的增长式进行时,存在着更少。的分支可能性而对子类的限制可能会警告:如果创建了具有抽象方法的类的实例,将产生 EAbstractError 错误,因为没有定义方法。TPersistent 类是没有实例的。TPersistent 类有抽象方法。通常不必要创建 TPersistent 类的对象。它们将使用$M 指令编译,编译器将对 TPersistent 及其派生类添加运行时类型信息。TPersis

25、tent 所做的就是描述了一个接口,其中引入了对象的可赋值性、标识、所、以及是否可流化等性质。这就是它所作的。它使得其派生类可以用名字建立标识,可以被拥有,其他一些对象还可以与 TPersistent 对象有聚合关系。TPersistent 描述了应该怎样实现对象的赋值。TPersistent 还引入了持久化对象应当能够从持久中读出或写入自身的概念。通常持久性是以 Windows文件的形式出现的,但不一定是这样。持久化类引入了所概念TPersistent.GetOwner方法返回 nil。想要建立所的子类可以重载 GetOwner,如同链或所TComponent 类所作,返回对象所有者 TPe

26、rsistent 子类的。例如,按钮可以放置在窗体上然后窗体即取得了按钮的所。这样,按钮的 GetOwner 方法将返回相应的窗体(参见第 4 章)。当使用 Project Browser 时,在家谱链中向下一层,可以很明显地看到 TComponent 类确实是这样做的。考虑到图形用户界面的外观,显然需要对所进行跟踪。如果窗体不知道置于其上的控件,消息怎能传播到所包含的控件。那是不可能的。所链是必要的,因此 TPersistent 类中引入了这个概念。持久化类具有标识为确保组件名出现在Object Inspector 中而定义了GetNamePath。它是组件在 Object Inspecto

27、r 中的外观,第 3 章 Delphi 体系结构的关键类70确保了可以在设计时对象。持久性包含了可赋值性有两个虚方法 Assign 和 AssignTo 可用于解决可赋值性的问题。组件可能包含许多特性和一些对象。例如,可视化组件拥有 TCanvas 对象,可用于绘制控件的图形外观。当对象被赋值时,对象的属性也需要被赋值。TPersistent 类中Assign 和 AssignTo 的实现如下。procedure TPersistent.Assign(Source: TPersistent); beginif Source <> nil then Source.AssignTo(S

28、elf) else AssignError(nil); end;procedure TPersistent.AssignTo(Dest: TPersistent); beginDest.AssignError(Self);end;Assign 调用 Source 参数的 protected 方法 AssignTo。如果 Source 不为 nil,则基于 Source 对象的特定类型调用 Source.AssignTo 方法。在子类中重载 Assign 方法,可以确保持久化对象知道如何向同类型的对象赋值。属性的持久化在 TPersistent 中引入对象持久化是很重要的。DefinePrope

29、rties 方法要使用 TFiler 对象从.dfm 文件读或写特性。当用文本格式窗体时,您所看到的文本是用 DefineProperties 方法写入的。这是持久化属性的文本表示。按下列步骤,可以用文本格式窗体文件:1在窗体中单击右键,显示窗体上下文菜单,如图 3.4 所示。图 3.4 从窗体上下文菜单选择View as Text,可以看到表示窗体的持久化数据2单击 View as Text,持久化窗体的文本表示。3按键 Alt+F12,转换到图形表示。注意:窗体文件可能被破坏。尽管可以在文本格式下对窗体进行处理,并将结果反映到图形格式中,但最好还是让 Delphi 和 Object Ins

30、pector 来进行这项工作。从文本格式显然可以看出,属性是按照名字和值成对以层次关系的。这实在是一种很优雅的方式。在 TPersistent 类中引入了 DefineProperties 方法。在 TComponent 类中实现了该方法,用于将特性写入 DFM 文件。DefineProperties 方法可以重载,以实现某些定制的高级组件技术(高级的组件编写技术请参见第 10 章)。3.3.2TComponent 类TComponent 是 TPersistent 类的直接后代。TComponent 类实现了 DefineProperties、GetOwner 方法,第 3 章 Delphi

31、 体系结构的关键类71以及两个引入了笛卡尔坐标位置的特性:Top 和 Left。TComponent 类引入了控件所有的组件数目的组件计数值、以及对象的名字和 Notification 方法。的概念、包含了拥注意:当在 Object Inspector 中选定所有者时,其内部组件也会。这是与以前版本的根本区别。在 Delphi 的较早版本中,内部对象的和特性必须被提升到外部对象的接口中。Delphi 6 使得内部对象可以10 章)。其自身,因而可以直接进行处理(的信息请参见第当或删除组件时,将自动调用 Notification 方法。Notification 方法的语法如下。procedure

32、 Notification(AComponent: TComponent; Operation:TOperation); virtual;所变动使得对象可以更新对所拥有的对象的。例如,处理程序的可设置为Nil(第 10 章示范了 Notification 的用法)。TComponent 也不能直接实例化。TComponent 对 TPersistent 类的能力有所增长。3.3.3TControl 类VCL 中的大多数类都是不可见的。这意味着组件可以在设计时进行可视化处理,而运行时可能并不存在可视化的外观。TControl 类由 TComponent 类子类化而来。TControl 类引入了可

33、以在设计和运行时的属性,使得可以可视化组件的外观和行为。外观的特性有 Cursor、Top、Left、Height 和 Width。TControl 类监视边界矩形,即包含控件图像的屏幕区域,还监视客户区矩形,即可以根据数据值进行修改的区域。例如,TImage 控件属于 TControl 类。控件会监视其自身与所表示的数据之间的不同之处。这样,TImage 实例拥有一个可视化区域,而其中一部分用于显示图像。控件包含一些行为,使得可以在笛卡尔平面上按照相对于 z 轴次序所呈现出的虚拟外观处理其实例,并且可以相对于 x-y 坐标进行对齐。z 轴次序创建了三于设计出整洁的外观。的假象。Align 特

34、性使得易TControl 类也引入了。可视化控件需要响应用户输入和 Windows 消息,这会影响控件的行为。包括是否在控件的某部分发生了鼠标单击,以及控件的一部分被遮住后又显现出来而需要重新绘制屏幕等。Delphi 使非Windows 控件也可以接收消息,从而扩展了 Windows 的行为。由于 Dispatch 是在 TObject根类一级定义的,因此消息会增强,使得开发者可以更好地到一些 Windows 通常图形用户界面和非可视化类。消息的控件。通过 Delphi 对 Windows 的3.3.4TWinControl 类TWinControl 类是TControl 类的子类。TWinC

35、ontrol 控件包含Windows 句柄,使得它们可以成为Windows操作系统的当前输入焦点。Windows 体系结构中只有窗口控件有 Windows 句柄,因而可以从 Windows 操作系统接收输入。Delphi 的体系结构使得消息可以到没有 Windows 句柄的 VCL 控件。TWinControl控件有窗体、框、组合框以及编辑控件等。要完整地浏览 Delphi 体系结构中的 TWinControl 分支,请参见 Project Browser。3.3.5使用新的化组件新的 TLabelEdit 控件是个小的改进,它在编辑控件中包含了。不太别致但很有用,因为编辑控件和控件通常成对出

36、现。默认情况下,位于编辑控件的上方,与编辑控件的左侧对齐,但相对于编辑控件的距离和位置可以在 Object Inspector 中修改。TLableEdit 控件说明了面向对象编程中两个好的策略。在设计新的组件时,改动要比较简单,尽可能从现存的组件派生,而不要修改已有的组件。扩展现存的组件避免了对已有代码的重新测试和对已有应用程序的不利影响,而且在编程工具集中增加了一个组件。3.3.6特性编辑器类特性编辑器类定义在 dsgninif.pas 中,源自 TPropertyEditor 类,用于管理复杂的特性。Object Inspector中的所有特性都是用特性编辑器进行修改的。整数字段用 TI

37、ntegerProperty 类的实例进行修改,而字符串字第 3 章 Delphi 体系结构的关键类72段使用 TStringProperty 编辑器。特性编辑器类有助于添加范围合理的数据,简化了复杂特性的管理,如TStrings 中的字符串和 TImage 中的 Picture 特性等。像 TStringProperty 之类的简单特性编辑器几乎是透明的。在 Object Inspector 中,它们表现为简单的输入域。当修改 TStrings 类型的特性时,会打开 String list editor编辑。框(见图 3.5),利用它可一致性地进行图 3.5 字符串列表编辑器是TString

38、ListProperty 类的实例,该类定义在stredit.pas 中特性编辑器为组件开发者提供了方便的起点,可以在设计时对非平凡的类进行修改。默认情况下,如果在类中添加了具有对关联的特性编辑器的特性,当在 IDE 中修改该特性时则会显示编辑器。当需要自定义的特性编辑器时,子类化相对最为接近的编辑器类即可。当创建商业组件时可以这样作。新的特性编辑器必须。Delphi 提供了所有内建的工具以完成必要的任务(关于自定义特性编辑器的创建和,请参阅第 11 章)。3.4TApplication 类TApplication 类是 TComponent 类的直接子类。每个传统的 Delphi 应用程序都

39、封装在一个 Application对象中,该对象包含了程序的主窗口的句柄,提供该句柄 Windows 操作系统可以向应用程序消息。注意:关键字 initialization 和 finalization 可放置于每个单元的结尾处。当单元装载到内存中时,initialization 部分的代码在单元中其他代码以及 finalization 部分运行前运行(的信息,请参见 VCL 单元 control.pas)。您的程序所需的惟一的 TApplication 对象是自动创建的。control.pas 单元的 initialization 部分调用了该单元中的本地过程 InitControls,该过

40、程创建了全局对象 Application 的实例。全局变量 Application 类型为TApplication,在 forms.pas 单元的 Var 部分。察看每个可执行工程的.dpr 文件,可以看到 forms.pas 是Uses 子句中的第一个单元。除了 Windows 句柄,Application 对象还包含对应用程序的主窗体、帮助文件、应用程序标题的。程序也可以接收到应用程序层的,下一小节对此进行描述。3.4.1Application响应 Application是 Application 对象的责任。应用程序运行过程中可能遇到任何此类,但如果编写了处理程序,在需要时即可对应用程序

41、进行微调。表 3.2 描述了可用的 Application可对这些编写处理程序。表 3.2 可以在代码中处理的 Application使用TApplicationEvents 组件来处理这些,可以名描述第 3 章 Delphi 体系结构的关键类73当组件的动作列表中没有定义 OnExecute 的OnActionExecute处理程序时,对组件的OnExecute进行响应OnActionUpdate当组件的动作列表中没有定义OnUpdate 的进行响应当应用程序获得当前输入焦点时,调用当应用程序失去当前输入焦点时,调用处理程序时,对组件的 OnUpdateOnActivate OnDeacti

42、vateOnException处理程序处理程序当发生未处理的异常时,调用处理程序。该处理程序确保即使未处理的异常也被记入日志,例如Windows NT日志当用户按键 F1 或用 HelpJump、HelpCommand 或HelpContext 请求帮助时,将触OnHelp发该动作。对于 F1 键的响应,在Project Options框中的Application 属性页(见图 3.6)中需要标识出帮助文件,并且控件必须有非零的 HelpContext 特性值OnHint在显示控件提示信息前,调用处理程序。控件的 ShowHint 特性必须为 True,而且其 Hint 特性必须为非空的字符串

43、值与用户交互的大多数应用程序都有许多时间处于空闲状态(在 Windows 任务管OnIdle理器中观察进程时,可以很明显地看到这一点)。空闲处理程序可以在空闲处理程序返回时,程时执行任务。这些任务要尽可能短,否则用户等待序的响应会显得很迟缓OnMessage OnMinimize OnRestore OnShortCutOnShowHint可用于预览所有到应用程序的消息当应用程序最小化时,调用处理程序当应用程序从最小化状态恢复时,调用处理程序当按下快捷键组合时,调用处理程序当应用程序要显示提示时,调用处理程序图 3.6 通过编程或在Project Options框的Application 属性

44、页中将帮助文件与应用程序关联。按键Alt+P,O 可打开 Project Options框表 3.2 中的予所匹配的是 TApplication 类的过程类型特性。在一个类中类型正确的方法然后将该方法赋特性,这样就对这些创建并分配了处理程序。TApplicationEvents 组件是 Delphi 最近的处理程序的创建。的一个增强,它方便了对 Application3.4.2使用TApplicationEvents 组件TApplicationEvents 组件(如图 3.7 所示)位于组件面板的 Additional 属性页上。与其他组件相同,单第 3 章 Delphi 体系结构的关键类7

45、4击窗体或数据模块即可放置它,并修改 Object Inspector 中的。每个处理程序都有一组不同的参数。下面列出的代码示范了如何将默认的亮黄色提示改为红色提示。procedure TForm1.ApplicationEvents1ShowHint(var HintStr: String;var CanShow: Boolean; var HintInfo: THintInfo);beginif( HintInfo.HintControl图 3.7 TApplicationEvents 控件= ButtonCommit ) thenHintInfo.HintColor := clRed;

46、CanShow := True;end;上面的代码对于伪数据库提交操作模拟了如何将提示的颜色改变为红色。如果 HintInfo.HintControl 控件为提交按钮,则提示 HintColor 改变为引人注目的红色。按下列步骤,可重复上面的例子:1. 创建新的应用程序。2. 在自动创建的默认窗体上,绘制出一个 TButton 控件。3. 对步骤 2 所绘制的按钮控件,对其名字特性键入 ButtonCommit。4在组件面板上选定 Additional 属性页。5. 在窗体上绘制出 TApplicationEvents 控件(如图 3.7 所示)。6. 在 Object Inspector 中

47、,选定 ApplicationEvents1 对象。7. 单击 Events 属性页,双击 OnShowHint 特性(Object Inspector 中的最后一项)来创建前面代码中的方法体。8. 键入 Delphi 无法自动生成的代码。9. 确认 CommitButton 按钮的 ShowHint 特性值为 True,而且已经对按钮的 Hint 特性键入了非空字符串值。按键 F9 运行例子程序。当在 CommitButton 按钮上移动鼠标时,提示将是红色的。可利用 Application确保未处理的异常写入到 Windows NT改进也可以在应用程序层合并进来。日志,空闲的处理器时间得到

48、有效利用,而一些自定义的3.5新的 Windows Shell 组件Delphi 中增加了新的 Shell 控件,可以很容易地创建文件系统管理界面来Windows 98、Windows2000 和Windows NT 4.0 中的较新的文件系统,如图示。新的控件代替了FileListBox、DirectoryListBox、DriveComboBox 和 FilterComboBox,以创建新的文件管理界面。第 3 章 Delphi 体系结构的关键类75图 3.8 使用新的Windows 控件,在 5 分钟内就可以重新创建一个Windows Explorer新的控件有 TShellTreeVi

49、ew(见图 3.8 的左侧), TShellListView(见图 3.8 右侧中部),以及 TShellComboBox(见图 3.8 中工具栏)。图中所示的例子程序无须代码即可快速创建。只需少量代码,即可为应用程序创建类似 Windows Explorer 的窗体。每个控件都有一个或多个特性指向程序中与其相关的控件,可以自动地反映出发生的变化。3.6图 形 类在 Delphi 中有五组类用于管理与图形相关的数据和功能,其中有四组直接由 TPersistent 子类化而来, 第五组是一个控件。TCanvas、TGraphics、TPicture 和 TGraphicObject 都是由 TP

50、ersistent 子类化而来。TGraphicControl 是第五个图形类,由 TControl 派生而来。所有在窗体上具有可视化表示的控件内部都包含 TCanvas 对象,该对象负责在控件的边界矩形内部显示文字和图形。TGraphic 类的子类有 TIcon、TBitmap 和 TMetaFile。TGraphicObject 类的子类有TBrush、TFont 和 TPen。TCanvas 对象用于对 Windows 尚未渲染的控件进行表面绘制,如 TEdit 和 TListBox 等。TGraphicControl 的子类有 TBevel、TCustomLabel、TImage、TP

51、aintBox、TShape 和 TSplitter。这些控件都具有可视化的效果,但并不接受用户的文本输入。TGraphicControl 控件没有 Windows 句柄,因此无法维护当前输入焦点。下面的代码示范了 TGraphic 对象的动态实例化,从磁盘驱动器加载.emf 元文件,将其赋予 TImage 对象的 Picture 特性。varGraphic : TGraphic; beginGraphic := TMetaFile.Create; tryGraphic.LoadFromFile( 'shepherd.enf'); Image1.Picture.Assign(G

52、raphic);finally Graphic.Free;end;end;注意:TGraphic 类是抽象类。尽管了 TGraphic 变量,但实际上实例化了它的一个子类TMetaFile,然后将实例赋予超类的变量。虽然 TImage 对象的 Picture 特性是对象而且有其自身的 LoadFormFile 方法,但上面的代码示范了TGraphic 类在技术上的应用。TImage 对象包含 TCanvas 对象。而 TCanvas 对象有 Windows 句柄。如果需要一系列的图像但不必立即,那么 TGraphic 类的较为实际的用法是装载一些图形对象而不是TImage 对象,以避免浪费大量

53、的 Windows 句柄。3.6.1TCanvas 类TCanvas 类封装了用于渲染图像的 Windows 设备描述表。TCanvas 包括了基本的文本和图形渲染方法,它使得对于 Windows 图像的管理不易出错。下面的例子示范了用窗体的 Canvas 特性显示浮雕式的文字。当窗口每次重画时,文字都会更新。产生浮雕效果的代码在下面列出(参见图 3.9 中的输出)。图 3.9 通过直接写TCanvas 对象产生的浮雕文字效果第 3 章 Delphi 体系结构的关键类76procedure TForm2.FormPaint(Sender: TObject); constSOFTCONCEPTS

54、_WEB = 'varFontRecall : TFontRecall; begin'FontRecall := TFontRecall.Create( Canvas.Font ); trySetBkMode( Canvas.Handle, Windows.Transparent ); Canvas.Font.Color := clWhite;Canvas.Font.Style := fsItalic, fsBold; Canvas.Font.Size := 16;Canvas.Font.Name := 'Times New Roman' Canvas.Text

55、Out(10, 10, SOFTCONCEPTS_WEB);Canvas.Font.Color := clGray; Canvas.TextOut( 9, 9, SOFTCONCEPTS_WEB );Canvas.Font.Assign( FontRecall.Reference ); finallyFontRecall.Free; end;end;提示:按照通常的规则,应避免在处理程序中编写代码。而应该编写名字与行为相符合的方法,然后在处理程序中调用该方法。这样可以提高代码的可读性,促进代码重用。重用名为 WriteEmbossedTextToCanvas 的方法或其他效果相同的东西,远比重

56、用一个接受TObject 参数的通用处理程序要简单得多。从上面列出的程序的第一行显然可以看出,代码是直接编写在窗体的 Paint的处理程序之中的。开始时,一个较新的类 TFontRecall 被实例化,以Canvas 的 Font 对象的当前状态。然后调用 Windows过程 SetBkMode 来设置背景模式,以得到最好的效果。Canvas 的句柄实际是 Windows 设备描述表,因此可以将 Canvas.Handle 传给 SetBkMode 过程。可以修改包含在窗体画布(即 Canvas 对象)中的字体对象的特性来得到想要的效果:首先输出文字,然后修改字体颜色,再以不同的颜色、稍许改变的 x-y 坐标重新输出同样的

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论