Object Pascal Style Guide - By Charles Calvert
(對象Pascal編碼風格嚮導- 譯:Tommy Tong)
我們承認許多好的已經確定的工作室或個人,擁有他們自己的和本文裡所說的不同的編程習慣, 但是,我們強烈建議你使用一個工具將你的代碼轉換為Borland風格的代碼,然後再提交給Borland,PRoject JEDI或其他任何公開的原始碼知識庫。我們不想強迫你改變你的習慣,但我們堅持所有與Borland產品一起工作的的程式碼遵循本文描述的習慣。
物件Pascal是一種優美的設計語言。較強的可讀性就是它的一個優點。本文設計的標準將增強物件Pascal程式碼的可讀性。當開發人員遵從本文展現的這些簡單的習慣,他們也將成為標準,這將有益於所有的Delphi開發人員使用統一的易讀的程式碼風格。執行這些標準的努力將增加開發人員的原始程式碼的價值,特別是在維護和調試循環階段。
儘管我們相信並且讚美本文所宣揚的風格,但我們沒有必要支持它,因為它本身是正確的而其它的則是錯誤的。然而我們相信絕大多數開發人員遵從的標準是有它的功效的,所以我們仍然支持並維護該風格。人類的大腦總是適應標準,並且尋找方法去快速組織所熟悉的模式,以便快速而有效地理解其意義。正是因這種要求而建立的標準將使大量的人盡可能容易的閱讀程式碼。如果第一次使用我們的指導方針是感到陌生,那麼我們請你堅持一會兒,你會發現你也變得習慣了。或者,如果你願意,你也可以保持你自己的風格,並透過一個遵從我們標準的程式來轉換,然後你可以將你的程式碼提交給Borland或其他知識庫了。
一些文字編輯器,象Visual SlickEdit可以幫助你按照一定的風格來格式化你的程式碼。
一個免費的由Egbert van Nes開發的格式化程式可以在以下的連接獲得:
http://www.slm.wau.nl/wkao/delforexp.html
另一個針對Delphi的商業化程式是CrackerJax:
http://www.kineticsoftware.com/html/products.html
────────────────────────────────────────────
1.0 介紹
本文不是為Object Pascal語言定義語法規則的一種嘗試。例如:在else前面放置封號";"是違法的;編譯器不允許這種用法。所以我不會在本文中展示語法規則。本文旨在在語言提供選擇的地方定義適當的行為習慣。我通常在只有一種控制方法的地方保持沉默。
1.1 背景
在本文出現的指導方針是基於Delphi原始碼的一部分。 Delphi原始碼恰好遵循這些指導方針。如果你發現了違反這些原則的情況,那麼應該是這些原則而不是那些不確定的原始碼成為你的指導方針。然而,你可以使用這些原始程式碼作為這些原則的補充,至少它可以幫助你得到關於你自己的程式碼的形式的一般看法。
1.2 感謝
本文這些格式是基於已完成的為java語言定義的風格標準的工作的。 Java在規則上對格式化Object Pascal原始碼是沒有任何影響的,但在Sun網站上的文件是本文的基礎。 在某些特殊的地方本文的風格和格式受到"A Coding Style Guide for Java WorkShop and Java Studio Programming"(Achut Reddy, 《Java車間和Java工作室的編碼嚮導》)的極大啟發。文章可在該URL找到:http://www.sun.com/workshop/java/wp-coding
Delphi小組為本文的完成做出了重大貢獻,事實上,如果沒有它們的幫助,本文是無法完成的。
2.0 原始檔
Object Pascal原始碼主要被分成單一來源文件和專案文件,他們都遵從相同的習慣。 Delphi專案檔案有一個.DPR的副檔名。它是項目的主文件。任何在專案中使用的單元檔案都有一個.PAS的副檔名。其它的文件,象批次檔、HTML檔或DLLs也可以在專案中扮演一個角色,但本文只涉及專案文件和單元文件。
2.1 原始檔命名
Object Pascal支援長檔名。如果你使用幾個單字來形成一個單一的名稱,那麼最好是為每個單字使用大寫的開頭字母:MyFile.pas。這被認為是插入式大寫或駝峰式大寫。擴展名應使用小寫形式。由於歷史原因,Delphi原始碼經常使用8:3式命名模式,但開發人員不必為上述規則所限製而轉向Delphi小組的用法。
如果你正在翻譯一個C/C++頭文件,那麼你翻譯的Pascal檔案要與C/C++頭檔保持相同的主文件名,副檔名用.PAS。例如:Windows.h -> Windows.pas。如果Pascal語法強迫你將幾個頭檔組合到一個單一的單元檔中,那麼包含其他頭檔的那個頭檔的檔名將會作為新單元檔的名稱。例如:Windows.h包含了WinBase.h文件,則新的單元文件名稱為Windows.pas.
2.2 來源文件組織
所有的Object Pascal單元檔案應依照以下的順序包含下列元素:
版權/標識塊註釋
單元名
介面段
實現部分
一個結束符"end."
每個部分之間至少空一行。
其它的元素應當被結構化成你認為最適當的順序。但版權應出現在檔案的最開始,然後是單元名,然後是任何條件定義、編譯器指示符或包含語句,然後是uses字句:
{************************************************* ******}
{ }
{ Borland Delphi Visual Component Library }
{ }
{ Copyright (c) 1995,98 Inprise Corporation }
{ }
{************************************************* ******}
unit Buttons;
{$S-,W-,R-}
{$C PRELOAD}
interface
uses
Windows, Messages, Classes,
Controls, Forms, Graphics,
StdCtrls, ExtCtrls, CommCtrl;
如果你將type段放到const段之前,或是將它們兩者混合,那是沒有什麼影響的。
實作部分需要先將implementation寫出來,然後是uses字句,然後是其它的包含聲明或別的指示符:
implementation
uses
Consts, SysUtils, ActnList,
ImgList;
{$R BUTTONS.RES}
2.2.1 版權/識別塊註釋
每一個原始檔案都應以一個包含版本資訊和標準版權佈告區塊註解開始。版本資訊可以像下面這樣:
{************************************************* ******}
{ }
{ Widgets Galore }
{ }
{ Copyright (c) 1995,98 Your Company }
{ }
{************************************************* ******}
版權佈告至少需要包含以下行:
版權所有(C) 年份版權所有者
如果你是為Borland開發軟體的第三方,你可以在版權的最後加入你自己的名字:
{************************************************* ******}
{ }
{ Borland Delphi Visual Component Library }
{ Copyright (c) 1995,99 Borland International }
{ Created by Project JEDI }
{ }
{************************************************* ******}
2.2.2 unit聲明
每一個單元檔要有一個unit聲明。 unit是一個保留字,因此它需要小寫。單元的名稱可以是大小寫混合的,但必須和單元檔案的檔案名稱相同。例如:
unit MyUnit;
則單元文件的名稱應為MyUnit.pas。在檔案系統中,它作為這個檔案的入口。
2.2.3 uses聲明
在單元內部,uses聲明應使用小些的uses引導。被引用的單元名稱要遵循在他自己的單元中被定義時使用的大寫習慣:
uses MyUnit;
每個單元名被一個逗號同其相鄰的單元名分開,最後一個單元名後面跟著一個分號:
uses
Windows, SysUtils, Classes, Graphics, Controls, Forms,
TypInfo;
在uses的下一行開始加入單元名和在uses後面直接加入單元名同樣都是正確的。
uses Windows, SysUtils, Classes, Graphics, Controls, Forms,
TypInfo;
你可以格式化你的單元名列表,可以在80個字元限制下換行,或是每個單元名稱一行。
2.2.4 類別和介面定義
類別的定義以兩個空格開始,然後是一個前綴"T"。 前綴要大寫,每個內嵌的單字要大寫開頭。不要在Object Pascal原始碼中使用製表符"Tab"。例:
TMyClass
在標識符之後接一個空格,然後是等號,然後是class單詞,class要小寫:
TMyClass = class
如果你的類別是從祖先繼承來的,則需要加入包含祖先類別的左右括號:
TMyClass = class(TObject)
範圍指示符號離頁邊兩個空格,並以下面的順序出現:
TMyClass = clss(TObject)
private
protect
public
published
end;
資料通常只在private段中聲明,並且它們的標識符以"F"開始。所有此類的聲明離頁邊4個空格:
TMyClass = class (TObject)
private
FMyDate: Integer;
function GetDate: Integer;
procedure SetData(Value: Integer);
public
published
property MyData: Integer read GetData write SetData;
end ;
介面遵從同類相同的規則,除了你應忽略範圍指示符和私有數據,並且使用interface單字代替class單字。
命名習慣
除了保留字和指示符是小寫外,所有的Pascal標識符應使用駝峰式格式,即每個標識符開頭字母要大寫,內嵌單詞的首字母也要大寫,只取首字母的縮寫詞也一樣。
MyIdentifier
MyFTPClass
對此規則主要的例外是頭檔翻譯的情況,應遵循在原頭檔案中的命名習慣。例如:
WM_LBUTTONDOWN,不要寫成wm_LButtonDown.
除了頭檔翻譯外,不要使用底線分割單字。類名應是名詞或名詞片語。介面或類別的名稱依賴於介面的顯而易見的目的、用途。
好的名字:
AddressForm, ArrayIndexOutOfBoundsException
低劣的名字:
ManageLayout //使用動詞片語
delphi_is_new_to_me //使用底線
3.1 單元命名
參見單元聲明
3.2 類/介面命名
參見類/介面聲明
3.3 域/字段命名
使用駝峰式格式。以大寫的"F"開始,並且在private中聲明所有的數據,使用屬性或獲取者(getter)和安裝者(setter)來提供公共的存取操作。例如:使用名字GetSomething來命名一個傳回內部域/欄位值的函數,使用SetSomething來命名一個設定域/欄位值的過程。
不要在const段全部使用大寫,除非是頭檔翻譯的需要。
Delphi是在加州開發的,所有我們都阻止記號的使用,除非是頭檔翻譯的需要。
正確:
FMyString: string;
不正確:
lpstrMyString: string;
當然在枚舉類型定義中保留了匈牙利命名法:
TBitBtnKind = (bkCustom, bkOK, bkCancel, bkHelp,
bkYes, bkNo, bkClose, bkAbort, bkRetry,
bkignore, bkAll);
在這種情況下字元bk被插入到這個枚舉類型的每一個元素前。 bk意味著ButtonKind。
在考慮命名習慣時,要避免使用單一字元的名稱,但零時變數和循環變數除外。
避免使用"l"(L)變量,因為它和"1"(one)無論在印表機還是在顯示器上都難以分辨。
3.4 方法命名
方法命名也使用駝峰格式。方法命名習慣同非常量域的命名方法是相同的,但可以從上下文區分它們。方法命名應強制使用動詞或動詞片語。例如:
//好的方法命名:
ShowStatus, DrawCircle, AddLayoutComponent
//差的方法命名:
MouseButton //名詞片語,沒有描述功能
drawCircle //以小寫字母開頭
add_layout_component //使用了底線
//以下方法的功能不夠明確。它是開始運行一個服務呢(更好:StartServer)還是判斷一個服務是否在運作(更好:IsServerRunning)?
ServerRunning //動詞片語,但不是命令
一個取得或設定一些類別屬性的方法應分別稱為GetProperty或SetProperty,Property代表該屬性的名稱。例如:
GetHeight, SetHeight
一個測試類別的布林屬性的方法應被命名為IsVisible,Visible代表屬性的名稱。例如:
IsResizable, IsVisible
3.5 局部變數命名
除了不使用"F"外,局部變數的命名規則同域/字段的命名規則一樣。參見3.3節。
3.6 保留字
保留字和指示符要全部小寫。這有時有些混亂。例如:Integer是一個標識符,並且以首字母大寫出現。而string保留字則全部小寫。
3.7 類型聲明
所有類型名稱聲明以字母T開始,接下來和類別的命名相同。
4.0 空白用法
4.1 空白行
空白行可以透過將邏輯相關的程式碼段分組來提高可讀性。一個空白行也可以在下列地方使用:
在版權註解區塊之後,套件聲明(package),導入段(import)。
類別聲明之間。
方法聲明之間。
4.2 空格
Object Pascal是一種非常清晰易讀的語言。通常,你不需要在程式碼裡加入很多空格來分隔行。以下幾條提供了一些原則該如何使用空格:
4.2.2 不應使用空格:
在方法名和左括號之間;
在.(dot)操作符之前或之後;
在一元運算子和它的操作數之間;
在一個型別和被它強制轉換的表達式之間;
在左括號之後和右括號之前;
在左方括號之後和右方括號之前;
在一個封號前;
例如:
//正確用法:
function TMyClass.MyFunc(var Value: Integer);
MyPointer := @MyRecord;
MyClass := TMyClass(MyPointer);
MyInteger := MyIntegerArray[5];
//錯誤用法:
function TMyClass.MyFunc( var Value: Integer ) ;
MyPointer := @ MyRecord;
MyClass := TMyClass ( MyPointer ) ;
MyInteger := MyIntegerArray [ 5 ] ;
4.3 縮排
你應當總是為所有的縮排層次縮排兩個空格。換句話說就是,第一層縮排兩個空格,第二層縮排四個空格,第三層縮排六個空格……。不要使用製表符Tab。
當然,仍然有少量的例外。保留字象unit, uses, type, interface, implementation, initialization 和finalization總是頂格的。單元的最後一個end標識符也是頂格的。在專案文件中,program和主begin、end也是頂格的。在主begin..end區塊內則需要縮排至少兩個空格。
4.4 續行
行應限制在80列以內。超過80列的行應被分成多個連續的行。所有的後續行應排列在該聲明的第一行之後,並且縮排兩個字元的空格。
例如:
//正確:
function CreateWindowEx(dwExStyle: DWord;
lpClassName: PChar; lpWindowName: PChar;
dwStyle: DWORD; X, Y, nWidth, nHeight: Integer;
hWndParent: HWND; hMenu: HMENU; hInstance: HINST;
lpParam: Pointer): HWND; stdcall ;
if ((X = Y)或(Y = X) or
(Z = P)或(F = J) then
begin
S := J;
end ;
不要在參數和它的型別之間換行,除非列表是由逗號分隔,那樣的話要在最後一個參數前換行,這樣型別名稱就在下一行開頭了。冒號和它的變數之間不應該有空格,而冒號和型別名稱之間要有一個空格。
//正確:
procedure Foo(Param1: Integer; Param2: Integer);
//錯誤:
procedure Foo( Param :Integer; Param2:Integer);
一個後續行不應以一個二進位操作符開始。避免在通常不出現空白的地方割斷一行,例如在方法名和它的左括號之間,或在一個陣列名和它的左方括號之間。如果你必須在上述情況下割斷行,那麼應在左括號或左方括號之後換行。不要把begin放在其它程式碼的同一行。
例如:
//錯誤:
while (LongExpression1 or LongExpression2) do begin
//DoSomething
//DoSomethingElse;
end ;
//正確
while (LongExpression1 or longExpression2) do
begin
//DoSomething
//DoSomethingElse;
end ;
if (LongExpressiong1) or
(LongExpression2) or
(LongExpression3) then
5.0 註釋
Object Pascal語言支援兩種註解:區塊和單行註解。以下是一些註解用法原則:
·在單元頂部放置註釋用以解釋單元的用途是有益的
·在類別聲明前放置註解是有益的
·在方法聲明前設定註釋是有益的
·避免語句意義明顯的註釋
i := i + 1; //Add one to i
·記住,容易誤解的註釋比沒有註釋更有害。
·避免在註解裡放入看上去要失效的訊息
·避免在註釋的邊框裡嵌入星號或其他的排版符號
·零時的註釋,即需要被改變或刪除的註釋,要在他們之前加上"???:"標記,這樣易於找到。從觀念上來說,所有的零時註解都應在程式發布前刪除。
// ???: Change this to call Sort when it is fixed
List.MySort;
5.1 塊註釋
Object Pascal支援兩種類型的區塊註解。最常用的是一對花括號{}括起來的註解。 Delphi小組盡可能的保持該註釋少而簡單。例如:你應該避免在你的註解裡使用星號來建立圖案或行。相反,使用空格來分隔你的註釋,就像你在字處理文檔裡做的一樣。你的註釋裡的單字應在第一個花括號的同一行開始,就像下面從DsgnIntf.pas中摘錄的一樣:
{ TPropertyEditor
Edits a property of a component, or list of components,
selected into the Object Inspector. The property
editor is created based on the type of the
property being edited as determined by the types
registered by...
etc...
GetXxxValue
Gets the value of the first property in the
Properties property. Calls the appropriate
TProperty GetXxxValue method to retrieve the
value.
SetXxxValue Sets the value of all the properties
in the Properties property. Calls the appropriate
TProperty SetXxxxValue methods to set the value. }
塊註釋通常被用在版權註釋中。也被用來註解掉一些程式碼行。
用於解釋方法的用途的區塊註釋應被訪問在方法的聲明前面。
例如:
// CORRECT
{ TMyObject.MyMethod
This routine allows you to execute code. }
procedure TMyObject.MyMethod;
begin
end;
// INCORRECT
procedure TMyObject.MyMethod;
{************************************************* *****
TMyObject.MyMethod
This routine allows you to execute code.
************************************************** *****}
begin
end;
第二種區塊註解包含了兩個字符,括號和星號:(* *)。這有時被稱為星括號註釋。這些註釋一般只在程式碼開發時有用,它的主要好處是允許嵌套註釋,註釋嵌套少於兩層。 Object Pascal不支援同類型的註解嵌套,因此事實上只有一層嵌套:花括號在星括號裡面,或是星括號在花括號裡面。 只要在你不嵌套它們時,在該類型的註釋中的其它類型的標準Pascal註釋將被忽略。因此,你可以使用該語法註解一大塊既有程式碼又有註解的程式碼:
(* procedure TForm1.Button1Click(Sender: TObject);
begin
DoThis; // Start the process
DoThat; // Continue iteration
{ We need a way to report errors here, perhaps using
a try finally block ??? }
CallMoreCode; // Finalize the process
end ; *)
在本例中,整個Button1Click方法被註解掉了,包括其中的任何子註解。
5.2 單行註釋
單行註解由註解符//及其引導的文字組成,在文字和註解符之間有一個空格。單行註解同程式碼在不同行的,要同程式碼有相同的縮排層次。你可以使用多個單行註解形成大的註解。
在單行註解或註解群組之前要有一個空白行,除非它是一個區塊的第一行。如果註解用於幾個語句,那麼註解和註解群組之後要跟一個空行。如果註解僅解釋它後面的一行聲明,則不必跟隨一個空白行。
例如:
// Open the database
Table1.Open;
單行註解也可以跟在他們解釋的程式碼聲明後面。這類註解有時被引用為跟蹤註解。在他們和程式碼之間至少要有一個空格。如果有多個追蹤註解在一個程式碼區塊中同時出現,那麼這些註解需要被對齊。
例如:
if ( not IsVisible) then
Exit; // nothing to do
Inc(StrLength); // reserve space for null terminator
若要避免對每行可執行程式碼進行追蹤註解。在一個方法或函數的begin..end區塊之間限制使用註解、甚至讓其為空,則在通常情況下是最好的。長的註解可以出現在方法、函數的定義之前的區塊註釋當中。
類別
6.1 類體的組織
類體的組織應遵循下列順序:
·域/欄位聲明
·方法聲明
·屬性定義
域/字段、屬性、方法應按它們的名稱進行字母索引排列。
6.1.1 訪問級別
除了由IDE產生的程式碼,類別的範圍指示符應按以下順序:
·private 聲明
·protect聲明
·public聲明
·published聲明
在Object Pascal中,類別成員有四種存取等級:發佈的、公開的、受保護的和私有的--依存取能力遞減的順序排列。預設的存取等級是published。一般,一個成員應被賦予最適合它的最低的存取等級。例如:只能在同一單元中被其他類別存取的成員就應被宣告為私有的。同時,聲明低存取等級的成員也給了編譯器提高最佳化的機會。當然,另一方面,使用低存取等級對子類別的擴展造成了困難。如果有理由認為某個類別在將來某個時候會被子類化,那麼應當將那些需要被子類別繼承擴展的成員聲明為受保護的,用於訪問私有資料的屬性也可以提供這方面的保護。
你應禁止對資料的公開存取。資料通常在private區段聲明,任何對他的公開存取應透過GetXXX、SetXXX方法或屬性來操作。
6.1.8 建構函數聲明
方法需要按字母索引排列。將建構子和析構函式放在public段的開始或依照字母索引排列都是正確的。
如果有多個構造函數或你使用了多個相同的名字,那麼應根據形參列表來排列,參數少的在參數多的前面。這意味著如果存在沒有參數的建構函數的話,那麼它必定出現在第一個。為了和C++Builder保持最好的相容,應保證建構函式的參數清單的唯一性。 C++不是根據建構函式的名稱來呼叫它的,所以區別多個建構子的唯一方法是通過它的參數列表。
6.2 方法聲明
如果可能,方法聲明要出現在單獨一行上。
例如:
Examples:
procedure ImageUpdate(Image img, infoflags: Integer,
x: Integer, y: Integer, w: Integer, h: Integer)
7.0 介面
介面的聲明與類別的聲明有相同的形式:
InterfaceName = interface ([ inherited Interface ])
InterfaceBody
end ;
介面聲明應被縮排兩格,介面體縮排四格,end結束符縮排兩格。
在介面聲明中沒有網域/欄位。但屬性可以出現。
所有的介面方法天生就是公開的和抽象的,用不著在介面聲明中包含此類關鍵字。
除非有其他的注意事項,否則接口的聲明同類的聲明具有相同的風格。
7.1 介面體組織
接口體的組織可以以下的順序:
·介面方法聲明
·介面屬性聲明
介面方法和屬性的聲明和類別具有相同的風格。
8.0 聲明
聲明是由封號結尾的一行或幾行程式碼。單一聲明只有一個封號,複合聲明中有多個封號。
//這是單一聲明:
A := B;
//這是複合宣告:
begin
B := C;
A := B;
end ;
8.0.1 單一聲明
如果需要將單一聲明換行,則需要參考上一行縮排兩格。
//例如:
MyValue :=
MyValue + (SomeVeryLongStatement / OtherLongStatement);
8.1.1 賦值與表達式聲明
每一行最多有一條聲明。
例如:
a := b + c; Inc(Count); //錯誤
a := b + c; //正確
Inc(Count); //正確
8.1.2 局部變數聲明
局部變數也使用駝峰格式,不要使用引導符"F",這是為類別宣告中域/欄位保留的。
例如:
var
MyData: Integer;
MyString: string ;
你可以在同一行宣告多個類型相同的變數:
var
ArraySize, ArrayCount: Integer;
這種聲明習慣在類別聲明中是不提倡。
8.1.3 數組聲明
通常總是在左方括號之前和右方括號之後放置一個空格:
type
TMyArray = array [0..100] of Char;
8.2.3 if語句
if語句至少要以兩行的形式出現:
例如:
//錯誤:
if A = B then DoSomething;
//正確
if A = B then
DoSomething;
如果是複合的if語句,則應當每個分隔符號一個新行:
//錯誤:
if A = B then begin
DoSomething;
DoSomethingElse;
end else begin
DoThis;
DoThat;
end ;
//正確
if A = B then
begin
DoSomething;
DoSomethingElse;
end
else
begin
DoThis;
DoThat;
end ;
以下的少數變化可以被採用:
//正確
if Condition then
begin
DoThis;
end else
begin
DoThat;
end ;
//正確
if Condition then
begin
DoThis;
end
else
DoSomething;
//正確
if Condition then
begin
DoThis;
end else
DoSoemthing;
//下面的方式可能不被關心,但卻是值得讚揚的:
if Condition then
DoThis
else DoThat;
8.2.4 for語句
Example:
// INCORRECT
for i := 0 to 10 do begin
DoSomething;
DoSomethingElse;
end ;
// CORRECT
for i := 0至10 do
begin
DoSomething;
DoSomethingElse;
end ;
8.2.5 while 語句
Example:
// INCORRECT
while x < j do begin
DoSomething;
DoSomethingElse;
end ;
// CORRECT
while x < j do
begin
DoSomething;
DoSomethingElse;
end ;
8.2.6 repeat until 語句
Example:
// CORRECT
repeat
x := j;
j := UpdateValue;
until j = 25;
8.2.7 case 語句
Example:
// CORRECT
case Control.Align of
alLeft, alNone: NewRange := Max(NewRange, Position);
alRight: Inc(AlignMargin, Control.Width);
end ;
// CORRECT
case x of
CSStart:
begin
j := UpdateValue;
end ;
csBegin: x := j;
csTimeOut:
begin
j := x;
x := UpdateValue;
end ;
end ;
// CORRECT
case ScrollCode of
SB_LINEUP, SB_LINEDOWN:
begin
Incr := FIncrement div FLineDiv;
FinalIncr := FIncrement mod FLineDiv;
Count := FLineDiv;
end ;
SB_PAGEUP, SB_PAGEDOWN:
begin
Incr := FPageIncrement;
FinalIncr := Incr mod FPageDiv;
Incr := Incr div FPageDiv;
Count := FPageDiv;
end ;
else
Count := 0;
Incr := 0;
FinalIncr := 0;
end ;
8.2.8 try 語句
// Correct
try
try
EnumThreadWindows(CurrentThreadID, @Disable, 0);
Result := TaskWindowList;
except
EnableTaskWindows(TaskWindowList);
raise ;
end ;
finally
TaskWindowList := SaveWindowList;
TaskActiveWindow := SaveActiveWindow;
end ;
作者 Blog: http://blog.csdn.net/sailerbai/