單元四、Object Pascal 介紹
4.1 Object Pascal程式單元
4.1.1 Object Pascal程式單元的基本架構
打開一個空的表格。
unit Unit1; {程式單元的開始及單元名稱}
interface {interface部分的開始}
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
Type {型態宣告} TForm1 = class(TForm) Private { Private declarations } public { Public declarations } end;
var {變數宣告} Form1: Tform1;
Implementation {實作部分的開始}
{$R *.DFM}
end.
|
- Unit:Object Pascal每一個程式或模組的最基本單位,由一群常數、資料型態、變數、程序及函式所構成。一般包含interface和implementation兩部份。
- Interface:程式單元對外的介面,他用來定義可以被其他程式單元所看見和使用的元素。
- Implementation:實際的做出interface所宣告的程式元素。
4.1.2 變數宣告
Var Form1:TForm1; ICounter:Interger; SName:String; |
- 步驟:先為變數命名,然後指定變數的型態。
- 變數命名原則
-
- 好記且有意義。
- 識別字最多63個字元。
- 識別字必須以字母或_開始,其後的字元是字母、底線、或是數字。
- 識別字不可以是保留字或Delphi已經定義的識別字。
- Object Pascal內建的資料型態
類別 | 資料型態 | 說明 |
整數 | Integer | 2 bytes,-32768到32767 |
Shortint | 1 byte,-128到127 | |
Longint | 4 bytes | |
Byte | 1 byte,0到255 | |
Word | 2 byte,0到65535 | |
實數 | Single | 7到8位有效數字,需4 bytes |
Double | 15到16位有效數字,需8 bytes | |
Extended | 19到20位有效數字,需10 bytes | |
Comp | 19到20位有效數字,需8 bytes | |
Real | 11到12位有效數字,需6 bytes | |
布林 | Boolean | True or False,需1 bit |
字元 | Char | ASCII字元 |
字串 | String | 最長255個ASCII字元 |
指標 | Pointer | 未定型的指標 |
字串指標 | Pchar | 指向字串的指標 |
4.1.3 型態宣告
-
- 使用者自訂的型態要先宣告。
- 以保留字type為開始。
- 型態只是資料型態的長相,不是真正的變數。
4.1.4 uses子句
-
- 類似C/C++中的Include。
- 具有延伸作用。
4.2 程式單元的內涵
實作一個表格,並研究其產生的程式碼。
-
- 加入ListBox元件,並適當的調整其大小。
- 加入兩個Button元件,如上圖。把Button1的Caption訂為『列出資料』,Button2的Caption訂為『清除資料』。
- 加入Data Access中的Table元件,DatabaseName特性設為『DBDEMOS』,TableName特性設為『ANIMALS.DBF』,Active = True,IndexFieldNames設為Name。
- 加入Data Access中的DataSource元件,DataSet = Table1。
- 儲存表格為MainForm,按F12,切換到程式編輯器。
unit MainForm;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, DB, DBTables, StdCtrls;
type TForm1 = class(TForm) ListBox1: TListBox; Button1: TButton; Button2: TButton; Table1: TTable; DataSource1: TDataSource; private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
…
end. |
- Delphi加入元件時會自動把元件的宣告加到表格的型態宣告之中,同時會把其所在的程式單元加到uses子句中。
- 這種自動維護程式碼的功能有助於我們快速的發展程式。但要切記,如果指更動程式編輯器(增減一個元件),Delphi的表格並不會跟著更動,而且往往會造成錯誤。
-
- 雙擊『清除資料』按鈕,Delphi會在程式編輯器產生Button2Click是件處理程序。
Unit1的interface部份出現
type TForm1 = class(TForm) … procedure Button2Click(Sender: TObject); private … |
Unit1的implementation部份出現
implementation
{$R *.DFM}
procedure TForm1.Button2Click(Sender: TObject); begin end; |
-
- 在implementation部份,我們可以呼叫Clear方法來清除ListBox中的內容。
procedure TForm1.Button2Click(Sender: TObject); begin ListBox1.Clear; end; |
4.3 流程控制
4.3.1 跳離敘述
- if 敘述
If ThisYearIs = ‘1995’ then MessageBeep(1) Else MessageDlg(‘ThisYearIs不是1995’, mtInformation, [mbOK], 0); |
-
- 巢狀if 敘述
else會自動與最靠近的if配對。
If ThisYearIs = ‘1995’ then If ThisMonthIs = ‘8’ then MessageBeep(1) Else MessageDlg(‘ThisYearIs不是1995’, mtInformation, [mbOK], 0); |
則當1995年且不是8月時顯示『ThisYearIs不是1995』
If ThisYearIs = ‘1995’ then Begin If ThisMonthIs = ‘8’ then MessageBeep(1) End Else MessageDlg(‘ThisYearIs不是1995’, mtInformation, [mbOK], 0); |
則當不是1995年時顯示『ThisYearIs不是1995』
- case 敘述
Case StrToInt(thisMonthIs) of 1, 3, 5 , 7, 9, 11: MessageDlg(‘ThisMonthIs是奇數月’, mtInformation, [mbOk], 0); 2, 4, 6, 8, 10, 12: MessageDlg(‘ThisMonthIs是偶數月’ mtInformation, [mbOk], 0); Else MessageDlg(‘ThisMonthIs有錯誤’, mtInformation, [mbOk], 0); End; |
4.3.2 迴圈敘述
- Repeat敘述
I:=1; Repeat … Writeln(I); Until I = 10; |
- While敘述
I:=1; While I<= 1 do Begin I:=I+1; Writeln(I); end; |
- For敘述
for I:= 1 to 10 do Writeln(I); |
-
- 巢狀For迴圈
for I:= 1 to 10 do for J:= 1 to 5 do Writeln(I*J); |
4.3.3 完成範例程式
- 雙擊列出資料按鈕,完成下面程式。
procedure TForm1.Button1Click(Sender: TObject); begin Table1.First; While not Table1.EOF do Begin ListBox1.Items.Add(Table1.FieldByname('NAME').Text); Table1.Next; End; end; |
- 執行。
4.4 加入第二個表格(the second form)
-
- 選File|New Form以建立新表格。
- 在表格中加入四個Label元件,分別將其名稱訂為『名稱』、『大小』、『重量』、『區域』。
- 加入四個DBText元件作為顯示資料的欄位。
- 加入一個DBImage以便顯示圖像。
此時的程式編輯器的內容如下:
unit SndForm;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, DBCtrls, DB, DBTables, StdCtrls;
Type TForm2 = class(TForm) Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; DBImage1: TDBImage; DBText1: TDBText; DBText2: TDBText; DBText3: TDBText; DBText4: TDBText; private public end;
var Form2: TForm2;
Implementation
{$R *.DFM} end. |
-
- 選第一個表格中的ListBox1,雙擊OnDbkClick事件,填入下面的事件處理程序。
procedure TForm1.ListBox1DblClick(Sender: TObject); begin Form2.ShowModal; end; |
-
- 在MainForm的implementation中加入對SndForm使用的宣告。
implementation
uses SndForm;
{$R *.DFM} |
-
- 執行程式,按列出資料按鈕後,在雙擊ListBox中有資料的地方。
4.5 程序和函式
4.5.1 表頭部份
procedure由保留字procedure開始,參數放於刮號內。
Procedure setDBName(Name1: string; Name2:string; Name3:string); |
或
Procedure setDBName(Name1, Name2, Name3:string); |
function由保留字function開始,參數放於刮號內,後面加型態宣告。
function getDBName(Name1, Name2, Name3:string):string; |
4.5.2 程式區塊
-
- 包含宣告部份與敘述部份。
- 宣告部份告訴編譯器有哪些項目要被使用。他包含型態宣告(以保留字type開始)、變數宣告(以var開始)、常數宣告(以const開始)。
Type TCount = Integer; TPrimaryColor = (Red, Yellow, Blue); TTestIndex = 1..100; TTextValue = -99..99; TTestList = array[TTestIndex] of TTestValue; TCharVal = Ord(‘A’)..Ord(‘Z’); TDays = (Modday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
|
-
- 敘述部份說出可以執行的邏輯行動,他由begin開始,由end結束。
- 每個程式方塊的宣告以該程式方塊為有效範圍。
4.5.3 函式值的回傳
- 函式值回傳的方法有兩種。
-
- 把回傳的值指定給函式名稱。
Function GetRecordNumber: Integer;
Begin
GetRecordNumber:=Table.RecordCount;
End;
- 把回傳的值指定給Result變數(此變數不需宣告即可使用)。
- 把回傳的值指定給函式名稱。
Function GetRecordNumber: Integer; Begin Result:=Table.RecordCount; End; |
4.5.4 在程式中加入程序或函式
- 如何讓程序或函式被其他程式使用
-
- 程序或函式把的表頭部份放在程式單元的interface部份。
- 把宣告這個程序或函式的程式單元的名稱放在存取這個程序或函式的程式單元的uses子句中。
- 程序或函式的宣告
程序或函式必須在所有使用他的程式之前宣告。
- 前置宣告
使用前置宣告的程序或函式可以把其implementation部份放在程式的任何一個地方。他可以用來產生相互遞迴的功能,即在A函式中有B函式,同時B函式中也有A函式。
Function GetRecordNumber:Integer; forward; |
4.5.5 傳遞參數
-
- 數值參數:參數以傳值(call by value)的方式傳遞,副程式不會改變原程式中參數的值。
procedure SetformData(aTblName:string); |
-
- 變數參數:參數以傳址(call by address)的方式傳遞,參數所傳的是實際變數的指標,副程式會改變原程式中參數的值。
Procedure GetTableName(var aTblName:string); |
-
- 常數參數:形式參數的值不被改變。指定的方式是在參數前加一個const保留字。
procedure SetformData(const aTblName:string); |
5.6 完成範例程式
-
- 選第一個表格中的ListBox1,雙擊OnDbkClick事件,填入下面的事件處理程序。
procedure TForm1.ListBox1DblClick(Sender: TObject); var aStr: string; begin aStr := ListBox1.Items[ListBox1.ItemIndex]; Form2.SetClickedData(DataSource1, Table1, aStr); Form2.ShowModal; end; |
-
- 在SndForm的uses子句中加上DB和DBTables兩單元的使用宣告。
unit SndForm;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, DBCtrls, DB, DBTables, StdCtrls; |
-
- 在TForm2的類別宣告的private和public部份加上:
private aDataSource: TDataSource; aTable: TTable; aNameStr: string; public procedure SetClickedData(aSource: TDataSource; aTbl: TTable; const aName: string); end; |
-
- 在implementation的部份加上SetClickedData的實作。
procedure TForm2.SetClickedData(aSource: TDataSource; aTbl: TTable; const aName: string); begin aDataSource := aSource; aTable := aTbl; aNameStr := aName; end; |
-
- 在Form2的OnActivate事件中,加入下面程序:
procedure TForm2.FormActivate(Sender: TObject); begin DBText1.DataSource := aDataSource; DBText2.DataSource := aDataSource; DBText3.DataSource := aDataSource; DBText4.DataSource := aDataSource; DBImage1.DataSource := aDataSource; if aTable.FindKey([aNameStr]) then begin DBText1.DataField := 'NAME'; DBText2.DataField := 'SIZE'; DBText3.DataField := 'WEIGHT'; DBText4.DataField := 'AREA'; DBImage1.DataField := 'BMP'; end; end; |
- 執行。