Delphi代码编写标准详解
- 格式:doc
- 大小:79.50 KB
- 文档页数:23
目录一、文件命名 (2)1、项目文件 (2)2、窗体文件 (2)3、数据模块文件 (2)4、远程数据模块文件 (2)5、单元文件 (3)6、窗体单元 (3)7、数据模块单元 (3)8、通用的单元 (3)9、组件单元 (3)10、文件头 (4)二、窗体与数据模块命名 (4)1、窗体类型的命名标准 (4)2、窗体实例的命名标准 (4)3、自动创建的窗体 (4)4、模式窗体实例化函数 (4)5、数据模块的命名标准 (6)6、数据模块实例的命名标准 (6)三、组件命名 (6)1、组件类型的命名标准 (6)2、组件单元 (6)3、注册单元 (6)4、组件实例的命名规则 (7)四、过程和函数 (7)五、包命名 (7)1、运行期包与设计期包 (7)2、文件命名标准 (7)一、文件命名1、项目文件项目文件的名称应当具有描述意义。
例如:“The Delphi 5 Developer’s Guide Bug Manager”的项目名称为DDGBugs.dpr 一个系统信息程序的名称为SysInfo.dpr。
2、窗体文件窗体文件的名称应当表达出窗体的用途,且具Frm后缀。
例如:Student窗体的文件名叫StudentFrm.dfm,主窗体的文件名叫MainFrm.dfm。
3、数据模块文件数据模块文件的名称应当表达出数据模块的作用,且具有DM后缀。
例如:Student数据模块的文件名叫StudentDM.dfm。
4、远程数据模块文件远程数据模块文件的名称应当表达出远程数据模块的用途。
名称后要RDM后缀。
例如:远程数据模块的文件叫StudentRDM.dfm。
(1)单元名:单元的名称应当有描述性。
例如:应用程序的主窗体单元叫MainFrm.pas。
(2)Uses句子:Interface部分的Uses子句应当只包含该部分需要的单元。
不要包含可能由Delphi自动添加的单元名。
Implementation部分的Uses子句应当只包含该部分需要的单元,不要有多余的单元。
附录A 编码规范管理程序代码编写规范通常一个大型应用系统,都是由多人共同完成的。
在这种环境下如何实现相互之间的交流呢,这就要求同一个程序组的编程风格要基本一致。
这里,除了以上讲到的命令和界面要一致外,还包括程序代码的规范。
而程序代码的规范主要有以下几个方面的内容:一、代码及注释规范1.代码中所有保留字的大小写要一致,这里我们规定都用小写;2.注释要求:●单元的头注释中要求指明的项目如下示例:(******************************************************** 建立日期:年月日;* 作者:* 最近更新时间:******************************************************** 单元主要功能描述:********************************************************* 修改记录* =======* 修改日期:* 修改原因:* 修改简要情况:*******************************************************)●过程和函数注释中除了指明该过程或函数的功能外,在该过程或函数中的重要方法的语句的作用都要加注(显而易见的语句除外,当然这个度是靠每个人自己把握)。
●公用变量也要求被注释,以说明该变量的用途。
●被引用自制构件或第三方构件单元,要求与系统中的单元区分开,可另起一行,并在中间加入注释如:{ 以下为自制构件及第三方构件单元}●被引用的单元要求注释如,usesDataMod; { 数据模块 }3.变量申明位置要求:●全局变量要求在程序接口部分的var下面申明;●公用变量要求在public部分申明;●私有变量要求在private部分申明;●对于用作for循环的变量,如i、j、k等应该在使用该变量的过程或函数中去申明,不得在public、private以及程序接口部分的var下面申明;●只在一个过程或函数中使用的变量或方法,和用作for循环的变量一样,应在使用该变量的过程或函数中去申明。
Delphi 编码规范版本说明目录1.规范说明 (6)2.源代码编写格式 (7)2.1一般编写格式规则 (7)2.1.1缩进 (7)2.1.2空格 (7)2.1.3边距 (8)2.1.4注释 (9)2.2O BJECT P ASCAL语法书写格式规范 (10)2.2.1括号 (10)2.2.2保留字和关键字 (10)2.2.3变量与常量 (10)2.2.4begin...end. (13)2.2.5语句 (14)2.2.6类型 (20)2.2.7过程与函数 (21)2.2.8类 (23)3.控件 (26)3.1命名 (26)3.2常用控件简称 (26)3.2.1Standard页 (26)3.2.2Additional页 (26)3.2.3Win32页 (27)3.2.4System页 (28)3.2.5Data Access页 (28)3.2.6Data Control页 (28)3.2.7dbExpress页 (29)3.2.8BDE页 (29)3.2.10Internet页 (30)3.2.11FastNet页 (30)3.2.12Qreport页 (31)3.2.13Dialogs页 (31)3.2.14Win3.1页 (32)3.3自定义控件简称 (32)3.3.11stClass页 (32)3.3.2wing页 (33)4.文件 (34)4.1项目文件 (34)4.1.1项目开发目录结构 (34)4.1.2命名 (34)4.2窗体文件 (34)4.2.1命名 (34)4.2.2界面 (35)4.3数据模块文件 (36)4.3.1命名 (36)4.4远程数据模块文件 (36)4.4.1命名 (36)4.5单元文件 (37)4.5.1普通单元文件 (37)4.5.2窗体单元文件 (37)5.附录 (38)5.1修改规范 (38)5.1.1新增代码 (38)5.1.2删除代码 (38)5.1.3修改代码 (39)5.2编程规则 (39)5.2.2可读性要求 (40)5.2.3结构化要求 (40)5.2.4正确性与容错性要求 (41)5.2.5可重用性要求 (42)5.2.6程序效率要求 (42)5.3注释模版 (43)5.3.1项目注释 (43)5.3.2文件注释 (43)5.3.3函数与过程 (45)5.4部分常用单词缩写 (52)1.规范说明本规范主要规定Delphi源程序在书写过程中所应遵循的规则及注意事项。
[Delphi园地 ]第十一章 Delphi应用程序的应用(一)11.1 Help文件的建立Help文件是Micosoft Windows3.0以上的版本提供的超文本帮助文件。
利用这种超文本,用户可非常方便地使用帮助文件系统。
帮助文件是以主题为主线进行编写的,一个主题可以跳转至相关的主题,也可按关键字进行主题查询。
帮助文件与软件开发工具相结合,可实现应用程序的'上下文敏感',而且帮助系统自动装入。
“上下文敏感”是指根据程序当前执行代码来显示Help文件的相应部分。
Windows提供的很多应用程序都有帮助系统,读者可以从这些系统中了解应用程序的许多信息。
11.1.1 建立Help文件所需的工具和文件程序员可为自己的应用程序建立帮助文件系统。
但建立最基本的帮助系统, 必须有以下文件1. WinHelp 应用程序 ( WinHelp.exe) 。
运行帮助系统实际上是运行用帮助源文件的WindHelp程序。
帮助文件只有通过WinHelp文件才能运行。
2. 能创建主题的字处理器。
这种处理器能以RTF格式保存文件, 能创建$,#,K,+脚标。
RTF(Rich Text Format)格式是一个能记录各种文本特征的文件格式。
这些特征包括字体大小、线型风格等。
Microsoft Word 6.0处理器能满足以上要求。
3. 一个能以ASCII格式保存文件的字处理器或编辑器,这是为了创建Help工程文件(.HPJ文件)。
4. 帮助文件编译器(HCP.EXE或HC31.EXE),两种编译器均能编译在Windows3.1 环境中使用的帮助文件,但不能编译Windows3.0环境下的帮助文件。
HCP.EXE是保护模式的编译器,能更好地使用内存空间。
要在Windows的Dos窗口中使用HCP.EXE编译器。
5. 帮助编译器所需的错误信息源文件(HCP.ERR或HC31.ERR)。
如果帮助文件在编译过程中出现错误,WinHelp运行时将提示有关的错误信息,而这些信息保存在HCP.ERR或HC31.ERR文件中。
Delphi 开发指南——编码标准文档版权所有?1998 Xavier Pacheco 及Steve Teixeira翻译2000 李颖(e.w@)目录1.导言2.一般源代码格式规范缩进页宽Begin..End 对3.Object Pascal 语言3.1括号3.2保留字和关键字3.3过程和函数(子程序)3.4变量3.5语句if 语句case 语句while 语句for 语句repeat 语句with 语句3.6结构化的意外处理概要try..finally 的使用try..except 的使用try..except..else 的使用3.7类(Classes)域(Fields)方法(Methods)静态方法(Static Methods)的使用虚/动态方法(Virtual/Dynamic Methods)的使用抽象方法(Abstract Methods)的使用属性访问方法(Property AccessMethods)属性(Properties)命名规则访问方法的使用4文件工程(Project)文件窗体(Form)文件数据模块(Data Module)文件远程数据模块(Remote Data Module)文件单元(Unit)文件一般单元结构单元名称Uses 子句Interface 部分Implementation 部分Initialization 部分Finalization 部分窗体单元数据模块单元一般用途单元组件(Component)单元文件头5.窗体和数据模块窗体窗体类型命名标准窗体实例命名标准自动创建窗体模式化(Modal)窗体实例函数数据模块数据模块命名规则数据模块实例命名规则6.包(Packages)运行期(Runtime)和设计期(Design)包的使用文件命名规则7. 组件(Components)7.1用户自定义组件7.2组件单元7.3注册(Registration)单元的使用7.4组件实例命名约定7.5组件前缀Standard 页面Additional 页面Win32 页面System 页面Internet 页面Data Access 页面Data Controls 页面Decision Cube 页面QReport 页面Dialogs 页面Win31 页面Samples 页面ActiveX 页面Midas 页面导言本文档将描述Delphi 4 开发指南中使用的Delphi程序代码书写规范. 一般情况下, 本文档遵循Borland 公司"未明确说明"的编码格式规范, 少数情况下也有例外. 在Delphi 4 开发指南中包括本文档是为了向读者介绍一种在合作开发中保持代码风格一致的方法. 目的是为了保证开发队伍中的所有程序员都能够理解其他人编写的代码. 实现这一目的的方法是通过保持代码的一致性来增强其可性.本文档无法包罗万象, 因此可能对于你不够详细. 你可以使用并修改这些标准以适应你自己的需要. 但我们仍建议你不要与Borland 开发组使用的标准偏离得太多. 我们提出这些建议, 是因为当你的开发队伍中加入新程序员时, 他们最熟悉的很可能就是Borland 标准. 和大多数编码规范文档一样, 本文档将根据需要继续更新. 因此, 你可以在/ddg 在线得到最新版本. 本文档不会包括用户界面标准. 这是一个不同的但同样重要的主题. 大量的第三方书籍和Microsoft 文档都包括了这些指南, 因此我们决定不再重复这些信息, 而是将你指引到Microsoft Developers Network 和其他信息来源. .一般编码格式规范缩进缩进应该是每行2个空格. 不要在源文件中保存Tab字符. 在使用不同的源代码管理工具时Tab字符将因为用户设置的不同而扩展为不同的宽度.你可以禁止保存Tab字符, 方法是通过Tools | Environment 菜单打开Environment Options 对话框, 然后在Editor 页中关闭"Use tab character" 和"Optimal fill" 选项.页宽页宽应该设置为80字符. 源代码一般不会超过这个宽度, 并导致无法完整显示, 但这一设置也可以灵活调整. 在任何情况下, 超长的语句应该在一个逗号或者一个操作符后折行. 一条语句折行后, 应该比原来的语句再缩进2个字符.Begin..End 对begin 语句应该单独作为一行. 例如, 下面的第1行是错误的, 第2行是正确的:for I := 0 to 10 do begin // 错误, begin 和for 在同一行for I := 0 to 10 do // 正确, begin 单独作为一行begin当begin 作为else 子句的一部分时例外, 比如:if some statement = thenbegin...endelse beginSomeOtherStatement;end;end 语句永远单独作为一行.如果begin 语句不是else 子句的一部分, 相应的end 语句应该缩进到与begin 对齐的位置.Object Pascal 语言括号左括号和后一个字符之间不应该出现空格, 同样, 右括号和前一个字符之间也不应该出现空格. 下面的例子说明括号和空格的错误及正确使用:CallProc( AParameter ); // 错误CallProc(AParameter); // 正确不要在语句中使用无意义的括号. 括号只应该为达到某种目的而出现在源代码中. 下面的例子说明错误和正确的用法:if (I = 42) then // 错误- 括号毫无意义if (I = 42) or (J = 42) then // 正确- 的确需要括号保留字和关键字Object Pascal 语言保留字和关键字应该完全小写.过程和函数(子程序)命名规则子程序名应该以大写字母开头,而且应该易于阅读. 下面是一个正确格式的子程序名: procedure thisisapoorlyformattedroutinename;下面是一个首字母适当大写的子程序名:procedure ThisIsMuchMoreReadableRoutineName;子程序名应该具有与其用途相关的含义. 导致发生某动作的子程序应该以动词为前缀命名, 例如:procedure FormatHardDrive;为输入参数赋值的子程序应该以Set 为前缀命名,例如:procedure SetUserName;取回数值的子程序应该以Get 为前缀命名, 例如:function GetUserName: string;形参(Formal Parameters)格式在可能的情况下, 同类型的形参应该在一条语句中说明:procedure Foo(Param1, Param2, Param3: Integer; Param4: string);命名所有的形参名称应该具有与其用途相关的含义, 而且不应该基于传递到子程序的标识符名称. 适当情况下, 参数名应该以字符A 为前缀, 例如,procedure SomeProc(AUserName: string; AUserAge: integer);使用前缀"A" 是一种约定, 以便参数名与类的属性名、域名重复时消除歧义.参数顺序下面的形参顺序主要是为在寄存器模式下得到更高的性能, 寄存器模式是惯用的调用模式.调用者最常使用的参数应该在参数的最前位置, 使用越少的参数, 其位置应该越在右面.输入参数队列应该在输出参数队列的左面.最抽象参数应该在最精确参数的左面, 例如: SomeProc(APlanet, AContinent, ACountry, AState, ACity).参数顺序规则也可能出现例外情况, 比如事件响应程序(event handlers), 名为Sender 的TObject 类型参数通常作为第一个参数.常数参数(Constant Parameters)当记录, 数组, ShortString, 或接口(interface)类型参数在子程序中不被修改, 则相应的形参应该标识为Const. 这将确保编译器产生最高效的代码来传递这些不被修改的.其他类型的参数如果在子程序中不被修改, 也可以标识为Const. 虽然不能提高效率, 但至少为子程序的调用者提供了更多关于参数使用的信息.命名冲突如果引用的2个单元中包含同名子程序, 则实际调用的将是在uses 子句中位置最后的单元中的子程序. 为了避免这种与uses 子句相关的语意不明(uses-clause-dependent ambiguities), 应该用单元名作为前缀来指明所调用的子程序, 例如:SysUtils.FindClose(SR);或Windows.FindClose(Handle);变量变量命名和格式变量名称应该具有与其用途相关的含义.循环控制变量可以命名为单个字母, 比如I, J, 或K. 也可以是更有意义的名称, 比如UserIndex.Boolean 变量名称必须描述得足够详细, 保证其True 和False 取值具有清楚的含义. 局部变量在过程内使用的局部变量与其他变量一样, 遵循相同的用法和命名约定. 临时变量应该适当地命名.如果必要, 局部变量的初始化应该在子程序入口处立即进行. AnsiString 变量自动初始化为空字符串, interface 和dispinterface 类型变量自动初始化为nil, Variant 和OleVariant 类型变量自动初始化为Unassigned.全局变量的使用使用全局变量不是好习惯, 但也有可能必须使用全局变量. 如果是这样, 建议你尽量保持全部变量在它可用的范围内与上下文相关. 例如, 一个全局变量可能只在某个单元的implementation 部分可用.打算供几个单元公用的全局数据应该移到一个公用单元中.全局数据可以在var 部分用一个值立即初始化. 注意, 所有的全局数据初始状态下都自动归零, 因此不要将全局变量初始化为"空"值, 比如0, nil, '', Unassigned 等等. 全局数据自动归零的原因之一是因为初始状态为0的全局数据在exe 文件中不占据空间. 初始状态为0的数据将存储在一个"虚"数据段中, 这个数据库只在应用程序启动时从内存中分配. 初始状态非0的全局数据则必须在磁盘上的exe 文件中占据空间.类型大小写约定类型名称如果是保留字, 则必须完全小写. Win32 API 类型一般完全大写, 你应该遵循Windows.pas 和其他API 单元中某些类型名称的约定. 其他变量名称, 首字母应该大写, 其余部分也应该足够清楚. 下面是几个例子:varMyString: string; // 保留字WindowHandle: HWND; // Win32 API 类型I: Integer; // 在System 单元中引入的类型标识符浮点(Floating Point)类型使用Real 类型是不好的, 因为它仅仅是为了与旧的Pascal 代码保持向后兼容而保留的. 对于一般的浮点运算应该使用Double 类型. Double 是IEEE 定义的标准数据格式, 处理器指令以及系统总线都为处理Double 类型而进行过优化. Extended 类型应该只在需要比Double 更大的数据范围时使用. Extended 是Intel 指定类型, Java 不支持. Single 类型应该只在浮点变量本身占用的字节大小很重要的情况下使用, 比如使用其他语言编写的DLL 时.枚举(Enumerated)类型枚举类型名称应该具有与其用途相关的含义. 类型名称必须以字符T 为前缀, 表示是一个类型声明. 枚举类型的标识符序列必须以2到3个小写字符为前缀, 而且前缀必须与类型名有联系, 例如:TSongType = (stRock, stClassical, stCountry, stAlternative, stHeavyMetal, stRB);枚举类型的变量实例的名称应该与不带T 前缀的类型名称相同, 除非有其他原因需要更详细的名称, 比如FavoriteSongType1, FavoriteSongType2, 等等.Variant 和OleVariant一般来说使用Variant and OleVariant 类型是不好的, 但如果数据类型只能在运行时确定, 就必须使用这些类型了, 比如开发COM 和数据库程序时. OleVariant 常用于开发基于COM 的程序, 比如OLE 自动化和ActiveX 控件. Variant 则常用于非COM 程序. 原因是Variant 能(与字符串变量一样)更高效地存储Delphi 字符串, 但OleVariant 需要把所有的字符串转换为Ole Strings(WideChar Strings), 而且由于没有引用记数, 字符串将永远存在.结构类型数组类型数组类型名称应该具有与其用途相关的含义. 类型名必须以字符T 为前缀. 如果声明了指向该数组类型的指针类型, 则其名称必须以字符P 为前缀, 而且必须在数组类型的前一行位置进行声明, 例如:typePCycleArray = ^TCycleArray;TCycleArray = array[1..100] of integer;数组类型变量实例名称应该与不带字符T 前缀的类型名称相同.记录类型记录类型名称应该具有与其用途相关的含义. 类型名必须以字符T 为前缀. 如果声明了指向该记录类型的指针类型, 则其名称必须以字符P 为前缀, 而且必须在记录类型的前一行位置进行声明. 记录元素的声明应该对齐为一列, 例如:typePEmployee = ^TEmployee;TEmployee = recordEmployeeName: stringEmployeeRate: Double;end;语句if 语句if/then/else 语句中最可能被执行的部分应该放在then 子句中, 不太可能被执行的部分应该放在else 子句中.如果可能, 尽量不要使用一连串的if 语句, 而应该以case 语句替代.不要使if 语句嵌套超过5层以上, 尽量以更清楚的代码替代.不要在if 语句中使用无意义的括号.如果if 语句中需要检测多个条件, 则条件应该按照计算强度从小到大地排列. 这将使得你的代码执行的布尔计算更少, 性能更高. 例如, 如果Condition1 比Condition2 计算更快, Condition2 比Condition3 计算更快, 那么if 语句应该是如下结构:if Condition1 and Condition2 and Condition3 thencase 语句概要case 语句中的单个子句应该以case 常数的数字顺序或字母顺序排列. 子句中的执行语句应该尽量保持简单, 一般不要超过4到5行代码. 如果执行语句过于复杂, 应该将它放置在独立的过程或函数中.case 语句的else 子句应该只在正常的默认情况或检测到错误的情况下使用.格式case 语句遵循同样的缩进和命名约定.while 语句使用Exit 过程退出while 循环是不好的; 如果可能, 应该只使用循环条件来结束循环.while 循环的所有初始化代码应该紧贴在进入while 循环之前, 不要被其他无关语句分隔开.循环结束后的处理应该紧跟在循环之后.for 语句如果需要执行确定次数的增量循环, 应该用for 语句替代while 语句.repeat 语句repeat 语句与while 循环类似, 并遵循相同的规则.with 语句概要with 语句应该小心使用, 并有很多需要注意的地方. 不要过多地使用with 语句, 而且要小心with 语句中使用多个对象, 记录, 等等的情况. 例如:with Record1, Record2 do这样的代码可能会产生语意含糊, 并导致难以检测的bug.格式with 语句格式遵循同样的命名约定和缩排规则.结构化的意外处理概要意外处理在错误修正以及资源保护中都应该大量使用. 也就是说, 任何分配资源的情况, 都应该使用try..finally 以确保资源被正确释放. 在单元的initialization/finalization 中或在对象的constructor/destructor 中分配/释放资源的情况不在此列.try..finally 的使用任何可能的地方, 所有的资源分配代码都必须以try..finally 结构保护起来.例如, 下面的代码可能导致的bug:SomeClass1 := TSomeClass.CreateSomeClass2 := TSomeClass.Create;try{ do some code }finallySomeClass1.Free;SomeClass2.Free;end;更安全的做法应该是:SomeClass1 := TSomeClass.CreatetrySomeClass2 := TSomeClass.Create;try{ do some code }finallySomeClass2.Free;end;finallySomeClass1.Free;end;try..except 的使用try..except 应该只在你需要在产生意外时执行任务的情况下使用. 一般来说, 你不需要使用try..except 来简单地显示错误信息, 因为应用程序将通过Application 对象自动实现这一点. 在except 子句中, 如果你希望在执行过自己的任务后再调用缺省的意外处理程序, 应该使用raise 来再次产生这个意外.try..except..else 的使用在try..except 中使用else 子句是不好的, 因为它将阻塞所有的意外, 包括那些你没有准备处理的意外.类命名规则类的类型名称应该具有与其用途相关的含义, 类型名必须以字符T 为前缀, 表明这是一个类型定义, 例如:typeTCustomer = class(TObject)类的实例名称一般与不带T 前缀的类名称一样, 例如varCustomer: TCustomer;注意: 关于组件命名的更多信息, 请参见"组件类型命名标准" 部分.域命名规则类的域遵循与变量一样的命名约定, 除非以字符F 前缀表示是重要的域名称.可见度(Visibility)所有的域都应该是私有的(private). 可在类范围外访问的域应该通过属性来实现.方法命名规则类方法与过程和函数遵循相同的命名约定.静态方法的使用如果你不希望方法在派生类中被重载(override), 应该使用静态方法.虚/动态方法的使用如果你希望方法在子类中被重载, 应该使用虚方法方法. 动态方法应该只在存在大量(直接和非直接)派生类的类中使用. 例如, 一个类中包含一个很少被重载的方法, 但这个类有100个派生类, 则应该将这个方法设置为动态方法, 以减少这100个派生类消耗的内存.抽象方法的使用不要在会创建实例的类中使用抽象方法. 抽象方法应该只在不会创建实例的基类(base classes)中使用.属性存取方法所有的属性存取方法应该出现在类定义的私有或保护部分.属性存取方法遵循与过程和函数相同的命名约定. 取值方法必须以单词Get 为前缀, 赋值方法必须以单词Set 为前缀, 赋值方法参数必须命名为Value, 类型应该与属性描述的一致, 例如:TSomeClass = class(TObject)privateFSomeField: Integer;protectedfunction GetSomeField: Integer;procedure SetSomeField( Value: Integer);publicproperty SomeField: Integer read GetSomeField write SetSomeField;end;属性命名规则用于存取私有域的属性应该与相应的域名称系统, 但没有F 前缀.属性名应该是名词, 而不是动词. 属性表示数据, 方法则表示动作.数组属性名应该是复数形式. 普通属性名应该是单数形式.存取方法的使用尽管不是必要的, 我们仍然建议你为访问私有域的属性最少建立一个的赋值方法.文件工程文件工程文件名称应该具有描述性. 例如, The Delphi 4 Developer's Guide Bug Manager 的工程命名为: DDGBugs.dpr. 一个系统信息程序命名为SysInfo.dpr.窗体文件命名窗体文件名称应该具有描述性, 并与其用途相关. 名称应该带有Frm 后缀. 例如, About 窗体的文件名为AboutFrm.dpr. Main 窗体的文件名为MainFrm.dpr.数据模块文件命名数据模块名称应该具有描述性, 并与其用途相关. 名称应该带有DM 后缀. 例如, Customers 数据模块的文件名为CustomersDM.dfm.远程数据模块文件命名远程数据模块名称应该具有描述性, 并与其用途相关. 名称应该带有RDM 后缀.例如, Customers 远程数据模块的文件名为CustomersRDM.dfm.单元文件一般单元结构单元名称单元文件名称应该带描述性. 例如, 包含应用程序主窗体的单元应该命名为MainFrm.pas.Uses 子句interface 部分的uses 子句应该只包括interface 部分中代码需要的单元. Delphi 自动加入的无关的单元名应该删除.implementation 部分的uses 子句应该只包括implementation 部分中代码需要的单元. 无关的单元名应该删除.Interface 部分Interface 部分应该只包括可被外部单元访问的类型声明, 变量声明, 过程/函数的预先声明, 等等. 其他内容应该在implementation 部分.Implementation 部分Implementation 部分应该包括类型本单元私有的类型声明, 变量声明, 过程/函数.Initialization 部分不要将耗费大量时间的代码放在单元的initialization 部分. 这将导致应用程序启动缓慢.Finalization 部分确保你释放了在Initialization 部分分配的全部项目.窗体单元命名窗体的单元文件名应该与窗体文件名相同. 例如, About 窗体的单元文件名为AboutFrm.pas. Main 窗体的单元文件名为MainFrm.pas.数据模块单元命名数据模块的单元文件名应该与数据模块的文件名相同. 例如, Customers 数据模块的单元文件名为CustomersDM.pas.一般用途单元命名一般用途单元名称应该具有含义, 并与其用途相关. 例如, 一个实用程序单元命名为BugUtilities.pas. 一个包含全局变量的单元命名为CustomerGlobals.pas.记住, 单元名在工程使用的所有包内应该是唯一的. 因此建议你不要使用过于抽象或普通的单元名.组件单元命名组件单元应该保存在单独的目录下, 以便将它们作为用户自定义组件和组件包区分开. 绝对不要与工程保存在相同的目录下. 单元名应该能表示其内容.注意: 关于组件命名标准的更详细信息, 请参见"用户自定义组件"部分.文件头建议在所有的源文件, 工程文件, 单元文件等等中使用包含信息的文件头. 正确的文件头应该包括以下信息:{Copyright ?YEAR by AUTHORS}窗体和数据模块窗体窗体类型命名标准窗体类型名称应该描述其用途. 类型定义应该以字符T 为前缀, 描述性的名称跟随在前缀之后. 最后, Form 作为后缀跟在描述性的名称之后. 例如, About 窗体的类型名称应该是:TAboutForm = class(TForm)Main 窗体的定义应该是TMainForm = class(TForm)客户登记窗体的名称类似于TCustomerEntryForm = class(TForm)窗体实例命名标准窗体实例应该命名为与类名一致, 但不带T 前缀. 例如, 上述窗体类型, 其实例名称如下:Type Name Instance NameTAboutForm AboutFormTMainForm MainFormTCustomerEntryForm CustomerEntryForm自动创建窗体除非有其他更好的理由, 否则应该只有主窗体是自动创建的. 其他所有窗体应该从Project Options 对话框的Auto-Create Forms 列表中删除. 详情请阅读下面的部分.模式化(Modal)窗体实例函数所有的窗体单元应该包含一个窗体实例化函数, 这个函数将创建, 设置, 模式化显示, 释放窗体, 并返回窗体模式化(modal result)结果. 传递给该函数的参数遵循本文档规定的"参数传递"标准. 使用这样的函数的目的是为了封装窗体的使用, 使得代码更易于重用和维护.窗体变量应该从单元中删除, 并在函数中声明为局部变量. 注意, 这需要先将窗体从Project Options 对话框的Auto-Create Forms 列表中删除参见本文档的"自动创建窗体"部分.例如, 下面的单元说明了为GetUserData 窗体编写的一个这样的函数.unit UserDataFrm;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls;typeTUserDataForm = class(TForm)edtUserName: TEdit;edtUserID: TEdit;private{ Private declarations }public{ Public declarations }end;function GetUserData(var aUserName: String; var aUserID: Integer): Wor d;implementation{$R *.DFM}function GetUserData(var aUserName: String; var aUserID: Integer): Wor d;varUserDataForm: TUserDataForm;beginUserDataForm := TUserDataForm.Create(Application);tryUserDataForm.Caption := 'Getting User Data';Result := UserDataForm.ShowModal;if ( Result = mrOK ) thenbeginaUserName := UserDataForm.edtUserName.Text;aUserID := StrToInt(UserDataForm.edtUserID.Text);end;finallyUserDataForm.Free;end;end;end.数据模块数据模块命名标准DataModule 类型名称应该描述其用途. 类型定义应该以字符T 为前缀, 描述性的名称跟随在前缀之后. 最后, DataModule 作为后缀跟在描述性的名称之后. 例如, Customer 数据模块的类型名称类似于:TCustomerDataModule = class(TDataModule)Orders 数据模块的类型名称类似于TOrdersDataModule = class(TDataModule)数据模块实例命名标准数据模块实例名称应该与类型名称一致, 但不带T 前缀. 例如, 上述数据模块类型, 其实例名称如下:Type Name Instance NameTCustomerDataModule CustomerDataModuleTOrdersDataModule OrdersDataModule包运行期和设计期包的使用运行期包只包含包内其他组件需要的单元和组件. 包含属性/组件编辑器和其他设计期间代码的单元应该放置在设计期包内. 注册单元应该放在设计期包内.文件命名标准包应该按照以下模式命名:"iiilibvv.pkg" - 设计期包"iiistdvv.pkg" - 运行期包其中"iii" 表示以3个字符作为前缀. 这个前缀可以用来标识公司, 个人, 或其他信息."vv" 表示包所适用的Delphi 版本.注意包名称中包含"lib" 或"std", 是为了标识这是运行期包还是设计期包.当既有设计期包又有运行期包时, 文件名应该类似. 例如, Delphi 4 开发指南的包命名为: DdgLib40.pkg - 设计期包DdgStd40.pkg - 运行期包组件用户自定义组件组件类型命名标准组件命名与类命名类似, 不同的是组件名带有3个字符的前缀. 这个前缀用来标识公司, 个人, 或其他信息. 例如, Delphi 4 开发指南编写的一个时钟组件定义为:TddgClock = class(TComponent)注意前缀字符为小写.组件单元组件单元应该只包含一个主组件. 主组件是指出现在组件板(Component Palette)上的组件. 主组件的其他辅助性的组件/对象也在相同的单元内.注册单元的使用组件的注册过程应该从组件单元中删除, 而放置在单独的注册单元中. 这个注册单元将注册所有的组件, 属性编辑器, 组件编辑器, 专家(experts)等等.组件的注册动作只在设计期包内进行, 因此注册单元应该只包含在设计期包内, 而不在运行期包内.建议注册单元命名为: XxxReg.pas其中"Xxx" 是3字符前缀, 用来标识公司, 个人, 或其他信息. 例如, Delphi 4 开发指南中的组件注册单元命名为DdgReg.pas.组件实例命名约定所有的组件名称都应该是描述性的. 不应该有组件使用Delphi 缺省赋给的名称. 组件名称应该包括一个小写前缀, 以指明其类型. 使用前缀而不是使用后缀的原因之一是在Object Inspector 和Code Explorer 中可以更容易地按名称查找组件.组件前缀以下前缀赋给Delphi 附带的标准组件. 如果安装了第三方组件, 请增加这份列表.。
Delphi编写标准指南一、序言二、通用源代码格式规则2.1 缩格2.2 页边空格2.3 Begin...End 配对三、Object Pascal3.1 括号3.2 保留字和关键字3.3 过程和函数(例程)3.3.1 命名/格式化3.3.2 形式参数3.3.2.1 格式化3.3.2.2 命名3.3.2.3 参数的排序3.3.2.4 常量参数3.3.2.5 名称的冲突3.4 变量3.4.1 变量的命名和格式3.4.2 局部变量3.4.3 全局变量的使用3.5 类型3.5.1 大写约定3.5.1.1 浮点指针类型3.5.1.2 枚举类型3.5.1.3 变数和ole变数类型3.5.2 结构类型3.5.2.1 数组类型3.5.2.2 记录类型3.6 语句3.6.1 if 语句3.6.2 case 语句3.6.2.1 一般性话题3.6.2.2 格式3.6.3 while 语句3.6.4 for 语句3.6.5 repeat 语句3.6.6 with 语句3.6.6.1 一般话题3.6.6.2 格式3.7 结构异常处理3.7.1 一般话题3.7.2 try...finally的使用3.7.3 try...except的使用3.7.4 try...except...else的使用3.8 类类型3.8.1 命名和格式3.8.2 域3.8.2.1 命名/格式3.8.2.2 可视化3.8.3 方法3.8.3.1 命名/格式3.8.3.2 使用静态的方法3.8.3.3 使用虚拟/动态的方法3.8.3.4 使用抽象的方法3.8.3.5 属性存取方法3.8.4 属性3.8.4.1 命名/格式3.8.4.2 使用存取的方法四、文件4.1 工程文件4.1.1 命名4.2 窗体文件4.2.1 命名4.3 数据模板文件4.3.1 命名4.4 远端数据模板文件4.4.1 命名4.5 Unit文件4.5.1 通用Unit结构4.5.1.1 unit的名字4.5.1.2 uses子句4.5.1.3 interface部分4.5.1.4 implementation部分4.5.1.5 initialization部分4.5.1.6 finalization部分4.5.2 窗体单元4.5.2.1 命名4.5.3 数据模板单元4.5.3.1 命名4.5.4 一般目的单元4.5.4.1 命名4.5.5 构件单元4.5.5.1 命名4.6 文件头五、窗体和数据模板5.1 窗体5.1.1 窗体类型命名标准5.1.2 窗体实例命名标准5.1.3 自动创建窗体5.1.4 模式窗体实例化函数5.2 数据模板5.2.1 数据模板命名标准5.2.2 数据模板实例命名标准六、包6.1 使用运行包和设计包的比较6.2 文件命名标准七、构件7.1 用户自定义构件7.2 构件单元7.3 使用注册单元7.4 构件实例命名约定7.5 构件的前缀7.6 Standard页7.7 Additional页7.8 Win32页7.9 System页7.10 Internet页7.11 Data Access页7.12 Data Controls页7.13 Decision Cube页7.14 QReport页7.15 Dialogs页7.16 Win3.1页7.17 Samples页7.18 ActiveX页7.19 Midas页一、序言本文档详述了在Delphi 4开发者指南下进行编程的代码编写标准。
Delphi_组件使用和代码Delphi组件使用及其代码i. 数组定义(1) 一维数组数组名:array [n1 ..n2] of数据类型;(2)二维数组数组名:array [n1 ..n2,m1 . . m2] of 数据类型;或者数组名:array [n1 ..n2] of array[m1 m2] of 数据类型;(3)动态数组数组名:array of 数据类型;使用前要用SetLength (数组名,数组长度);来动态申请空间2. 使用math数学函数:需要在uses引用里面添加math;其中power(a,b)函数是求a的b次幕。
RandomRange(a,b)函数是随机产生一个a、b之间的数。
3. 声明全局变量需要在implementation 之后声明;初始化格式需要在最后一个end之后:语句:initialization赋值语句;4. 常量在var后使用con st关键字声明常量:如const PI = 3.145. 枚举类型使用声明:type枚举类型名=(枚举值1 ,枚举值2, ....................... );定义:var变量名:枚举类型名;6?指针类型(1)@运算符:放在变量的前面,获得变量的地址;A运算符:放在指针变量的后面,取得该指针变量中所存放地址变量的数据;(2)声明:type指针类型名=A数据类型;var指针变量名:指针类型名;或者var 指针变量名:A数据类型;7. 日期时间函数function Now : TDateTime ;//返回系统当前日期和时间function Date : TDateTime ;// 返回系统当前日期function Time : TDateTime ;// 返回系统当前时间function DateTimeT oStr ( DateTime : TDateTime) : string ;// 将日期时间数据转换为字符串function StrT oDateTime ( const s : string) : TDateTime ;// 将字符串转换为日期时间数据function DateToStr ( DateTime : TDateTime) : string ;// 将日期数据转换为字符串function TimeT oStr ( DateTime : TDateTime) : string ;// 将时间数据转换为字符串function FormatDateTime ( const Format : string ;DateTime : TDateTime ) : string ;//按指定格式输出日期时间例女口: formatDatetime ( yyyy-mm-dd :now);formatDatetime ( hh:mm:ss :now);8. 自定义过程(1)在type下声明:procedure < 过程名>(< 参数列表>);(2)将光标移动定位在过程声明中,按Ctrl+Shift+C ,实现自动生成部分过程框架procedu re <过程名>(<参数列表>)<局部变量声明>;begin<过程体语句>;end ;(3)自定义过程的调用:过程名(<实参表>);9. 自定义函数(1)函数不用声明;(2)functionv函数名>[(<参数列表>)]: <返回类型>;<局部变量声明>;begin<函数语句>;end ;(3)自定义函数的调用:函数名(实参表);10. 对话框函数MessageDIg(1)<变量>:=MessageDlg (信息内容',类型,[按钮组],HelpCex);(2)类型:mtWarning 含有感叹号符号的警告对话框mtError 含有红色差号符号的错误对话框mtInformation 含有蓝色i符号的信息对话框mtConfirmation 含有蓝色?符号的确认对话框mtCustom 不含图标的一般对话框,对话框的标题是程序的名称按钮组:mbYes Yes按钮,函数返回mrYes或6mbNo No按钮,函数返回mrNo或7mbOk Ok按钮,函数返回mrOk或1mbCa ncel Cancel按钮,函数返回mrCancel或2mbHelp Help按钮mbAbort Abort按钮,函数返回mrAbort或3mbRetry Retry按钮,函数返回mrRetry 或4mbIg nore Ignore按钮,函数返回mrlgnore 或5mbAII All按钮,函数返回mrAII或8mbNoToAII NoToAII按钮,函数返回mrNoT oAll或9mbYesToAII YesToAII 按钮,函数返回mrYesToAII 或10 HelpCtx 指定当用户单击HeIp ”按钮或<F1>键时,现实的帮助主题。
Delphi源程序代码规范V1.0鼎创公司2005-8-13I. 总则1.1 目的为了对程序员的开发进行适当的规范化,特制定本规范。
其根本目的,是为了保证程序具有良好的、一致的结构,以期提高程序的可读性及可维护性,方便程序的测试、维护、升级等工作,同时,也培养程序员书写代码的规范性。
1.2 原则名称反映含义,形式反映结构;1.3 申明本规范适用于采用DELPHI作开发工具的公司所有项目,程序员应严格按照本规范编写代码,如项目有确实需要的特殊要求,也必须经项目经理审核后,把该特殊要求形成文档当作本文档的随附文件一起保存。
1.4 文档编写: XXX 2001年6月23日第一次修改:XXX 2001年7月7日第二次修改:XXX 2001年9月28日II.代码规范2.1 项目规范2.1.1.每一个项目的代码、文档按模块、功能必须在项目文件夹中有条理的归类存放,每个项目文件夹中均必须包含以下子文件夹:Code:源代码目录Sql:数据库脚本目录Demodata:演示数据目录Userdata:用户数据目录Help:帮助文档目录Install:安装文件目录Document:文档目录Picture:图片目录templates:报表模板目录子文件夹下也必须依照详细的用途分类建立子目录。
详细的示例如下:示例:Project Name|code sql demodata Picture help install document templates| |appserver client || 测试文档设计文档数据字典需求分析用户文档module1 module2 module3 ……2.1.2.每个项目的主目录下均必须有一个项目说明文件,说明该项目的一些概要性提示和相关规范。
2.1.3.在项目文件夹下的每层每个子目录中必须有一个文件夹说明文件,说明该层文件夹及其子文件夹的分类方法和含义。
任何时候,新增一个文件夹时,均必须在同层目录下的文件夹说明文件中添加所新增文件夹的分类含义,同时创建该文件夹下的文件夹说明文件。
delphi反编译:DELPHI定义的条件编译介绍说明疯狂代码 / ĵ:http://Delphi/Article66671.html经常看到些里面用到如:{$def win16},{$def win32}的类信息可是这些好像并没有定义不知道在哪里可以找到这些条件编译定义或者是介绍说明具体讲述win16代表什么WIN32代表什么VER140代表什么?{$IFDEF WIN32} — 这可不是批注对于Delphi来说﹐左右大括号的间内容是批注﹐然而「{$」(左括号后紧接着货币符号)对于Compiler(编译器)而言并不是批注﹐而是写给Compiler看特别指示应用时机和场合Delphi中有许许多多Compiler Directives(编译器指令)﹐这些编译指令对于我们发展有何影响呢? 它们又能帮我们什么忙呢?Compiler Directive 对开发影响和助益, 可以从以下几个方向来讨论:?协助除错? 版本分类?重用和管理? 设定统执行环境协助除错稳健熟练设计师经常会在开发应用系统过程中﹐特别加入些除错或者回馈验算﹐这些除错对于软件Software品质提升有极其正面功能然而开发完成正式版本中如果不需要这些额外话﹐要想在堆中找出哪些是除错用并加以删除或设定为批注﹐不仅累人﹐而且容易出错﹐况且日后维护时这些除错还用得着此时如果能够应用像是$IFDEFCompiler Directives ﹐就可以轻易指示Delphi要/不要将某段编进执行文件中同时﹐Compiler本身也提供了些检查开关﹐可以预先对中可能问题提醒设计师注意﹐同样有助于撰写正确版本分类除了上述除错版本/正式版本分类的外﹐对于像是「试用版」「普及版」「专业版」版本分类﹐也可以经由Compiler Directive使用﹐为最后产品设定区别使用权限其它诸如「中文版」「日文版」「国际标准版」等全球版本管理方面﹐同样也可以视需要指示Delphi特别连结哪些资源档或者是采用哪些适当以上两则例子中﹐各版本间只需共享同份代码即可Delphi 1.0 和 Delphi 2.0有许多区别的处﹐组件资源文件(.DCR)即是其中例﹐两者档案格式并不兼容﹐在您读过本文的后﹐相信可以写出这样﹐指示Delphi在区别版本采用适当资源文件以利于组件安装{$IFDEF WIN32}{$R XXX32.DCR}{$ELSE}{$R XXXX16.DCR}{$EDNIF}重用和管理经过前文讨论后﹐相信你已经不难看出Compiler Directives在管理上应用价值对于原始重用和管理﹐也是Compiler Directives 使得上力地方. 举例来说: Pascal-Style串是Delphi 1.0和 Delphi 2.0的间明显差异﹐除了原先短串的外﹐Delphi 2.0的后还多了更为方便使用长串﹐同时﹐系统也额外提供了像是 Trim这样串处理函式假如您有个串处理单元必须要同时应用于Delphi 1.0 和2.0项目时﹐编译指示器可以帮你忙此外﹐透过像是{$I xxxx} 这样 Compiler Directives﹐我们也可以适当含入某些, 同样有助于切割组合我们或编译设定设定致执行环境项目小组成员间﹐必须有共同环境设定﹐我很难预料个小组成员间彼此有区别{$B}{$H}{$X}设定﹐最后子系统在并入主时会发生什么事此外, 当您写好个组件或单元需要交予第 3者使用时, 使用编译指示器也可以保证元件使用者和您有相同编译环境使用Compiler Directives指令语法Compiler Directives从外表看起来和批注颇为类似, 和批注区别是:Compiler Directives语法格式都是以「{$」开始, 不空格紧接个名称(或个字母)表明给Compiler特别指示, 再加上其它开关或参数内容, 最后以右大括号作为指令结束, 例如:{$B+}{$R-}{$R MyCursor.res}同时, 就如同Pascal变量名称和保留字样, Compiler Directives也是不区分大小写从指令语法格式来说Compiler Directives﹐可以进步分类成以下 3种格式:?开关指令(Switch directives)这类指令都是单字母以不空格方式连接「+」或「-」符号; 或者是开关名称以个空格后连接「ON」或「OFF」来表示作用/关闭某个编译指示开关例如:{$A+}{$ALIGN _disibledevent=>Re(F);CloseFile(F);{$I+}FileExists := (IOResult = 0) and (FileName <> ‘’);end; { FileExists }可移植性我们都可能会用到其它公司或个人创作unit或component, 也可能分享给其它人, 换句话说, 单元或可能会在区别机器上编译, 直接将Compiler directives加入, 不仅可以免去使用前需要特别更改IDE麻烦, 更重要是解决了各个单元间要求区别编译环境歧异注意事项Compiler directives作用和影响范围如同变量可见范围和生命周期, 在我们使用 Compiler Directives 时也必须注意各个Compiler Directives 作用范围.Compiler Directives作用范围可分为以下两种:全域全域Compiler Directives, 影响所及是整个项目; 我们稍早前提到经由Delphi IDE改变Compiler directives方式就属于全域设定区域而区域Compiler Directives 影响所及只从Compiler Directives 改变那行开始, 直到该单元(Unit)结束或另个相同Compiler Directives 为止,对其他单元并没有影响也就是说, 如果在unit中特别加入Compiler directives, Compiler会优先采用区域设定, 然后才是属于项目层级全域设定值得提是, 在中直接加入Compiler directives最大作用范围也只限于当时那个单元而已, 对其他单元并没有任何影响, 即使是以uses参考也是样也就是说,我们可以透过uses参考其它unit公开变量和函式, 但是各个unit编译指令并不会互相参考这项独立性质, 使得unit的间编译环境设定和关系变得十分简洁, 例如Delphi 2.0VCL都是在{$H+}情况下编译,因此, VCL中串都是以长串型态编译而成, 有了这项编译指令独立特性, 不论我们Prject中设定为何, 这些在VCL中定义过串都是长串我们Project也不会uses了VCL中unit而改变了自己设定因此, 在我们移交到网络上时, 大可以放心在中加入必要Compiler directives, 别担心, 即使别unit以uses参考了我们, 也不影响它自己原来设定如果我们自行以{$DEFINE _DEBUGVERSION}($DEFINE在稍后个别指令介绍中将有介绍说明)定义了个条件符号, 这个新条件符号也是区域, 换句话说, 它只从定义那个单元那列的后才成立, 当然, 也只对目前这个单元有效. 由于自订条件符号只有区域作用, 如果有好几个单元都需要参考到某个条件符号, 如何办呢? 嗯! 在每个单元开头处中都加上编译指示是最直接方式,可是略嫌麻烦, 特别是编译指示有变时, 要修正各个单元设定内容, 很容易疏忽而出错比较简易可行作法是从Delphi IDE整合发展环境主选单-Project / Options / Directories/ConditionalConditionals 中填入条件名称这样, 相对于项目各个unit而言, 就有了个全域条件符号 或者, 您也可以参考本文对于{$I}这个Compiler Directive介绍说明我在那里指出了另个弹性解决方式修改过编译指令后, 建议BuildAll过次请试试这个:procedure TForm1.Button1Click(Sender: TObject);begin// opt是用来侦测某个编译开关作用状态{$opt H+}ShowMessage(’H+’);{$}ShowMessage(’H-’);{$end}end;在我们执行上述时, 在Delphi预设是$H+时, ShowMessage会在画面上会显示「H+」, 执行过后, 让和form内容和位置保留不变, 单纯从主选单: Project/Options/Compiler, 将Huge Strings核对方块清除($H-),然后按下F9执行, 咦! 如何还是看到「H+」?!那是Delphi只会在unit内容经过异动后才会重新将.PAS编译成.DCU, 在我们例子中, 并没有变动, .DCU当然也没有重新产生, 最后.EXE这个部分自然也是没什么变化所以, 要解决这个问题,只要以Delphi IDE主选单Project/Build All指示Delphi重新编译全部即可因此, 如果您从Delphi IDE修改过Compiler Directives后, 记得要Build All喔!不应该用来作为执行流程控制在中, 我们可以使用叙述, 根据执行当时情况控制执行时流程, 但我们不可以用{$IFDEF}来作同样事, 为什么? 从上述介绍说明, 相信您不难发现, Compiler directives会对最后.EXE内容发生直接影响, 应用像是{$IFDEF}指示Compiler结果, 几乎可以视同授权Compiler在编译那个时候自动选用/舍弃到.DCU, .EXE中, 换句话说, 在编译完成时, 会执行到那段已成定局了,我们自然不能用它来作流程控制条件编译巢套最多可以16层在使用{$IFDEF}…{$ENDIF}条件编译我们时, 个{$IFDEF}中可以再包含另个{$IFDEF}, 但深度最多只能16层, 虽然是个限制, 但以正常情形来说, 这应该已经足够了有些Compiler directives不应写在Unit中对于像是{$MINSTACKSIZE}{$MAXSTACKSIZE}管理堆栈大小, 或者像是{$APPTYE}指示编译成图形/文字模式Compiler directives, 只能写在.DPR中, 写在Unit中是没有效果建议事项确定您了解指令影响由于编译指令影响是如此直接和深远, 在修改和应用某个Compiler directive时,请确定您已经了解其含意和影响打开全部侦错开关Delphi有关侦错Compiler directives如下:? $HINTS _disibledevent=>ByteField: ;IntegerField: eger;end;…procedure TForm1.Button1Click(Sender: TObject);beginShowMessage(IntToStr(SizeOf(MyRecord)));end;ShowMessage在{$A+}时显示结果是:「8」; 倘若是{$A-}, 那所得结果是「5」,按理说, Byte应该只要个就足够了, 但是考虑到硬件执行特性, 经过对齐后record会有比较好执行速度有关这个Compiler Directive要注意事项是: 不管{$A}开关是ON或OFF, 使用packed修饰过记录宣告, 是定不会对齐. 例如:MyRecord = packed record // 不会对齐记录宣告方式{$APPTYPE GDI} 应用型态般情形下, Delphi会以{$APPTYPE GUI}方式产生个图形使用者接口, 如果您需要产生个文字屏幕模式, 那可以经由:在.DPR中加入{$APPTYPE CONSOLE}从主选单: Project/Options/Linker/EXE and DLL Options, 核取「Generate Console Application」Check Box其它有关这个Compiler Directive注意事项有:$APPTYPE不能应用在DLL项目或单单元(Unit), 它只对.EXE有意义而且只有写在.DPR中才有作用我们可以应用单元中IsConsole在执行时侦测应用类型参阅Object Pascal手册第十 3章可以知道更多有关Console Mode Application信息{$B-} 布尔评估请看以下:(Length(sCheckedDateString) <>or EmptyStr(sCheckedDateString)or (sCheckedDateString = ‘ . . ‘)or (sCheckedDateString = ‘ / / ‘) thenbeginResult := True;Exit;end;假如sCheckedDateString串内容是「85/12/241」(长度9)话, 以上述句, 其实在第个逻辑判断时就已经知道结果了, 即使不看后来逻辑运算结果也知道整个式子会是真值假如您希望对整个逻辑表达式进行完整评估 — 尽管结果已知, 后来逻辑运算也不影响整个结果时仍要全部评估过, 请将这个Compiler directives设为{$B+}, 反的, 请设为{$B-}, 系统默认值是{$B-}{$D+} 除错信息当以{$D+}(默认值)编译时, 我们可以用Delphi整合发展境境Debugger设定断点, 也可以使用Trace Into或Trace Info追踪执行过程, 值得注意是, 以{$D+}编译, 执行速度并不会受到影响, 只不过编译过DCU档案长度会加大, 但EXE档大小不变{$DEFINE条件名称} 定义条件名称随着您对Compiler Directives了解和应用程度加深, 您会发现这是个非常实 用编译指示经常, 我们会除错需要﹑区别区别版本等缘故, 希望选择性采用或排除某段, 这个时候, 我们就可以先以$DEFINE定义好个条件名称(Conditional name),然后配合{$IFDEF条件名称}…{$ELSE}…{$ENDIF}指示编译器按指定条件名称的有无来选择需要编译以下列片断来说:{$DEFINE _ProVersion}…procedure TForm1.Button1Click(Sender: TObject);begin{$IFDEF _Proversion}frmPr.ShowModal; // A{$ELSE}ShowMessage(’很抱歉, 试用版不提供打印功能’);{$ENDIF}end;编译器将会选择编译上述A那列, 日后, 如果我们需要编译「简易版」版本时, 只要将{$DEFINE _ProVersion}那列整个删掉或者, 将{$DEFINE _ProVersion}改成{-$DEFINE _ProVersion},让它变成普通批注或者, 在{$DEFINE _ProVersion}下列加上{$UNDEF _ProVersion},解除_ProVersion这个条件名称定义这样, 由于_ProVersion这个条件名称未定义缘故, Compiler就只会选择{$ELSE}下那段, 重新编译次, 不需费太多力气, 很容易就可以制作出简易版」了, 省去了要同时维护两份麻烦使用$DEFINE时其它注意事项如下:以{$DEFINE}定义条件名称都是区域换句话说, 它作用范围只在当时所在单元才有效, 即使定义在uniterface, 由其它unit以uses参考也没有效,仍然只有在目前unit有作用此外, 它作用范围是从定义起, 到unit结尾或者以{$UNDEF}解除为止如果单元中已经用{$DEFINE}定义了个条件名称, 而且也没有用{$UNDEF}解除定义, 重新{$DEFINE}个同样名称并没有作用, 换句话说, 它们是同个.假如需要个全域条件名称, 您可以:主选单: Project / Options / Directories/Conditional Conditionals 中填入条件名称以下标准条件名称, 是Delphi 2.0已经预先预备好, 我们可以直接引用,同时, 它们都是全域, 任何Unit都可以参照得到VER90: Delphi Object Pascal版本编号90表示9.0版, 日后若出现9.5版时, 也会有VER95定义 WIN32: 指出目前是在Win32(95, NT)作业环境? CUP386: 采用386(含)以上CPU时, 系统会提供本条件名称? CONSOLE: 此符号会于应用是在屏幕模式下编译时才定义{$DESCRIPTION 描述内容}应用{$DESCRIPTION}可以指定加入段文字到.EXE或.DLL表头模块描述进入点(module description entry)中﹐通常我们会用这个Compiler Directive加入应用名称和版本编号到.EXE中例如:{$DESCRIPTION Dchat Version 1.0}{$X+} 扩充语法这是为了和的前Pascal版本前向兼容编译指令, 虽然设定这个开关型指令仍有作用, 但笔者建议您大可保留系统默认值{$X+}, 在{$X+}下:? 不需要非得准备个变量接受传回值, 换句话说, 传回值可以舍弃, 此时, 就可以像是呼叫样, 很方便呼叫? 支持Pchar型态和零基作为C语言以Null结尾串{$HINTS OFF} 提示讯息打关{$HINTS}开关后, Compiler会提示设计师注意以下情况:? 变量定义了却没有使用? 流程中不会执行for或while循环? 只有存入没有取用指定叙述意思是说, 指定数据到某个变量的后,却没有任何参考取用这个变量值{$HINTS _disibledevent=>varI, J: eger;begin_False thenfor I := 1 to 3 do ;J := 3;end;{$HINTS OFF}由于简单, 在两个$HINTS中间, 我们不难看出:? for循环不会执行到, I变量也因此不曾用过? J := 3写了等于白写但在越写越长而日趋复雓时, 藉由{$HINTS _disibledevent=>举例来说, 笔者有份由Keypro厂商提供.OBJ檔, 在使用时, 相关如下:…{$L hasptpw.obj}{$F+}procedure hasp (Service, SeedCode, LptNum, Pass1, Pass2 : word;var p1,p2,p3,p4 : word); external;{$F-}…经过{$L hasptpw.obj}宣告的后, 其它部分就可以直接呼叫原先位于 hasptpw.obj 中hsap这个了{$L+} 区域符号信息在{$L+}时, Delphi会额外加入些区域符号信息, 这使得我们可以应用Delphi IDE中 View/Call Stack, View/Watch在执行时检视变量内容和函式呼叫关系应用这个Compiler directive注意事项有:? {$D-}时, {$L+}不会有作用? 使用{$L+}, 只会加大.DCU档案大小, 对.EXE大小和执行速度并没有影响{$H+} 长串宣告Delphi 2.0的后, 串多了个更为好用长串, 不仅没有资料长度255限制,和C语言惯用Null-terminated 兼容性也大为提高使用{$H}时注意事项有:? {$H+}编译情形下, 以定义串变量都是长串, 请注意,串是否为长串是在串定义时决定, 例如:procedure TForm1.Button1Click(Sender: TObject);{$H-}vars: ;begin{$H+}s := ‘测试下长串’;Windows.MessageBox(0, pchar(s), ‘讯息’, 64);end;由于var前{$H-}缘故, 虽然在begin后我们立即设定为{$H+}, 但s仍然是个短串,所以, 自然不能像是长串样, 以pchar强制型别转换后当作Null-terminated串使用? 承上, 不管是{$H+}或{$H-}, 只要串是以长串方式定义, 即使begin..end;中改成{$H-}, 该串操作仍然具有长串特性因此, 由于VCL中串都是长串, 即使我们是{$H-}, 仍然可以拿它们当长串来使用? 不论{$H}状态如何, 以AnsiString定义定是长串; 以[n]或ShortString定义定是短串{$M 16386, 1048576} 内存配置大小要改变唯叠(Stack)内存配置大小时, 我们可以有以下两种选择:? 使用{$MINSTACKSIZE数字}, {$MAXSTACKSIZE数字}, 分别指定最小.最大Stack 大小.? 或者使用{$M min, max}, 同时指定最小和最大值使用这些Compiler directive时注意事项有:? 写在.DPR中才有效果? 堆栈最小数字必须介于1024至21474835647的间? 堆栈最大数字必须介于$MINSTACKSIZE至21474835647的间? 当内存不足而无法满足最小堆栈大小时, Windows会在激活这时提出报告? 当要求内存超过$MINSTACKSIZE大小时, 将举发EStackOverflow例外{$Z1} 最小列举大小这个Compiler directive将影响储存列举型态时最小所需数值如果宣告列举型态时, 数值不大于256, 而且也在系统预设{$Z1}时, 这个列举型态只占用个储存{$Z2}时, 以两个储存, {$Z4}时, 以 4个储存C语言通常以WORD或DWORD储存列举型态, 如果您需要和C、C沟通时,{$Z2}{$Z4}就很管用了{$Z+}, 和{$Z-}分别对应到{$Z1}和{$Z4}{$P+} 开放串参数在和宣告时, 其中串自变量, 在{$P+}时表示是Open ; {$P-}时,只是般串变量而已这个Compiler directive只在{$H-}时有作用{$O+} 最佳化开关建议您维持{$O+}系统默认值开启这个Compiler directive, Delphi会自动进行最佳化处理, 可以因此跑得快些, 您可以放心打开这个编译开关, Delphi不会进行不安全最佳化而使您执行时发生{$Q-} 满溢检查, {$R-} 范围检查{$Q}和{$R}是组搭配使用Compiler directive, 它们将检查数值或操作是否在安全边界中, {$Q}会检查整数运算(如+, -, Abs, Sqr, Pred,Succ等), 而{$R}则检查串和存取是否超出合理边界范围等问题使用这两个Compiler directives会这些检查动作而降低执行速度,通常我们会在除错时开启这两个编译开关{$U-} Pentium CPU浮点运算安全检查还记得早期Pentium CPU浮点运算不正确事吧? 这批CPU应该回收得差不多了,但如果您仍然不确定会不会意外遇到漏网的鱼或黑心牌经销商话, 请将这个 Compiler directives设为{$U+}根据Borland手册介绍说明, 如果CPU是没有暇疵, 设定{$U+}对于执行速度只有轻微 影响; 但如果是问题CPU, 浮点除法速度会因此慢上 3倍, 是否要打开这个开关,您心中应该已有取舍{$R文件名称} 资源档在您还没有开始学习Compiler directives的前, 这个指令就已经出现在您中了,每次开出个新form时, Delphi自动在Implement开头部分中加入{$R *.DFM},在Project/Source中看到.DPR中也有{$R *.RES}, 这些是什么意思呢? 意思是说,在编译连结时, 含入和项目主档名同名.RES, 以及和form unit档案同名.DFM等资源档 如果您需要在中使用额外资源(例如: 自订鼠标指针), 请注意不要自行以Resouse WorkShop或Image Editor等资源编辑器更改这些和Project或Form同名资源档,改变这些同名档案不仅无效, 可能还有不可预期因些,您应该在另外个资源档中存放这些资源, 并于{$R}中写明档案名称将其连结进来, 例如: {$R MyCursor.res}{$T-} @指针型态检查应用@操作数可以取得变量地址, 在{$T-}时, 以@取得是个无型别指针(Poer)反过来说, 在{$T+}时, 是有型别指针, 假定I是个eger变量, @I所得到即是相当于^Integer(Poer of Integer)指针{$WARNINGS _disibledevent=>beginVarConst := 5;ShowMessage(IntToStr(VarConst));end;const不是常数吗? 为什么可以改呢? 在先前Pascal版本中, 以const VarName: DataType = const value;定义具型态常数确是可以改, 假如您希望常数就是常数, 它不应该允许修改,请将这个Compiler directive设为{$J-}不论是{$J+}或{$J-}, 以const VarName = const value; 定义常数(没有加上型别宣告), 是个真正常数, 其它不可以改变其内容其实{$J+}时还有个妙用, 那就是宣告出类似C语言变量, 换句话说,产生了个和Application相同生命周期变量在这种情形下, 变量只在第次使用时才会建立, 或结束时, 该变量也不会消灭, 下次再呼叫到这个或时, 我们仍然可以参考到上次执行结束时值让我们试下这个例子:{$J+}procedure TForm1.Button1Click(Sender: TObject);consti: eger = 0;beginShowMessage(IntToStr(i));Inc(i);ShowMessage(IntToStr(i));end;第次执行时, 我们分别会看到「0」「1」, 再点次这个按钮时, 看到将是「1」「2」 2009-3-28 1:29:52 疯狂代码 /。
引言概述:Delphi程序设计是一种面向对象的编程语言,它以其良好的可视化开发环境和丰富的组件库而闻名。
本文将深入探讨Delphi程序设计的进阶知识,为读者提供更深入的理解和应用。
主要包括:Delphi的多线程编程、数据库操作、图形用户界面设计、网络编程和常用算法的实现等五个大点。
正文内容:一、Delphi的多线程编程1.理解多线程编程的概念和原理2.使用TThread类创建和管理线程3.线程同步和互斥的技术和方法4.处理线程间通信和数据共享的问题5.性能优化和异常处理的注意事项二、数据库操作1.连接和配置数据库的方法2.SQL语句的使用和优化3.使用数据集和数据绑定技术实现数据可视化4.事务处理和数据的增删改查操作5.数据库连接池和安全性的考虑三、图形用户界面设计1.Delphi中的控件和容器的使用2.自定义控件和界面风格3.响应用户交互和输入的事件处理4.使用图像和图表进行数据可视化5.快捷键和界面布局的优化四、网络编程1.TCP/IP协议和Socket编程的基本概念2.使用TClientSocket和TServerSocket实现基于TCP的通信4.安全通信和网络编程中的加密技术5.服务器端的负载均衡和高并发处理五、常用算法的实现1.排序算法的比较和选择2.查找算法和数据结构的应用3.图算法和最短路径的查找4.字符串处理和正则表达式的应用5.数据压缩和加密算法的实现总结:本文对Delphi程序设计的进阶知识进行了详细的阐述,包括多线程编程、数据库操作、图形用户界面设计、网络编程和常用算法的实现。
通过掌握这些知识,读者可以提高自己的程序设计能力,并在实际项目中运用到Delphi开发中。
希望本文对读者有所帮助,为其进一步学习和探索Delphi程序设计打下坚实的基础。
Delphi编写标准指南一、序言二、通用源代码格式规则2.1 缩格2.2 页边空格2.3 Begin...End 配对三、Object Pascal3.1 括号3.2 保留字和关键字3.3 过程和函数(例程)3.3.1 命名/格式化3.3.2 形式参数3.3.2.1 格式化3.3.2.2 命名3.3.2.3 参数的排序3.3.2.4 常量参数3.3.2.5 名称的冲突3.4 变量3.4.1 变量的命名和格式3.4.2 局部变量3.4.3 全局变量的使用3.5 类型3.5.1 大写约定3.5.1.1 浮点指针类型3.5.1.2 枚举类型3.5.1.3 变数和ole变数类型3.5.2 结构类型3.5.2.1 数组类型3.5.2.2 记录类型3.6 语句3.6.1 if 语句3.6.2 case 语句3.6.2.1 一般性话题3.6.2.2 格式3.6.3 while 语句3.6.4 for 语句3.6.5 repeat 语句3.6.6 with 语句3.6.6.1 一般话题3.6.6.2 格式3.7 结构异常处理3.7.1 一般话题3.7.2 try...finally的使用3.7.3 try...except的使用3.7.4 try...except...else的使用3.8 类类型3.8.1 命名和格式3.8.2 域3.8.2.1 命名/格式3.8.2.2 可视化3.8.3 方法3.8.3.1 命名/格式3.8.3.2 使用静态的方法3.8.3.3 使用虚拟/动态的方法3.8.3.4 使用抽象的方法3.8.3.5 属性存取方法3.8.4 属性3.8.4.1 命名/格式3.8.4.2 使用存取的方法四、文件4.1 工程文件4.1.1 命名4.2 窗体文件4.2.1 命名4.3 数据模板文件4.3.1 命名4.4 远端数据模板文件4.4.1 命名4.5 Unit文件4.5.1 通用Unit结构4.5.1.1 unit的名字4.5.1.2 uses子句4.5.1.3 interface部分4.5.1.4 implementation部分4.5.1.5 initialization部分4.5.1.6 finalization部分4.5.2 窗体单元4.5.2.1 命名4.5.3 数据模板单元4.5.3.1 命名4.5.4 一般目的单元4.5.4.1 命名4.5.5 构件单元4.5.5.1 命名4.6 文件头五、窗体和数据模板5.1 窗体5.1.1 窗体类型命名标准5.1.2 窗体实例命名标准5.1.3 自动创建窗体5.1.4 模式窗体实例化函数5.2 数据模板5.2.1 数据模板命名标准5.2.2 数据模板实例命名标准六、包6.1 使用运行包和设计包的比较6.2 文件命名标准七、构件7.1 用户自定义构件7.2 构件单元7.3 使用注册单元7.4 构件实例命名约定7.5 构件的前缀7.6 Standard页7.7 Additional页7.8 Win32页7.9 System页7.10 Internet页7.11 Data Access页7.12 Data Controls页7.13 Decision Cube页7.14 QReport页7.15 Dialogs页7.16 Win3.1页7.17 Samples页7.18 ActiveX页7.19 Midas页一、序言本文档详述了在Delphi 4开发者指南下进行编程的代码编写标准。
在通常情况下,本文档遵循“取消”式格式的指引方针,该方针由Borland国际通过一些例外来使用。
在Delphi 4开发者指南中包含本文档的目的在于阐述一种方法,通过该方法,开发小组可以在他们所编写的代码中保持一贯的风格。
这样做的目的是使在开发小组中的每一个程序员都可以明白其他程序员的代码。
这有助于提高代码编写的可读性和使用的一贯性。
本文档并不意味着包含了所有存在于代码中的标准。
但是,它的内容已足够帮你起个好头。
你可以自由的增加修改这些标准来满足你的需要。
我们不赞成你偏离这些由Borland开发人员所使用的标准太远。
我们推荐这么做是因为一旦有新的程序员加入到你的开发小组中,而他们最喜欢和最熟悉的是Borland的标准。
象大多数代码标准文档,本文档也会根据需要进行改动。
因此,你可以到/ddg中找到最新的更新版本。
本文档不包括用户接口标准。
本文档是独立的但也是同样重要的。
已经有足够的第三方书籍和Microsoft文档包括了另外一些指导方针,而我们决定并不复制这些信息,但我们会指引你到Microsoft Developers Network 和一些资源,在那儿可以找到你所需的信息。
二、通用源代码格式规则2.1 缩格缩格是指在每一级有两个空格。
不要在源代码中保留tab字符,这是因为tab字符会随着不同用户的不同设置和不同的资源管理工具(打印、文档、版本控制等)而代表不同的宽度。
你可以通过关闭Environment选项对话框中Editor页上的“Use tab character”和“Optimal fill”检查框(通过Tools|Environment)来禁止保存tab字符。
2.2 页边空格页边空格会被设置成80字符宽。
通常,源码不会超出这个边界,但这个方针会有一些弹性。
不管是否有可能,那些超出到另一行的语句会在一个逗号或其他操作符之后与前面的语句相连。
当一个语句被打断相连时,它应比原来的那一行语句缩进两个字符。
2.3 Begin...End 配对Begin 子句应写在独立的一行。
例如,下面第一行是错误的写法而第二行是正确的。
for I := 0 to 10 do begin //错误,begin同for在同一行for I := 0 to 10 do //正确,begin出现在独立的一行begin这个规则的例外是当begin子句的出现是作为一个else子句的一部分-参考例子:if some statement thenbegin...endelse beginsomeOtherStatement;end;end 语句永远出现在独立的一行。
当begin语句不是一个else子句的一部分时,相应的end语句永远缩进到与begin部分相对应的位置。
三、Object Pascal3.1 括号永远不要在括号与括号之间的字符中间留下空格。
下面的例子示范了错误的与正确地使用括号中的空格:CallProc( Aparameter ); //错误CallProc(Aparameter); //正确永远不要在一个语句中使用不必要的括号。
括号只应在源代码中需要的地方使用。
以下的例子示范了错误和正确的使用:if (I = 42) then //错误-多余的括号if (I = 42) or (J = 42) then //正确-需要括号3.2 保留字和关键字Object Pascal 保留字和关键字永远是全部小写。
3.3 过程和函数(例程)3.3.1 命名/格式化例程的名字永远应该以大写的字母开头并且中间错落分明以便于可读性。
下面是一个不正确格式的过程名称:procedure thisisapoorlyformattedroutinename;下面是一个合适的大小写例程名称的例子:procedure ThisIsMuchMoreReadableRoutineName;例程的名称应该同它的内容相符。
一个会导致某个行为的例程应以动词开头。
例如:procedure FormatHardDrive;一个用于设置输入参数的例程应以单词set作为前缀,例如:procedure SetUserName;一个用来接收某个值的例程应以单词get作为前缀,例如:procedure GetUserName : string;3.3.2 形式参数3.3.2.1 格式化如果有的话,相同类型的形参应合并在一个语句中:procedure Foo(Param1, Param2, Param3 : Integer; Param4 : string);3.3.2.2 命名所有形参的名字应是十分符合它们所代表的意义,特别是应该以传送到例程中的标志符的名称为基础。
一个好的参数名称应以字符A为前缀-例如:procedure SomeProc(AuserName : string; AuserAge : integer);“A”前缀按约定表示该参数的名称是与类类型中的一个属性或域的名称相对应的。
3.3.2.3 参数的排序下面的形参的顺序重点说明了注册者调用约定调用的好处。
-最常用的参数应放在第一位,其它的参数应按从左到右的顺序排列。
-输入参数列表应放在输出参数列表的左边。
-将通用的参数放在特殊参数的左边,例如:procedure SomeProc(Aplanet, AContinent, Acountry, Astate, Acity)-排序有可能有些例外,比如事件的处理。
类型为TObject的Sender参数经常放在第一位。
3.3.2.4 常量参数当一个参数为记录型、数组类型、ShortString、或接口类型并且在例程中不被改变时,这些参数应做上常量标记。
这样做会让编译器更加有效率的产生有关这些不改变的参数的代码。
而例程中另外一些非变参数也可常量来传送。
尽管这样做没有产生任何效果和提高效率,这将会给调用例程的使用者提供更多的信息。
3.3.2.5 名称的冲突当使用拥有两个名称相同的例程的两个单元时,如果你调用该例程时,在uses子句中排在后面的单元中的例程将会被调用。
为了解决这种“在uses子句上的模糊”冲突,要在调用该例程时写上相关的单元的前缀,例如:sysUtile.FindClose(SR);或windows.FindClose(Handle);3.4 变量3.4.1 变量的命名和格式变量的命名应以使用它们的目的相符循环控制变量应采用一个单独的字符作为名字,比如I,J,或K,也可以采用更加有意义的名字,比如UserIndex。
逻辑变量的名字应能充分表达准确的真或假的意思。
3.4.2 局部变量一个过程中的局部变量应遵循所有其它变量的使用和命名约定。
临时变量的取名应合理。
如果必须的话,在一进入例程就应初始化局部变量。
局部的AnsiString变量会自动初始化为一个空的字符串。
局部接口和派分接口类型变量将会自动初始化为nil,并且局部变数和ole变数类型变量会自动初始化为Unassigned3.4.3 全局变量的使用使用全局变量是不推荐的。
但是,在某些时候还是必须使用,而且它们也只应在必须使用的时候才使用。
在这种时候,你应努力只在一段上下文范围内使用全局变量。
例如,一个全局变量只应在一个单元的implemntation部分内是全局的。