delphi

delphi

快速應用程序開發工具
Delphi,是Windows平台下著名的快速應用程序開發工具(Rapid Application Development,簡稱RAD)。它的前身,即是DOS時代盛行一時的“BorlandTurbo Pascal”,最早的版本由美國Borland(寶蘭)公司于1995年開發。主創者為Anders Hejlsberg。經過數年的發展,此産品也轉移至Embarcadero公司旗下。Delphi是一個集成開發環境(IDE),使用的核心是由傳統Pascal語言發展而來的Object Pascal,以圖形用戶界面為開發環境,透過IDE、VCL工具與編譯器,配合連結數據庫的功能,構成一個以面向對象程序設計為中心的應用程序開發工具。[1]
    中文名: 外文名: 别名: 英文名:Delphi 發布單位:美國Borland(寶蘭)公司 發布時間:1995年 類别:編程語言 作者:安德斯·海爾斯伯格

安裝方法

Delphi的安裝與其它應用軟件并無不同。2.0版必須在Windows 95以上的操作系統中使用。啟動Windows 95或Windows NT後,将Delphi的光盤放入光驅(CD-ROM)中,運行光盤上的INSTALLSETUP.EXE文件,它的安裝程序會提示您正确地裝入Delphi。如果您是在微軟中文Windows環境中安裝Delphi,請參照附錄A來設置您的BDE環境,以便于處理中文數據。

為避免隐藏在Delphi後的Program Manager和曾經運行過的其它程序擾亂版面,分散您的注意力,不妨在啟動Delphi前關掉其它應用程序;啟動Delphi後,再最小化隐藏在後面的Delphi 2.0程序組。這樣屏幕上就隻留下Delphi窗口可見了。

首次加載Delphi,屏幕上會出現四個窗口:

(1)标題為“Delphi-Project1”的Delphi主窗口

(2)Object Inspector窗口

(3)标題為“Form1”的窗體(Form)窗口

(4)标題為“Unit1.PAS”的代碼編輯窗口。

剛啟動時這一窗口的大部分被“Form1”窗體所掩蓋。将“Form1”窗體移開,或單擊Form1窗體下方的狀态行,可以使其全部可見。在“Form1”窗體的任意可見位置單擊鼠标,可以恢複主窗體可見。

Delphi的主窗口位于屏幕的上端,包括Menu(菜單)、Speed Bar(加速條)和Component Panel(部件選項闆)。Menu是下拉式主菜單。Speed Bar位于主窗口的左下端,由兩排共14個加速按鈕組成。這些按鈕是菜單功能的快捷方式,各種圖标直觀地表示了它能執行的動作。Component Panel由一行、若幹頁對象按鈕所組成,利用它來選擇需要的部件并将它放到窗體中去。

Object Inspector窗口含有兩頁:Properties頁顯示窗體中當前被選擇部件的屬性信息,并允許改變對象的屬性;Events頁列出了當前部件可以響應的事件。按動Object Inspector下端的“Events”頁标簽,使得Events頁可見,這一定的事件後邊的空白處,可以定義對象接受到相應事件時執行的動作。首次啟動時,Object Inspector窗口顯示的是當前窗體Form1的屬性。Object Inspector根據對象屬性的多少,決定是否有滾行顯示。移動滾行條,可以查看當前對象的全部屬性。

此外,Object Inspector上還有Object Selector(對象選擇器),位于Object Inspector上方的下拉式菜單中。它顯示了窗體上所有部件的名稱和類型,也包含窗體本身。您可以用Object Selector很容易地在窗體的各個部件之間切換,也可以快速地回到窗體本身。當窗體中含有較多的對象時,您會發現這是切換對象尤其是回到窗體的最快捷途徑。

想使Object Inspector一直可見,可将鼠标移到Object Inspector上,按動右鍵,以啟動Object Inspector的彈出式菜單,将其設置為Stay On Top。這對初學者常是一個很重要的設置方式。

鎖定部件

如果部件已經對齊,為防止不小心移動部件,可以将部件位置鎖定。選擇主菜單上的Edit|Lock Controls選項,使得部件不能進行移動操作。解鎖隻需再次選擇此項即可。

調整“Shape”部件的大小,使之與右邊的按鈕組相匹配。再改變窗體的大小,按住并拖動窗體右下方使之剛好包容窗體上的全部部件。這樣,您的用戶界面就會比較美觀。及時地保存所做的工作至關重要。對設計者來講,有兩個文件需要保存:庫單元文件(以.PAS為後綴)和工程文件(以.dpr為後綴)。從主菜單上選擇File|Save Project As...項,Delphi會顯示标題為“Save Unit1 As”的文件保存對話框,Delphi 2.0 允許用戶更改存儲路徑,您可以在下拉式列表框中選擇。

最好将您的文件保存在自己的目錄中。在編輯框中鍵入demoform.pas以保存庫單元文件;然後顯示标題為“Save Project As”的另一個文件保存對話框,鍵入sample.dpr。Delphi保存這兩個文件并返回窗體窗口。不要把庫單元和工程存成一樣的文件名,Delphi要求兩者不同。

第一次保存後,以後可以随時通過Speed Bar中的“Save All”和“Save file”來保存工程文件和庫單元文件。一般來講,當确認文件的改變後,要同時存儲這兩個文件。

運行工程:操作使您有了一個自己的應用程序界面。在速度條中按動“Run”按鈕(繪有綠色三角圖标),您可以看到,所生成的界面與您設計的界面是完全一緻的。

改變對象的屬性:上述的工程雖能夠運行,但它對您的按動按鈕操作是沒有什麼反應的,而且,所有部件上還寫着不需要的字樣。雙擊窗口的關閉按鈕結束運行,回到設計界面。下面,将仔細講述如何在Object Inspector中改變部件的各種屬性。

用Properties頁改變部件的屬性值:首先要改變各種部件的标題。先給窗口命名為“Demo”。按動Object Inspector上端的Object Selector的題條或者其右端的下拉标志,找到Form1項,并點動左鍵,窗體被選中。在Object Inspector的Properties頁中,找到Caption屬性并用左鍵選中,将其右端的Form1改為Demo,同時,您會發現窗體的标題已經相應地做了改變。

用鼠标點中窗體中的Shape部件,Object Inspector列出了它的屬性。選中Shape屬性,您會發現右端出現了下拉标志。點動這一标志,可以查看對象的Shape屬性可選值。它的形狀可以是矩形、圓形、圓角矩形、方形等幾種。這是設計後續功能的基礎。

選中Button1按鈕,此時Object Inspector已經顯示出此按鈕的一應屬性。将它的Caption屬性改為“ℜctangle”,“&”号使得Delphi特殊處理它後面的字符,在這裡,按鈕中的R字母被做了下劃線處理,運行時,可以用“Alt-R”熱鍵來按動這一按鈕。同樣,您可以将其它的兩個按鈕Button2和Button3的Caption屬性改成需要的形狀指示,譬如“&RoundRec”、“&Ellipse”。

可以把某個按鈕作為窗口上的缺省按鈕,Delphi會為按鈕加上有黑色的邊緣。運行時,回車即相當于被按下。隻需将此按鈕的Default屬性從False改成True,即将它設為窗體的缺省按鈕。點動Default屬性,在右端的值後面雙擊左鍵,或從下拉菜單中選取True,即可改變這一屬性。Delphi中有許多隻有True、False兩個屬性的部件,雙擊左鍵可以在這兩個值之間切換。

漢化界面及字體選取

如果您的Windows95系統中安裝了中文系統,對界面做漢化是極其方便的。例如,您可以将Button1的Caption屬性改成“&R矩形”,同樣地可改變其它部件的屬性,将窗體做成中文的操作界面。

若對中、西文字體不滿意,則可以調整Font屬性以滿足您的要求。Font屬性的前面,有一個小小的“+”号,這說明它表征的是集屬性,也即屬性不再是一個單值,而是一個屬性的集合。雙擊Font,ObjectInspector将在下面擴充顯示它的其它屬性。Color用來表示文本的顔色,Name定義了字體名,如System,MsSerif,Arial,宋體,黑體等。Style下又擁有四個屬性:fsBold,fsItalic,fsUnderline和fsTrikeOut。如果想讓字體有其中的某種風格,可把相應的屬性值設成True。

Font對話框可以更為直接地設定以上屬性。Font屬性右側值段有帶省略号的按鈕,單擊它可以激活Font對話框,如圖1.7所示:

這一對話框中包含了上述的全部屬性,使得調整字形更為直接方便。但要申明的是,對于窗體Form來講,Font屬性改變的是窗體中其它部件的顯示字形,它本身的标題字體是缺省的System字體,不能通過屬性來改變。

使用圖形編輯對話框

最後,用圖标按鈕BitBtn1來控制Shape部件的顔色。選中圖标按鈕,将它的Caption屬性改為“&Color”(或“&C顔色”)。可以在按鈕中加入一個圖标來形象地表述它的功能。選用ObjectInspector中的Glyph屬性,點動值段的三點按鈕,彈出圖形編輯對話框。

您可以通過圖形編輯對話框裝入圖标,在本例程中,按動Load按鈕,選擇Delphi2.0ImagesButtonsBrush.bmp文件裝入,Bitbtn1就成為一個圖标按鈕。另外,Delphi還為您提供了豐富的Windows标準圖标按鈕。想運用它們,改變BitBtn的Kind屬性。用戶不妨嘗試一下,選擇其它值可以生成漂亮的标準按鈕,如OK,Cancel等等。這會使您在以後的程序開發中受益匪淺。

至此,界面的設計工作就已完成了。運行一下觀察效果,别忘記保存您的庫單元文件、工程文件。

編寫事件處理過程

完成用戶界面,隻是建立了一個“骨架”,下面要做的便是給程序加入“靈魂”,也即,使它能夠完成所要求的功能。

為用戶操作建立“事件”

單擊窗體上的“Rectangle”按鈕,在ObjectInspector中,點動“Events”頁标簽,出現事件窗口。在本例程中,隻關心OnClick事件,即按鈕接收到左鍵單擊時應用程序所作出的反應。在ObjectInspector窗口中雙擊OnClick事件右端的值段,會使得Delphi激活庫代碼編輯器,并将光标停在該按鈕所對應的過程的begin...end之間。“Rectangle”按鈕的功能是使Shape部件的形狀為矩形。聯系前文查看過的Shape部件的“Shape”屬性,現在,要做的是在程序中控制部件的屬性。

在光标處鍵入以下的程序段:

Shape1.Shape:=stRectangle;

用同樣的方法,在Button2和Button3的OnClick事件響應内複制以上語句,并分别将賦值号後的屬性值改為stRoundRect和stEllipse。為防止輸入錯誤導緻程序運行出錯,建議您使Shape1部件的ObjectInspector可見,檢視屬性Shape的各個值并對應輸入。

在代碼編輯器中,Delphi自動建立的過程以關鍵字Procedure開頭,用戶可以在begin…end之間加入自己的程序,也可以定義變量。這個程序塊對用戶的外部事件(此例中是按動按鈕)進行響應。稱之為事件處理過程。

使用顔色編輯對話框

圖标按鈕“Color”要控制部件Shape1的顔色,可以調入顔色編輯對話框,用以選擇要變成的顔色。這時就要用到運行時不可視的部件ColorDialog了。同樣地使圖标按鈕BitBtn1響應OnClick事件,在它的過程中加入以下的語句:

ColorDialog1.Execute;

Shape1.Brush.Color:=ColorDialog1.Color;

這樣,圖标按鈕的功能也就完成了。

初學者可能對這樣的程序段不能理解。其實也是十分簡單的。查看ColorDialog的Brush屬性,就會發現它是個集屬性,在其下還有一個Color選項,正是想改變的屬性。既然想将圖形的顔色變得更加豐富多彩,它本身提供的幾種顔色就已不能滿足要求了。用顔色編輯器可以得到更多的色彩。程序的第一句用Execute方法,使得ColorDialog運行它本身。當用戶在對話框中進行操作,選定了一種顔色時,即使得TColorDialog對象的一個屬性Color置為選定顔色的值。将此值賦給Shape1的Brush屬性的子屬性Color,就将選定的顔色加到了圖形上。

讀者的要求可能會是,怎樣盡快的了解這些這些方法、屬性和域呢?下文對使用聯機幫助的簡單介紹可能會對您有所裨益。

使用聯機幫助Help

事實上,使用聯機幫助是您全面地了解可用的方法、對象的域、?的例程。較為簡單有效的方法是使用Help中的搜索功能。如果您對一個對象知之甚少,選用主菜單中的Help|HelpTopics項,在彈出的幫助對話框,選用Indexes(“索引”)頁,Delphi2.0會提示您輸入要檢索的主題。以您想用的部件的對象名作為檢索主題詞,可以參閱很多基本的信息。

例如,上文的例程中,在編輯框中鍵入對象的名稱TColorDialog,在詞條中就會出現該主題,按動Display按鈕顯示出TColorDialog的幫助信息。查看method,可以找到能應用在CclorDialog1上的方法Execute;仔細閱讀它的功能,上述的編程便不難理解了。Properties中提供了部件的所有屬性,在關鍵屬性KeyProperties前加上了“金鑰匙”,提供了詳盡的說明。在Task中您可以查閱該對象的其它相關主題,還可以參閱Example中的應用例程。

編程方法

Delphi的編程語言是以Pascal為基礎的。Pascal語言具有可讀性好、編寫容易的特點,這使得它很适合作為基礎的開發語言。同時,使用編譯器創建的應用程序隻生成單個可執行文件(.EXE),正是這種結合,使得Pascal成為Delphi這種先進開發環境的編程語言。

本章中,将讨論ObjectPascal的主要特點,并講解如何在事件處理過程和其他應用程序中,使用它來編制程序代碼。本章将講解Delphi應用程序中最常用的ObjectPascal語法,而不是Pascal語言的一切細節。如果您完全不熟悉Pascal編程,請參閱一些基礎的Pascal教程。如果您具有編程經驗,并能熟練地使用其他流行程序語言,您将在本章的ObjectPascal中發現一些相同的概念。如果您已經熟悉了BorlandPascal,就可以快速浏覽或跳過本章。

編寫ObjectPascal程序代碼

在前邊的章節中,通過例程,已經編寫了幾行簡單的代碼。在本章中,将從熟悉Pascal編程的角度,配合實例,講解ObjectPascal編程的基該方法。

在編寫自己的ObjectPascal程序時,要注意程序的可讀性。Pascal語言是英式結構語言,在程序中選擇合适的縮排、大小寫風格,并在需要時将程序代碼分行,會使得程序代碼能夠很容易地被自己和他人讀懂。一般的程序員都有這樣的體驗:如果不給程序加上适當的注解,一段時間後,自己也難以理清程序的流程。給程序及時地加上注釋是良好的編程習慣。Delphi的注釋需要加注在{}之間,編輯器會把它們處理成為空白。Delphi保留了BorlandPascal編輯器的風格,關鍵字采用黑體字,被注釋的部分會變暗,這使得編程風格良好,易讀易寫。

賦值

在事件處理過程中,最常用到的工作就是把一個新值賦給一個屬性或變量。在設計用戶界面時,可以使用ObjectInspector(ObjectInspector)來改變其屬性;但有時需要在程序執行時改變屬性的值,而且有些屬性隻能在執行時改變,這些屬性在Delphi的在線幫助的“Proprety”主題中被标為執行期屬性。進行這種改變,就必須使用賦值語句。

下文的賦值語句表征一個OnClick事件。當按鈕按動後,将編輯框部件Edit1的Color屬性置為clRed:

procedureTForm1.Button1Click(Sender:TObject);

begin

Edit1.Color:=clRed;

end;

當按動按鈕後賦值語句被執行,編輯框變成紅色。

在語句中,部件的名稱在屬性前,中間用“.”表示屬性的所屬關系。這樣就準确地指定了要将clRed值賦給哪一部件的哪一屬性。賦值号為“:=”,不論給屬性還是給變量賦值,都是将右邊的值賦給左邊的屬性或變量。

當将一個屬性值、變量、常量或文本數據賦給屬性或變量時,所賦值的類型和接受此值的屬性或變量的類型應相同或兼容。一個屬性或變量的類型定義了此屬性或變量的可能值集合,也定義了程序代碼可以執行的運算。在前邊的例程中,編輯框部件的Color屬性和clRed的類型都是TColor。可以在在線幫助中找到一個屬性的類型;另外一種方法是在ObjectInspector中選定該屬性值段,并按下F1鍵,則類型将在屬性說明的結尾處列出,例如Color屬性列出下邊的語句:

PropertyColor:TColor;

有些屬性是隻讀(ReadOnly)的,它們隻能被讀取,不能被改變。請查閱在線幫助,在Delphi中這些隻讀屬性都有注解。

标識符的說明與使用

标識符是Delphi應用程序中一些量的名稱,這些量包括變量(var)、常量(const)、類型(type)、過程(procedure)、方法(Method)及其他,ObjectPascal在應用标識符時,必須首先說明它們。ObjectPascal是強類型語言,它的編譯器可以檢查确保賦給變量或屬性的值是正确的類型,以便于您改正錯誤。因為ObjectPascal是編譯語言,所以Delphi的執行速度要比使用解釋語言快得多。在使用标識符前說明它們,可以減少程序錯誤并增加代碼的效率。

變量

變量是程序代碼中代表一個内存地址的标識符,而此地址的内存内容在程序代碼執行時可以被改變。在使用變量前必須對它進行說明,即對它進行命名,并說明它的類型。在所有變量說明以前加上保留字var。變量說明左邊是變量的名稱,右邊則是該變量的類型,中間用(:)隔開。

var

Value,Sum:Integer;

Line:String;

在窗體中加入一個名稱為Edit1的編輯框,再加入一個名稱(屬性Name)為Add的按鈕部件,并建立如下的事件處理過程:

procedureTForm1.addClick(Sender:TObject);

var

X,Y:Integer;

begin

X:=100;

Y:=20;

Edit1.Text:=IntToStr(X+Y);

end;

在本例中,當按動ADD按鈕時,編輯框中顯示值120。在ObjectPascal中,必須确保變量或屬性被賦予類型相同或兼容的值。您可以嘗試将賦給X的值改為100.0,或去掉IntToStr函數,在編譯時會出現類型不匹配的錯誤,這也說明了ObjectPascal強類型語言的特點。

條件

case語句适用于被判斷的變量或屬性是整形、字符型、枚舉型或子界型時(LongInt除外)。用case語句進行邏輯跳轉比編寫複雜的if語句容易閱讀,而且程序代碼整形較快。

下面的例程顯示一個使用case語句的窗體:

建立如下的事件處理過程:

procedureTForm1.Button1Click(Sender:TObject);

var

Number:Integer;

begin

Number:=StrToInt(Edit1.Text);

caseNumberof

1,3,5,7,9:Label2.Caption:='奇數';

0,2,4,6,8:Label2.Caption:='偶數';

10..100:

begin

Label2.Caption:='在10到100之間';

Form1.Color:=clBlue;

end;

else

Label2.Caption:='大于100或為負數';

end;

end;

執行程序,當Edit1部件接受到一個值,并按動“OK”按鈕觸發程序後,Number便被賦值為用戶輸入的數值。case語句根據Number的值判斷該執行哪一條語句。象if語句一樣。case語句也有可選擇的else部分。case語句以end結尾。

循環

ObjectPascal的循環語句有三種:repeat、while和for語句。

repeat語句

repeat語句會重複執行一行或一段語句直到某一狀态為真。語句以repeat開始,以until結束,其後跟随被判斷的布爾表達式。參閱以下的例程:

i:=0;

repeat

i:=i+1;

Writeln(i);

until=10;

當此語句被執行時,窗體的下方會出現1到10的數字。布爾表達式i=10(注意,與其他語言不同的是,“=”是關系運算符,而不能進行賦值操作)直到repeat..until程序段的結尾才會被計算,這意味着repeat語句至少會被執行一次。

不同

while語句和repeat語句的不同之處是,它的布爾表達式在循環的開頭進行判斷。while保留字後面必須跟一個布爾表達式。如果該表達式的結果為真,循環被執行,否則會退出循環,執行while語句後面的程序。

下面的例程達到和上面的repeat例程達到同樣的效果:

i:=0;

whilei0then

test2(A);{經前置說明,調用未執行的過程Test2}

writeln(A);

end;

procedureTest2(varA:Integer);{經前置說明的Test2的執行部分}

begin

A:=Adiv2;

ifA>0rhen

test1(A);{在Test2中調用已執行的過程Test1}

end;

procedureTForm1.Button1Click(Sender:TObject);

begin

Alpha:=15;{給Alpha賦初值}

Test1(Alpha);{第一次調用Test1,遞歸開始}

end;

按鈕的OnClick事件處理過程給Alpha賦初值,并實現先減1再除2的循環遞歸調用,直到Alpha小于0為止。

函數

過程

過程與函數是程序中執行特定工作的模塊化部分。Delphi的運行庫包含許多過程與函數以供您的應用程序調用。您不必了解過程與函數的邏輯,但要知道過程與函數的用途。在對象中說明的過程和函數稱為方法(Method)。所有的事件處理過程都是過程,以保留字procedure開頭。每一個事件處理過程隻包含了當這一事件發生時需要執行的程序代碼。在事件處理過程中使用Delphi已經存在的過程與函數,隻需在程序代碼中調用它們即可。

使用

與過程一樣,函數的程序代碼也執行特定的工作。它和過程的差别為:函數執行時會返回一個值,而過程則沒有返回值。函數可以用來賦給一個屬性或變量;也可以使用返回值來決定程序的流程。前文中實際上已經接觸過了函數。在講述變量時,曾用到過下面的程序段:Edit1.Text:=IntToStr(X+Y);其中,IntToStr(Value)把一個LongInt類型的數值轉化為字符串的值,Value是IntToStr唯一的參數,它可以是一個整形的值、變量、屬性或産生整形值的表達式。調用函數,必須把返回值賦給和此返回值類型兼容的變量或屬性。

有些函數返回一個True或False的布爾量,用戶的程序可以根據返回值來決定跳轉。下文的例程講述了函數返回值為Boolean的判斷用法:

在窗體中加入一個ColorDialog對象和一個Name屬性為ChangeColor的按鈕。為按鈕的OnClick事件建立事件處理過程如下:

procedureTForm1.ChangeColorClick(Sender:TObject);

begin

if ColorDialog1.Execute then

Form1.Color:=ColorDialog1.Color

else

Form1.Color:=clRed;

end;

此事件處理過程使用一個返回Boolean值的Execute方法。按動按鈕,并在顔色對話框中選擇一個顔色。如果按動OK按鈕,ColorDialog.Execute方法将返回True,則Form1.Color将被賦值為ColorDialog1.Color,窗體顯現您選用的顔色;如果按動顔色對話框的Cancel按鈕,方法将返回False值,窗體将變為紅色。

跳轉語句

ObjectPascal的跳轉語句有if和case兩個。

if語句

if語句會計算一個表達式,并根據計算結果決定程序流程。在上文的例程中,根據ColorDialog.Execute的返回值,決定窗體的背景顔色。if保留字後跟随一個生成Boolean值True或False的表達式。一般用“=”作為關系運算符,比較産生一個布爾型值。當表達式為True時,執行then後的語句。否則執行else後的代碼,if語句也可以不含else部分,表達式為False時自動跳到下一行程序。

if語句可以嵌套,當使用複合語句表達時,複合語句前後需加上begin…end。else保留字前不能加“;”,而且,編譯器會将else語句視為屬于最靠近的if語句。必要時,須使用begin…end保留字來強迫else部分屬于某一級的if語句。

程序

程序代碼在調用一個過程或函數時,通常用參數傳遞數據到被調用的過程或函數中。最常用的參數有數值參數、變量參數和常量參數三種。由被調用過程或函數定義的參數為形參,而由調用過程或函數指明的參數叫實參。在NoValue函數中,說明函數體中的AnEditBox是形參,而調用時在ifNoValue(Edit1)…中,Edit1是實參。

數值參數在運行過程中隻改變其形參的值,不改變其實參的值,即參數的值不能傳遞到過程的外面。試看下面的例程:

procedureCalculate(CalNo:Integer);

begin

CalNo:=CalNo*10;

end;

用以下例程調用Calculate函數:

Number:=StrToInt(Edit1.Text);

Calculate(Number);

Edit2.Text:=IntToStr(Number);

Number接受由編輯框1輸入的數值,經Calculate過程運算。它是一個數值型實參。在進入Calculate函數後,會把Number實參拷貝給形參CalNo,在過程中CalNo增大十倍,但并未傳遞出來,因此Number值并未改變,在編輯框2中顯示仍然是編輯框1中的輸入值。形參和實參占用不同的内存地址,在過程或函數被調用時,将實參的值複制到形參占用的内存中。因此出了過程或函數後,形參和實參的數值是不同的,但實參的值并不發生變化。

如果您想改變傳入的參數值,就需要使用變量參數,即在被調用程序的參數表中的形參前加上保留字var。例如:procedureCalculate(varCalNo:Integer);

則CalNo并不在内存中占據一個位置,而是指向實參Number。當一個變參被傳遞時,任何對形參所作的改變會反映到實參中。這是因為兩個參數指向同一個地址。将上一個例程中過程頭的形參CalNo前面加上var,再以同樣的程序調用它,則在第二個編輯框中會顯示計算的結果,把第一個編輯框中的數值放大十倍。這時形參CalNo和實參Number的值都是Nnmber初始值的10倍。

如果當過程或函數執行是要求不改變形參的值,最保險的辦法是使用常量參數。在參數表的參數名稱前加上保留字const可以使一個形參成為常量參數。使用常量參數代替數值參數可以保護您的參數,使您在不想改變參數值時不會意外地将新的值賦給這個參數。

物件類型

枚舉類型

一個枚舉型的說明列出了所有這種類型可以包括的值:type

Tdays=(Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday);

可以定義上述枚舉類型的變量:

var

DayOfWeek:TDays;

在枚舉型中,括号中的每一個值都有一個由說明它的位置決定的整形值。例如Sunday有整形值0,Monday有整形值1等。您可以把DayOfWeek說明為一個整形變量,并将一星期的每一天賦一個整形值以達到相同的效果,但用枚舉型會使得程序可讀性好,編寫容易。當您在枚舉型中列出值時,您同時說明了這個值是一個标識符。例如您的程序中如果已經含有TDays類型且說明了DayOfWeeks變量,則程序中便不能使用Monday變量,因為它已經被說明為标識符了。

子界類型

子界型是下列這些類型中某範圍内的值:整形、布爾量、字符型或枚舉型。在您想限制一個變量的取值範圍時,子界型是非常有用的。

type

Thours=0..23;

TValidLetter='A'..'F';

TDays=(Sunday,Monday,Tuesday,Wednesday,Thursday,

Friday,Saturday);{枚舉型}

TWorkDay=Monday..Friday;{一個TDays型的子界}

子界型限定了變量的可能取值範圍。當範圍檢查打開時,(在庫單元的Implementation後面有{$R*.DFM}字樣表示範圍檢查打開,否則您可以在Options|Project|ComplierOptions中選擇RangeCheking來打開範圍檢查),如果變量取到子界以外的值,會出現一個範圍檢查錯誤。

數組類型

數組是某種數據類型的有序組合,其中每一個元素的值由其相對位置來指定,您可以在數組的某個位置上放置數據,并在需要時使用這些數據。下面的類型說明了一個Double型的數組變量:

var

Check:array[1..10]ofDouble;

它表示Check指向一個含有10個Double型元素的數據串列,代表每一個元素的是1到10之間的數字,稱為索引。數組的每一項由數組名稱加上[]中的索引來表示。Check包含10個變量,Check表示第一個變量。您也可以把數組定義成類型:

type

TCheck=array[1..10]ofDouble;

則變量說明改為:

var

Check:TCheck;

您可以通過給數組賦值等方法來使用數組。下面的語句将0.0賦給Check數組中的所有元素:

forJ:=1to10do

Check[J]:=0.0;,

數組也可以是多維的,下面的類型定義了一個20行、20列的數組。

type

Ttable=array[1..20,1..20]ofDouble;

var

table1:TTable;

,;,;想将這一表格的所有數據初始化為0.0,您可以使用for循環:

var

Col,Row:Integer;

forCol:=1to20do

forRow:=1to20do

Table1[Col,Row]:=0.0;

字符串類型

字符串類型事實上是一個一維的字符數組。當您說明一個字符串型的變量時,您應當指明這個字符串的大小,下面是說明字符串類型的例子:

type

MyString:string;

var

MyName:MyString;

則變量MyName被說明成為最多可以包含15個字符。如果您沒有說明字符串的大小,Delphi會認為字符串包含最大值255個字符。給字符串賦值可以直接使用單引号括起的字串賦值:

MyName:='Frank.Smith';

或MyName:='張明';

因為MyName是一個可以包含15個字符的MyString型變量,上文的兩個的變量都是有效的,一個漢字可以視作兩個字符。當您給字符串型變量賦的值多于定義數值時,例如将MyName賦為‘FrankSmith.Franklin’,則Delphi隻會接受前15個字符‘FrankSmith.Fran’。在内存中,字符串通常占用比所說明的大小多一個字節的空間,因為第一個位置是一個包含這個數組大小的字節。您可以使用索引值來訪問字符串的字符,MyName可以得到MyName的第一個字符'F'。

可以使用Delphi豐富的運算符、過程和函數來處理字符串型的變量和屬性。下面介紹幾個常用的運算符和Delphi過程或函數:

Concat和(+)功能相同,都可以将多個字符串組合在一起,建立一個較大的字符串;Copy會返回一個字符串中的子字符串;Delete在一個字符串中從一個指定位置起删除一定數目的字符;Insert在一個字符串中插入一個字符串;Length返回字符串的長度;Pos返回一個子字符串在一個字符串中的位置,即索引值。

集合類型

集合類型是一群相同類型元素的組合,這些類型必須是有限類型如整形、布爾型、字符型、枚舉型和子界型。在檢查一個值是否屬于一個特定集合時,集合類型非常有用。下面的例程可以說明集合類型的用法:在窗體上加入一個編輯框和一個按鈕,清除編輯框中的文字,在其上加上Caption為“輸入元音”的标簽Label,并在編輯框的下方加入一個空的标簽,将按鈕的Default屬性改為True,建立按鈕的事件處理過程如下:

procedureTForm1.Button1Click(Sender:TObject);

type

Tvowels=setofChar;

var

Vowels:TVowels;

begin

Vowels:=['a','e','i','o','u'];

ifEdit1.TextinVowelsthen

Lable2.Caption:='是元音';

else

Lable2.Caption:='請再試';

end;

執行這個程序,在編輯框中輸入字母,表達式Edit1.TextinVowels的結果是布爾型的,in是運算符,用來判斷字母是否存在于集合中。輸入的判别結果會顯示在編輯框的下方。以上就用到了集合類型TVowels。

記錄類型

記錄是您的程序可以成組訪問的一群數據的集合。下面的例程說明了一個記錄類型的用法:

type

TEmployee=record

Name:string;

YearHired:1990..2000;

Salsry:Double;

Position:string;

end;

記錄包含可以保存數據的域,每一個域有一個數據類型。上文的記錄TEmployee類型就含有四個域。您可以用以下的方式說明記錄型的變量:

var

NewEmployee,PromotedEmployee:TEmployee;

用如下的方法可以訪問記錄的單域:

NewEmployee.Salary:=1000;

編寫如下的語句可以給整個記錄賦值:

withPromotedEmployeedo

beginsfu nb

Name:='';

YearHired:=1993;

Salary:=2000.00

Position:='editor';

end;

您的程序可以将記錄當成單一實體來操作:

PromptEmployee:=NewEmployee;

以上介紹了用戶常用的自定義類型。在Delphi的編程中,對象是非常重要的用戶自定義數據類型。象記錄一樣,對象是結構化的數據類型,它包含數據的域(Field),也包含作為方法的過程和函數。在Delphi中,當您向窗體中加入一個部件,也就是向窗體對象中加入了一個域;每一個部件也是對象,每當您建立一個事件處理過程使得部件可以響應一個事件時,您即自動地在窗體中加入了一個方法。

記錄類型

記錄是您的程序可以成組訪問的一群數據的集合。下面的例程說明了一個記錄類型的用法:

type

TEmployee=record

Name:string;

YearHired:1990..2000;

Salsry:Double;

Position:string;

end;

記錄包含可以保存數據的域,每一個域有一個數據類型。上文的記錄TEmployee類型就含有四個域。您可以用以下的方式說明記錄型的變量:

var

NewEmployee,PromotedEmployee:TEmployee;

用如下的方法可以訪問記錄的單域:

NewEmployee.Salary:=1000;

編寫如下的語句可以給整個記錄賦值:

withPromotedEmployeedo

begin

Name:='';

YearHired:=1993;

Salary:=2000.00

Position:='editor';

end;

您的程序可以将記錄當成單一實體來操作:

PromptEmployee:=NewEmployee;

以上介紹了用戶常用的自定義類型。在Delphi的編程中,對象是非常重要的用戶自定義數據類型。象記錄一樣,對象是結構化的數據類型,它包含數據的域(Field),也包含作為方法的過程和函數。在Delphi中,當您向窗體中加入一個部件,也就是向窗體對象中加入了一個域;每一個部件也是對象,每當您建立一個事件處理過程使得部件可以響應一個事件時,您即自動地在窗體中加入了一個方法。在本章第2節中,将詳細講述Delphi面向對象編程的方法和技巧。

ObjectPascal的庫單元Unit

Units是常量、變量、數據類型、過程和函數的集合,而且能夠被多個應用程序所共享。Delphi已經擁有許多預定義的程序庫單元可供您建立您的程序庫單元使用。Delphi的VisualComponentLibrary由多個程序庫單元組成,它們說明了對象、部件以供您的應用程序用來設計用戶界面。例如,當您在窗體中加入一個CheckBox時,Delphi自動在您的程序庫單元中加入了Stdctrls庫單元,因為TCheckBox部件是在StdCtrls庫單元中說明的。

當您設計您的窗體時,Delphi自動建立一個和您的窗體有關的庫單元。您的庫單元不必都和窗體有關,也可以使用預定義的隻包含數學運算函數的庫單元,或是自行編寫數學函數庫單元。在一個庫單元中所有的說明都相互有關系,例如,CDialogs程序庫單元包含了在您的應用程序中使用的普通對話框的所有說明。

ObjectPascal程序庫單元的結構

不管一個庫單元是否和一個窗體有關,庫單元的結構都是相同的。其結構如下:

unit

interface

uses

{公有說明}

implementation

uses

{私有說明}

{過程和函數的執行部分}

initialization{選擇性的}

{選擇性的初始化程序}

end.

程序庫單元的接口部分

interface是庫單元的接口部分,它決定了本庫單元對其他任何庫單元或程序的可見(可訪問)部分。您可以在接口部分說明變量、常量、數據類型、過程和函數等等。Delphi在您設計窗體的庫單元中,将窗體數據類型、窗體變量和事件處理過程都說明在這一部分。

interface标志庫單元接口部分的開始。在interface中的說明對要使用這些說明的其他庫單元或應用程序是可見的。一個庫單元可以使用其他Unit的說明,隻需要在uses子句中指明那些庫單元即可。例如,您在庫單元A中編寫程序代碼,且您想調用UnitB于interface部分說明的程序。您可以把庫單元B的名稱加入到A的interface部分的uses子句中,則任何A中的程序都可以調用B中說明的程序。

而且,如果B中interface部分的uses子句中出現C庫單元,盡管A中未曾出現C,A同樣可以調用B、C庫單元在interface中說明的程序。但如果B出現在A的interface部分的uses子句中,那麼庫單元A便不能出現在B的interface的uses子句中。因為這樣會産生對庫單元的循環訪問。當試圖編譯時,會産生出現錯誤信息。

程序庫單元的實現部分

實現部分implementation中包含interface中說明的過程、函數、事件處理過程的具體實現程序代碼。這一部分可以有自己的額外說明,但這些說明是私有的,外部程序不能調用這些說明。在interface中說明的函數實體必須在implementation部分出現,可以使用标題簡寫:隻輸入procedure或function保留字,後面跟過程或函數的名稱即可,其後則是程序的實現部分了。如果您在implementation部分說明任何常式,其标題并未出現在interface部分,則必須寫全其标題部分。

在implementation部分的uses子句中指定的庫單元,隻供給本庫單元的程序使用其interface中說明的程序。其他使用本庫單元的庫單元,不能訪問這些在implementation的udes子句中庫單元的說明,因為在implementation後進行的庫單元包含是私有的。所以上例中,如果C出現在B的implementation部分,則A不能使用C的公有部分,除非C出現在A的uses子句中。在implementation中出現的循環訪問是Delphi所允許的,如果A的implemetation的uses子句中出現B,則B的implementation部分也可以出現A。

程序庫單元的初始化部分

初始化當前庫單元所使用的數據,或是通過interface部分将數據提供給其他應用程序、庫單元使用時,您可以在庫單元中加入一個initialization部分,在庫單元的end前加上您的初始化語句。當一個應用程序使用一個庫單元時,在庫單元中的initialization部分會先于其他的代碼執行。如果一個應用程序使用了多個庫單元,則每一個庫單元的初始化部分都會在所有的程序代碼前執行。

使用Delphi的可視化部件及其庫單元

當您在窗體中加入可視化部件時,如果該部件在可視化部件庫中,Delphi會在您的庫單元的interface部分的uses子句中自動加上需要使用的庫單元名稱。但有些對象在Delphi的環境中并沒有可視化部件存在,例如,您想在庫單元中加入一個預定義的信息框,則您必須把MsgDlg庫單元加入您的uses子句中。如果您要使用TPrinter對象的話,必須将Printer庫單元加入uses子句中。在在線幫助中可以查到對象所屬的預定義庫單元。

要使用在?一庫單元的名稱,并用‘.’号隔開。例如,要在Unit2中使用Unit1中說明的Calculate函數,應使用下面的方法:

Number:=Unit1.Calculate(10);

您可以在任何标識符如屬性、常量、變量、數據類型、函數等之前加上庫單元的名稱。您可以在自由地在任何Delphi庫單元中加入程序代碼,但不要改變由Delphi生成的程序。

建立與窗體無關的新庫單元

如果您想在工程中建立一個和任何窗體無關的新庫單元,可以現選用File|NewUnit。這時一個新的庫單元加入了工程,新庫單元的代碼如下:

unitUnit2;

interface

implementation

end.

Delphi将根據您的工程中的文件數目為您的庫單元選擇名稱,您可以在程序骨架間加入您的程序代碼。

當編譯您的工程時,這個新加入的庫單元會被編譯為一個具有.DCU後綴的文件。這個新生成的文件是鍊接到工程的可執行文件上的機器代碼。

将庫單元加入工程

将庫單元加入工程是比較簡單的。無論是您自己建立的庫單元還是Delphi建立的與窗體有關的庫單元,如果已經完成,則先打開您想加入庫單元的工程(可以用OpenProject打開工程);再選用File|OpenFile,然後選擇您想加入的源程序(.PAS文件),并選擇OK即可。則庫單元被加入到應用程序中。

文件操作

Delphi可對Windows操作系統的注冊表、存儲設備和文件系統進行方便的訪問。

内置單元Registry.pas中提供了TRegistry、TRegIniFile、TRegistryIniFile三個封裝類,提供了常用的注冊表、配置文件操作功能。

Classes.pas單元中,由TStream派生的THandleStream、TFileStream、TMemoryStream、TStringStream、TResourceStream,提供了涵蓋文件流、内存流、字符序列流和資源流的讀寫操作,可方便地對文件以及中間交換的序列化數據進行處理。而TStreamAdapter以接口形式提供了更為高級的流與流之間的相互操作。

對象編程

Delphi是基于面向對象編程的先進開發環境。面向對象的程序設計(OOP)是結構化語言的自然延伸。OOP的先進編程方法,會産生一個清晰而又容易擴展及維護的程序。一旦您為您的程序建立了一個對象,您和其他的程序員可以在其他的程序中使用這個對象,完全不必重新編制繁複的代碼。對象的重複使用可以大大地節省開發時間,切實地提高您和其他人的工作效率。

什麼是對象

一個對象是一個數據類型。對象就象記錄一樣,是一種數據結構。按最簡單的理解,可以将對象理解成一個記錄。但實際上,對象是一種定義不确切的術語,它常用來定義抽象的事務,是構成應用程序的項目,其内涵遠比記錄要豐富。在本書中,對象可被理解為可視化部件如按鈕、标簽、表等。了解對象,最關鍵的是掌握對象的特性。一個對象,其最突出的特征有三個:封裝性、繼承性、多态性。

對象的封裝性

對對象最基本的理解是把數據和代碼組合在同一個結構中,這就是對象的封裝特性。将對象的數據域封閉在對象的内部,使得外部程序必需而且隻能使用正确的方法才能對要讀寫的數據域進行訪問。封裝性意味着數據和代碼一起出現在同一結構中,如果需要的話,可以在數據周圍砌上“圍牆”,隻有用對象類的方法才能在“圍牆”上打開缺口。

對象的繼承性

繼承性的含義直接而且顯然。它是指把一個新的對象定義成為已存在對象的後代;新對象繼承了舊類的一切東西。在往新對象中添加任何新内容以前,父類的每一個字段和方法都已存在于子類中,父類是創建子類的基石。

對象的多态性

多态性是在對象體系中把設想和實現分開的手段。如果說繼承性是系統的布局手段,多态性就是其功能實現的方法。多态性意味着某種概括的動作可以由特定的方式來實現,這取決于執行該動作的對象。多态性允許以類似的方式處理類體系中類似的對象。根據特定的任務,一個應用程序被分解成許多對象,多态性把高級設計處理的設想如新對象的創建、對象在屏幕上的重顯、程序運行的其它抽象描述等,留給知道該如何完美的處理它們的對象去實現。

對象範圍

一個對象的範圍決定了它的數據域、屬性值、方法的活動範圍和訪問範圍。在一個對象的說明部分說明的數據域、屬性值、方法都隻是在這個對象的範圍中,而且隻有這個對象和它的後代才能擁有它們。雖然這些方法的實際程序代碼可能是在這個對象之外的程序庫單元中,但這些方法仍然在這個對象的範圍内,因為它們是在這個對象的說明部分中說明的。

當您在一個對象的事件處理過程中編寫程序代碼來訪問這個對象的屬性值、方法或域時,您不需要在這些标識符之前加上這個對象變量的名稱。例如,如果您在一個新窗體上加入一個按鈕和一個編輯框,并為這個按鈕編寫OnClick事件處理過程:

procedureTForm1.Button1Click(Sender:Tobject);

begin

Color:=clFuchsia;

Edit1.Color:=clLime;

end;

其中的第一行語句是為整個窗體Form1着色。可以編寫如下:

Form1.Color:=clFuchsia;

如果Edit1是在其他窗體中,那麼您需要在編輯框之前加上這個窗體對象的名稱了。例如,如果Edit1是在Form2之中,那它是Form2說明的一個數據域,并位于Form2的範圍中,那麼您需要将第二句改為:

Form2.Edit1.Color:=clLime;

而且需要把Unit2加入Unit1的uses子句中。

數據繼承

前面的TForm1類型是很簡單的,因為它隻含有域Button1和方法Button1Click。但是在這個窗體上,您可以改變窗體的大小、加入或删除窗體的最大最小化按鈕,或設置這個窗體為MDI界面。對于一個隻包含一個域和方法的對象來講,您并沒有看到顯式的支持程序。在窗體上單擊鼠标或用ObjectInspector的上端的ObjectSelector選中Form1對象,按動F1查閱它的在線幫助,您會在Properties和Method中找到它的繼承到的全部屬性和方法。

這些是在TForm類型中說明的,TForm1是TForm的子類,直接繼承了它所有的域、方法、屬性和事件。例如窗體的顔色屬性Color就是在TForm中說明的。當您在工程中加入一個新窗體時,就等于加入了一個基本模型。通過不斷地在窗體中加入部件,您就自行定義了一個新的窗體。要自定義任何對象,您都将從已經存在的對象中繼承域和方法,建立一個該種對象的子類。例如對象TForm1就被說明為對象TForm的子類,擁有一個窗體部件的基本屬性或方法。隻有當您在窗體中加入了部件或編寫了事件處理過程時,Form1才成為您自己的類型。

一個比較特殊的對象是從一個範圍較廣或較一般的對象中繼承下來的,它是這個特别對象的祖先,這個對象則稱為祖先的後代。一個對象隻能有一個直接的祖先,但是它可以有許多後代。TForm是TForm1類型的祖先,所有的窗體對象都是TForm的後代。

用F1查閱窗體的在線幫助時,您會發現TForm被稱為component(部件)。這是因為所有的部件都是對象。

在這個結構中所有的部件都是對象。部件類型TComponent從TObject類型中繼承數據和程序代碼,并具有額外的可以用作特殊用途的屬性、方法、事件,所以部件可以直接和用戶打交道,記錄它的狀态并存貯到文件中等等。控制類型TControl從TComponent中繼承而來,又增加了新的功能,如它可以顯示一個對象。

在上圖中,雖然TCheckBox不是直接由TObject繼承來的,但是它仍然有任何對象所擁有的屬性,因為在VCL結構中,TCheckBox終究還是從TObject中繼承了所有功能的特殊對象,但它還有些自行定義的獨到的功能,如可以選擇記錄狀态等。

臨時表

根據服務器上的DB數據庫,在本地創建一個臨時的表,這樣可以提高用戶對數據的訪問效率,同時也減輕了數據庫的訪問壓力。

創建臨時表*.DB

procedure TfUserInfo.createWork;

begin

with tblUserInfo do //頁面上的Table控件名字

begin

Active := False;

DatabaseName := 'Userwork';

TableName := 'W_USERINFO.DB'; //要創建的臨時表的名字

TableType := ttParadox;

with FieldDefs do //遍曆頁面(數據為DB Table)中的列,作為臨時表的列

begin

Clear;

Add('UserID' , ftString, 6, False); //設置臨時表的列、類型、長度

Add('UserName' , ftString, 20, False);

end;

CreateTable; //創建臨時表

end;

tblUserInfo.Close;

tblUserInfo.Open;

while not dbUserMSSQL.ADOQueryUser.Eof do //為臨時表填充數據

begin

tblUserInfo.Append;

tblUserInfo.FieldByName('UserID').AsString :=

dbUserMSSQL.ADOQueryUser.FieldByName('UserID').AsString;

tblUserInfo.FieldByName('UserName').AsString :=

dbUserMSSQL.ADOQueryUser.FieldByName('UserName').AsString;

tblUserInfo.Post;

dbUserMSSQL.ADOQueryUser.Next;

end;

tblUserInfo.First;

end;

相關詞條

相關搜索

其它詞條