关于编程的规范(300分)

  • 主题发起人 主题发起人 cooler
  • 开始时间 开始时间
Delphi 编程规范
这篇文章展现了一种格式化Delphi代码的标准风格。它的实现是基于Delphi小组
的开发习惯。

我们承认许多好的已经确定的工作室或个人,拥有他们自己的和本文里所说的不同
的编程习惯,但是,我们强烈建议你使用一个工具将你的代码转换为 Borland风格的代
码,然后再提交给Borland,Project JEDI 或其他任何公开的源代码知识库。我们不想
强迫你改变你的习惯,但我们坚持所有同 Borland产品一起工作的的代码遵循本文描述
的习惯。

Object Pascal 是一种优美的设计语言。较强的可读性就是它的一个优点。本文设
计的标准将增强 Object Pascal代码的可读性。当开发人员遵从本文展现的这些简单的
习惯,他们也将成为标准,这将有益于所有的 Delphi开发人员使用统一的易读的代码
风格。执行这些标准的努力将增加开发人员的源代码的价值,特别是在维护和调试循环
阶段。

尽管我们相信并且赞美本文所宣扬的风格,但我们没有必要支持它,因为它本身是
正确的而其它的则是错误的。然而我们相信绝大多数开发人员遵从的标准是有它的功效
的,所以我们仍然支持并维护该风格。人类的大脑总在适应标准,并且找寻方法去快速
组织所熟悉的模式,从而快速而有效地理解其含义。正是因这种要求而建立的标准将使
大量的人尽可能容易的阅读代码。如果在初次使用我们的指导方针是感到陌生,那么我
们请你坚持一会儿,你会发现你也变得习惯了。或者,如果你愿意,你也可以保持你自
己的风格,并通过一个遵从我们标准的程序来转换,然后将你的代码提交给 Boland 或
其他知识库了。

一些文本编辑器,象 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)的很大启发。该文章可在该
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 单元文件应当按照以下的顺序包含下列元素:

◎版权/标识块注释
·单元名(unit)
·接口段(interface)
·实现部分(implementation)
·结束符(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"。在标识符之后接一个空
格,然后是等号,然后是 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) or (Y = X) or (Z = P) or
(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

do
This;
// Start the process
do
That;
// 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:

// Broken line is aligned two spaces in from left.
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
do
Something;


◎正确:
if A < B then

do
Something;


如果是复合的 if 语句,则应当每个分隔符一个新行:

×错误:
if A < B then
begin

do
Something;

do
Somethingelse
;

end else
begin

do
This;

do
That;

end;


◎正确:
if A < B then

begin

do
Something;

do
Somethingelse
;

end
else

begin

do
This;

do
That;

end;


以下的少数变化可以被采用:

◎正确:
if Condition then

begin

do
This;

end else

begin

do
That;

end;


◎正确:
if Condition then

begin

do
This;

end
else

do
Something;


◎正确:
if Condition then

begin

do
This;

end else

do
Soemthing;


//下面的方式可能不被关心,但却是值得表扬的:
if Condition then

do
This
else
do
That;


8.2.4 for语句
Example:
// INCORRECT
for i := 0 to 10 do
begin

do
Something;

do
Somethingelse
;

end;


// CORRECT
for i := 0 to 10 do

begin

do
Something;

do
Somethingelse
;

end;


8.2.5 while 语句
Example:
// INCORRECT
while x < j do
begin

do
Something;

do
Somethingelse
;

end;


// CORRECT
while x < j do

begin

do
Something;

do
Somethingelse
;

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 语句
Example:
// Correct
try
try
EnumThreadWindows(CurrentThreadID, @Disable, 0);

Result := TaskWindowList;

except
EnableTaskWindows(TaskWindowList);

raise;

end;

finally
TaskWindowList := SaveWindowList;

TaskActiveWindow := SaveActiveWindow;

end;
 
好! 有时间再看。
 
私以为一个好的程序员写出来的代码一定是符合代码规范的.并且在阅读时是使人赏心悦目的.
 
有这样的格式化工具,delphix
 
至少要做到看了顺眼:
格式缩进、规则命名、勤加注释。
 
各位大虾,这么长的规范就这么贴么,看起来真累。
我这里还有一份我自己写的,请大家指正
程序编写规范
1、 变量名、函数及过程名称命名:
使用有意义的变量名。
可以使用英文、全拼拼音及两者相结合的方式命名。
不能使用拼音开头一个字母的方式。
英文常用词可以使用略写,入id,addr等。
2、 DataModal的使用
DataModal中不能use任何窗口单元。
所有sql语句在DataModal中。
3、 窗口单元
使用Taction编写代码。
窗口单元不能相互use。
其他单元不能直接处理窗口单元中的控件的行为。
限制使用数据感知控件。
多个窗口单元共同使用的部分放在Tframe中。
字符串常量放在单独的单元中。
4、 程序必须有注释。
注释例子
//---------------------------------------------------------------------------------------------------------------------
// 模块名称:
// 参数: 无
// 功能: 显示窗口
// 返回值: 无
// 编写人: 时间:
//---------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
// 修改纪录:
// 删除代码:
// 删除原因:
// 增加代码:
// 增加原因:
// 修改人: 时间:
//---------------------------------------------------------------------------------------------------------------------
5、 目录结构
应用程序主目录:可执行文件及其附件(dll,配置文件。。。)
/source 可执行文件的源代码
/source/xxx xxx模块的源代码
/文档 系统文档
/dcu 编译产生的dcu文件
 
收藏!!
 
谢谢大家的经验之谈,希望大家继续努力
 
〉〉wen
不是吧,有170多页
 
接受答案了
 
后退
顶部