向代码中增加方法和数据字段(Adding Methods and Data Fields to Code)
现在可以看出,在快速创建Windows应用程序的UI(用户接口)部分,Delphi是一个强有力的工具。它创建了事件处理程序,因而编程人员可以输入代码驱动其应用程序。但不久将会发现,需要在实际应用中添加更加复杂的代码。
往应用程序中增加复杂代码,其中一部分是在Delphi生成的代码中添加自己编写的数据字段及方法,例如,一个简单的应用程序可能包含有两打各种类型的事件处理程序,Delphi创建所有的事件处理程序,我们只需要在空白处填入实际代码。要使创建的应用程序能真正运转起来,我们必须编写很多方法添加到其中。
往Delphi生成的代码中添加方法和数据字段并不困难,但必须清楚规则,否则就会遇到麻烦。
Delphi如何管理类声明(How Delphi Manages Class Declarations)
正如我们知道的,在用Form Designer创建新窗体时,Delphi自动为新建的窗体建立单元文件。Delphi在创建类声明时,它把类声明创建为两段,第一段是Delphi管理的类声明部分,第二段是我们自己来管理。
在前面讲解Form Designer和Menu Designer中创建了一个名为“ScratchPad”的程序,下面的列表是ScratchPad程序的主窗体类声明。
ScratchPad主窗体类声明(THE class DECLARATION FOR ScratchPad'S MAIN FORM)
type TMainForm = class(TForm) ToolBar1: TToolBar; ToolButton1: TToolButton; ToolButton2: TToolButton; StatusBar: TStatusBar; Memo: TMemo; MainMenu: TMainMenu; FileMenu: TMenuItem; FileNew: TMenuItem; FileOpen: TMenuItem; FileSave: TMenuItem; FileSaveAs: TMenuItem; N1: TMenuItem; FilePrint: TMenuItem; FilePrintSetup: TMenuItem; N2: TMenuItem; FileExit: TMenuItem; Edit1: TMenuItem; EditReplace: TMenuItem; EditFind: TMenuItem; N4: TMenuItem; EditPaste: TMenuItem; EditCopy: TMenuItem; EditCut: TMenuItem; N5: TMenuItem; EditUndo: TMenuItem; Help1: TMenuItem; EditAbout: TMenuItem; EditContents: TMenuItem; EditSelectAll: TMenuItem; EditWordWrap: TMenuItem; OpenDialog: TOpenDialog; SaveDialog: TSaveDialog; MemoPopup: TPopupMenu; PopupCut: TMenuItem; PopupCopy: TMenuItem; PopupPaste: TMenuItem; procedure FileExitClick(Sender: TObject); procedure EditCutClick(Sender: TObject); procedure FileNewClick(Sender: TObject); procedure FileOpenClick(Sender: TObject); procedure FileSaveClick(Sender: TObject); procedure FileSaveAsClick(Sender: TObject); procedure EditUndoClick(Sender: TObject); procedure EditSelectAllClick(Sender: TObject); procedure EditCopyClick(Sender: TObject); procedure EditPasteClick(Sender: TObject); procedure EditWordWrapClick(Sender: TObject); private { Private declarations } public { Public declarations } end;
注意,组件声明的顺序与组件在窗体中的排列顺序一致。读者在“ScratchPad”中创建的主窗体类声明所包含的组件应该与上面列表中列出的相同,但排列顺序可能不一样。
有一点要特别指出:从类声明的第一行到关键字private这一段由Delphi管理,编程人员不要去动它。
Caution
在由Delphi管理的窗体类声明段中加进任何代码都会引起程序出错;一些情况下可能只是编译出错;但在某些时候也可能使程序出现无法修复的错误(这种情况很罕见,但是有可能发生)。因此,要像躲避瘟疫一样避开这段类声明。
在类声明的private段和public段添加数据字段或方法声明是安全的。还可以增加一个protected段,并在其中加进数据字段或方法。
简单介绍状态栏和提示信息(A WORD ABOUT STATUS BARS AND HINTS)
马上就要在ScratchPad程序的状态栏中加进显示提示文本的功能。在开始之前,需要简单介绍一下如何处理提示文本。
当Application对象的ShowHint属性设置为True(缺省设置),同时鼠标光标所指的ShowHint属性也设置成True时,就会触发提示事件。Application对象中有一个OnHint事件,只要提示事件被触发,该事件就会发生。Application对象的Hint属性包含了控件的提示文本。应用程序可使用OnHint事件来把提示显示在状态栏上。
问题是不能直接存取Application对象的OnHint事件。但是,可以将一个自己编写的方法分配给OnHint。这样,当提示事件发生时,该事件就改由自己的OnHint处理程序来处理。要做到这一点,就必须自己编写OnHint事件的事件处理程序。事件处理程序的编写下面再讲。
向代码中添加方法(Adding a Method to Your Code)
下面以在ScratchPad程序中实现提示文本的例子来讲解如何向应用程序中添加方法。首先,打开ScratchPad程序,如下图:
以下各步就是为每一个工具栏按钮指定提示文本,以便状态栏接收提示信息。ScratchPad中的工具栏的按钮仅仅是用于演示,但这不妨碍为这些按钮指定提示文本。
(1)显示ScratchPad的主窗体,点击主窗体工具栏的第一个按钮;
(2)在Object Inspector中找到Hint属性,并输入下面的内容作为提示文本:
Open|Open an Existing File
(3)把ShowHint属性设置为True;
(4)对工具栏中的其他按钮重复第(2)步和第(3)步。为每个按钮加上提示文本;
(5)点击主窗体底部的状态栏组件。把SimplePanel属性设置为True,使整个状态栏可以通过SimpleText属性来显示文本字符串。
现在,各项准备工作均已完成。把创建的OnHint处理程序取名为MyOnHint。首先,按下列步骤把方法声明加到类声明中:
(1)切换到Code Editor中,并保证当前编辑文件为SPMain.pas;
(2)在TScratchPad类的声明中找到private段,把下面一行代码加到private关键字后:
procedure MyOnHint(Sender : TObject);
为了方便观察,下面给出了类声明的最后几行,看起来如下:
private { Private declarations } procedure MyOnHint(Sender : TObject); public { Public declarations } end;
很好,现在已经把新方法的说明加到了类声明中。下面还有两项工作要做,先是要把实际的方法加到执行段(implementation);然后把新方法分配给Application对象的OnHint事件。步骤如下:
(1)滚动屏幕到执行段的底部;
(2)输入以下代码(正好在单元结尾end关键字之上):
procedure TMainForm.MyOnHint(Sender: TObject); begin StatusBar.SimpleText := Application.Hint; end;
(3)切换到Object Inspector,从Object Inspector选取ScratchPad的主窗体MainForm;
(4)切换到Object Inspector的Events页面,双击OnCreate事件,此时会显示Code Editor,在Code Editor中输入代码:
procedure TMainForm.FormCreate(Sender: TObject); begin Application.OnHint := MyOnHint; end;
(5)编译并运行程序,当鼠标指着一个工具栏按钮时,长提示文本显示在状态栏上,当鼠标光标停留在一个按钮上时,该按钮的短提示文本会以工具提示的方式显示在按钮旁边。
上面的第(2)步是把Application对象的Hint属性也就是提示文本赋值给StatusBar组件的SimpleText属性。第(5)步把第(2)步创建的方法分配给Application对象的OnHint事件。每当OnHint事件发生时,就调用MyOnHint方法,把提示文本显示在状态栏上。
Note
上面的例子是一个在应用中实现状态栏提示的例子,其过程比较繁琐,目的是讲解如何为窗体加方法及如何为事件分配方法。其实有一个简便的办法来实现状态栏提示,就是把状态栏的AutoHint属性设置为True,并指定每个组件的提示文本,其他工作由Delphi自动完成。
添加类数据字段(Adding a Class Data Field)
往类中添加数据字段,类似于向类中添加方法。只能把数据字段加到类声明的private段和public段,如果在类中创建了protected段,也可以往protected段中添加数据字段。
删除Delphi生成的代码(Deleting Delphi-Generated Code)
有时候需要把应用程序中Delphi生成的一段代码删除。例如,一个窗体上有一个按钮,由于改变了设计,不再需要这个按钮。从Form Designer中选取该按钮,并按键盘上的Delete键,就可以将这个按钮删除,Delphi删除按钮后,与按钮相对应的OnClick处理程序仍留在代码中。
Delphi明知道按钮已经删除,为什么不把与之对应的OnClick处理程序删除呢?因为有可能其他组件也使用这个事件处理程序。我们可以手动将其从代码中删除。
删除事件处理程序是件简单的事情。把事件处理程序中的代码全部删除,然后保存或编译工程,Delphi就会自动删除空的事件处理程序。
Note
有人可能会说,如果不能肯定某个事件处理程序是否被其他组件使用,最好还是将它留在代码中。依作者的卡法,这不是一个好的解决办法。编程人员有责任地对他自己的代码知道的一清二楚,及时删除不用的方法。不用的代码不会有什么大危害,但它会使.exe文件变得更庞大,某些情况下还会降低程序性能。请及时削减程序中不用代码或低效代码。