向代碼中增加方法和數據字段(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文件變得更龐大,某些情況下還會降低程序性能。請及時削減程序中不用代碼或低效代碼。