Delphi Code Specification Document Directory
1, preface 32, source program writing specification 32.1 General source code format specification 32.1.1 indentation 32.1.2 margin 32.1.3 Begin ... End statement 32.1.4 Note 42.2 Object Pascal statement format Writing specification and usage 42.2.1 Brand 42.2 .2 Reserved Words and Keywords 42.2.3 Processes and Functions 52.2.4 Variables 52.2.5 Type 62.2.6 Statement 62.2.7 Structured Abnormal Processing 73 Name Specification 83.1 Process (Function) 83.1.1 Name 83.1 .2 ginseng 93.1.3 Name conflict 93.2 Variables (Variable) 93.2.1 Local variables 93.2.2 Global variables 93.3 Type 93.3.1 General Type 93.3.2 Construction Type 103.3.3 Type (Class) 103.3.4 Component Type 113.3.5 Forms and dialog Type 133.3.6 Data Module Type 153.4 File 163.4.1 Project file 163.4.2 Form file 163.4.3 Data module file 163.4.4 Remote data module file 163.4.5 Unit file 174, Delphi code automatic formatting tool 18
1. The present document is mainly to provide a source code writing standard for Delphi developers, as well as the naming standards of the program and files, so that they have consistent formats in programming. In this way, each programmer written code can be understood by others. Note: This document does not contain user interface standards. The user interface standard is independent of other standards and is equally important. 2, source program writing specification 2. Universal source code format specification 2.1.1 Indenting indentation is two spaces in each stage. Do not place tabs in the source code. This is because the width of the tablet is different from different settings and code management utilities (printing, documentation and version control, etc.). By using the Tools | Environment menu, on the General page of the Environment Options dialog, do not select the Use Tab Character and Optional Fill check box so that the tab will not be saved. 2.1.2 The margin margins are set to 80 characters. Sourcecodes generally do not exceed margins by writing a word, but this rule is more flexible. As long as it is possible, the statement that exceeds a row should be wrapped in a comma or operator. After the wrap, the two characters should be indensed. 2.1.3 Begin ... End Statement Begin statement must be occupied separately. For example, the first line below is wrong, and the second line is correct: for i: = 0 to 10 do begin // fault, begin and for i: = 0 to 10 do // pair, begin is in addition A special case of Begin this rule is that when Begin is part of the ELSE statement, for example, if Some Statement = Thenbegin.. .Endelse begin Some Other Statement; End; Note: End statement is always a line. When BeGin is not part of the ELSE statement, the corresponding End statement is the same as the reachable amount of the Begin statement. 2.1.4 Note We usually use the "{...}" type block note, the previous "(* ... *) type block note is used to temporarily comment out the code that is not used, starting from Delphi 2 "//" row comment, if you do not support version of Delphi 2.0 or less, you can use "//" comment.
2.2 Object Pascal statement format Writing specification and usage 2.2.1 Braces There is no space between the parentheses and the next character. Similarly, there is no space in the right brackets and the previous characters. The following example demonstrates correct and incorrect spaces. CallProc (APARAMETER); // Wrong! CallProc (APARETER); / / correct!
Do not include excess parentheses in the statement. In the source code, parentheses only use when needed. The following example demonstrates correct and incorrect usage: if (i = 42) THEN / / wrong, parentheses is an excess IF (i = 42) or (j = 42) THEN / / correct, must be used in bracket 2.2.2 Words and keywords Object Pascal language reserved words and keywords are always completely lowercase. Here is Delphi 5 list of reserved words: and array as asmbegin case class constconstructor destructor dispinterface divdo downto else endexcept exports file finalizationfinally for function gotoif implementation in inheritedinitialization inline interface islabel library mod nilnot object of orout packed procedure programproperty raise record repeatresourcestring set shl shrstring then threadvar Totry Type Unit Untiluses Var While WithXor Private Protected PublicPublished Automated 2.2.3 Procedures and Functions □ Format The format should start with uppercase letters and interfiber to increase readability. Here is an incorrect way: procedure thisisapoorlyformattedRoutinename; change to this is right: Procedure thisismuchmorereadableRoutinename;
□ Conversion ● Format As long as possible, the same type of shape should be collected and together: Procedure Foo (Param1, Param2, Param3: Integer; param4: string;
● The order of parameter sequential parameter is mainly considered to consider register call rules. The most common parameters should be used as the first parameter, follow the left to right rows according to the frequency of use. The input parameter is before the output parameter. The large parameters should be placed before the range of small parameters. For example: SomeProc (Aplanet, Acontinent, Acountry, ASTATE, ACITY). Some exceptions. For example, during an event processing, the Snder parameter of the TOBJECT type is often the first parameter to be passed.
● Specific parameters should not be modified by the parameters of the record, array, short string, or interface type, and the shape should be used in const. In this way, the compiler will generate a code in the most effective way to ensure that the passing parameters are not variable. If other types of parameters are desired to be modified by the process, you can also marke with const. Although this has no effect, this is more information about the caller of the process.
2.2.4 Variables □ Partial variable local variables are used inside the process, and if needed, the variable should be initialized immediately at the entrance of the process. The variable of the local ANSISSTRING type is automatically initialized to an empty string, a partial interface and a variable of the DISPINTERFACE type automatically initialized to NIL, the local Variant and Olevariant type variables are automatically initialized to Unassigned.
□ Global variables generally do not encourage global variables. However, sometimes it needs to be used. Even so, global variables should be limited to the desired environment. For example, a global variable may only be overall in the implementation of the unit. Global variables If you will be used by many units, you should be used to use all objects in a common unit. Global variables can be directly initialized to a value when declaring. Note that all global variables are automatically initialized, so do not initialize global variables as null values such as 0, NIL, or Unassigned. The global variable of zero initialization is not spaced in .exe file. Zero-initialized data is saved in the virtual data segment, and the virtual data segment is only assigned memory only when the application starts. The global data of non-zero initialization is in the .exe file. 2.2.5 Type □ Calculation rule type identifier is a reserved word, should be written. Win32 API types are often all capitalized and follow rules such as Windows.PAS or other API units for specific type names. For other variable names, the first letter should be capitalized, and the other letters are cases interlaced. Here are some examples: var myString: String; // Reserved Word WindowsHandle: HWnd; // Win32 API Type I: Integer; / / Introduction Introduced in System Unit
□ Floating-point type does not encourage the use of the REAL type because it is just to be kept compatible with old Pascal code. Typically, Double should be used for floating point numbers. Double can be optimized by processor, which is the standard data format defined by IEEE. You can use extend when needed than the range provided by Double. Extend is the type of Intel, Java does not support. When the physical byte number of floating point variables is important (possibly writing DLLs in other languages), you should use Single.
□ Variant and Olevariant generally do not recommend using Variant and Olevariant. However, when the data type is only known in the run (often in the program of the COM and database applications), these two types are necessary to program. When COM programming such as an automated ActiveX control, Olevariant should be used; and Variant should be used for non-COM programming. This is because Variant can effectively save the native string of Delphi, while Olevariant converts all strings to an OLE string and does not reference counting functions.
2.2.6 Statement □ If statement is in the IF / THEN / ELSE statement, the most likely executed should be placed in the THEN clause, and it is not possible to place in the else clause. To avoid many if statements, you can use the CASE statement instead. If more than 5, don't use the IF statement. Please use a clearer way. Do not use excess parentheses in the IF statement. If there are multiple conditions to be tested in the IF statement, you should row from right to right in accordance with the computational complexity. This allows the code to make full use of the short-circuit estimation logic of the compiler. For example, if the condition1 is fast than Condition2, Condition2 is fast than Condition3, if the IF statement should be constructed: if condition1 and condition2 and condition3 Then If the condition3 is a big chance, we can use the short-circuit estimation logic, we can also put the consivation3 in the most Front: if Condition3 and condition1 and condition2 Then
□ The constant of each situation in the case statement case statement should be arranged in the order of numbers or letters. The action statement of each situation should be short and usually no more than 4 - 5 lines of code. If the action is too complicated, the code should be placed separately in a process or function. The ELSE clause of the CASE statement is only used for default or error detection. The CASE statement follows the general indentation and naming rules. □ While statement recommends not using the exit process to exit the While loop. If necessary, you should use a loop condition to exit the loop. All code initialized for the While loop should be located before the WHILE entry and not unrelated statements. Any business auxiliary work should be carried out immediately after cycling.
□ FOR statement If the number of cycles is determined, use the for statement to replace the While statement.
□ The REPEAT statement The REPEAT statement is similar to the While loop and follows the same rules.
□ WITH statement with statement should be careful. To avoid excessive use of the WITH statement, especially in the with statement, multiple objects or records. For example: with record1, these situations are easy to confuse programmakers and lead to difficulties in debugging. The WITH statement also follows this chapter about naming and indentation rules.
2.2.7 Structured Abnormal Handling □ Overview Abnormal Processing is mainly used to correct errors and protection resources. This means that anywhere to allocate resources must be used to ensure that resources are released. However, if it is an exception to the resource in the initial / end portion of the unit or the object of the object.
□ Try ... finally Usage Under possible cases, each resource allocation should match the try ... finally structure, for example, the following code may result in errors: someclass1: = tsomeclass.create; someclass2: = tsomeclass.create; Try {do some code} finally SomeClass1.Free; SomeClass2.Free; end; the above-described embodiment a security resource allocation is: SomeClass1: = TSomeClass.Create; Try SomeClass2: = TSomeClass.Create; Try {do some code} finallySomeClass2.Free ; "FINALLYSOMECLASS1.FREE; END;
□ Try ... Except usage If you want to perform some tasks when an exception occurs, you can use TRY ... Except. Usually, it is not necessary to use Try ... Except for simply displaying an error message because the Application object can automatically do this according to the context. If you want to activate the default abnormality processing in the clause, you can trigger an exception again.
□ Try ... Except ... Else Usage does not encourage Try ... Except with Else clause, because this will block all exceptions, including you are not ready to process an exception.
3 Name Specification 3.1 Process (Function) and Function 3.1.1 Naming Process and Function Name should make sense. The process of performing an action is preferably prefixed in front of the name before the name is prefixed. For example: procedure formatharddrive; setting the process name of the input parameter value should be prefixed as a set, for example: procedure setUsername; get the value of the process name should be prefixed with GET, for example: function getUsename: string;
3.1.2 The name of all ginseng should express its use. If appropriate, the name of the group is preferably prefixed in letter A, for example: procedure: string; meanserage: integer; prefix A is necessary when the parameter name is in the same name as the class, the prefix is necessary.
3.1.3 Naming Conflict When the process contains the same name in the two units, if the process is called, the process actually called is the process in the unit that appears later in the Uses clause. To avoid this, you can add the desired cell name before the method, for example: sysutils.FindClose (SR); or Windows.FindClose (Handle); 3.2 Variables Variable Name should be able to express its use. The loop control variable is often a single letter, such as I, J or K. It is also possible to use more meaningful names, such as UserIndex. The Boolean variable name must be clearly indicating the meaning of true and false values. 3.2.1 Local variables partial variables follow the naming rules of other variables.
3.2.2 Global variable global variables are headed by uppercase letters "G" and follow the naming rules of other variables.
3.3 Type (TYPE) 3.3.1 General Type Enumeration Type Name must represent the purpose of enumeration. The name is plus T character as a prefix before the name, indicating that this is a data type. The prefix of the enumeration type identifier list should contain 2 - 3 lowercase characters to associate each other. For example: TsongType = (Strock, StClassical, StCountry, Stalternative, Stheavymetal, StrB); the name of the modulus instance of the enumeration type is the same as the type, but there is no prefix t, which can also give a more special name, such as: FavoritesongTypel, FavoritesongType2, etc. Wait. 3.3.2 Construction Type □ Array type array type name should express the use of the array. The type name must add the letter "T" as a prefix. If you want to declare a pointer to the array type, you must add letter P to prefix, and the declaration is before the type declaration. For example: Type PcycleArray = ^ TcycleArray; TcycleArray = array [1..100] OF INTEGER; actually, the variable instance of the array type is the same as the type name, but no "T" prefix.
□ Record Type Record Type Name The use of records should be expressed. Type names must add letter T to prefix. If you want to declare a meter pointing to the type of record, you must add the letter P as a prefix, and its declaration before the type declaration. For example: Type Pemployee = ^ Temployee; TemPloyee = RecordemPloyeename: String; EMPLOYEERATE: DOUBLE; END;
3.3.3 Class Type (Class) □ Name and format class The name of the format should express the use of class. The general class name is to add letters "T". If the interface class is added to "I" before the class, the incorrect exception class is previously added "e" before the class name, and the class reference type (Class-reference type) is in class After the name, add "class". For example: type tcustomer = class (TOBJECT); icustomer = interface; tcustomerclass = class of tcustomer eCustomerException = class (exception); class instance names are usually the same as class name, but there is no prefix "T". Var Customer: TCUSTOMER; Note: For the naming of components, see "Component Type".
□ Field ● Naming and Format field Name Follow the same rule as the variable, but to add prefix f, indicating that this is a field.
● Visibility All fields must be private. If you want to access fields outside the scope of the class, you can be implemented by means of the properties of the class.
□ Method ● Naming and format method naming follows the same rules as the process and functions.
● Static method When you don't want a method being derived, it should use a static method. ● Virtual Method (Virtual) and Dynamic Method (Dynamic) When you want a method, you should use the virtual method (Virtual). If the class method is used directly or indirectly by multiple derived classes, the dynamic method should be used. For example, a certain class contains a frequently covered method and has 100 gestational categories, and the method should be defined as dynamic, which can reduce the overhead of memory.
● Abstracting method (abstract) If a class is to create an instance, do not use an abstract method. The abstract method can only be used in the base class that never creates an instance.
● Properties Access Method All attribute access methods should be defined in the private or protective part of the class. The attribute access method follows the same rules as the process and functions. The method used to read should be added "GET" prefix, and the method used to write should add "set" prefix, and there is a parameter called Value, which is the same as the type of property. For example: TSomeClass = class (TObject) privateFSomeField: Integer; protectedfunction GetSomeField: Integer; procedure SetSomeField (Value: Integer); publicproperty SomeField: Integer read GetSomeField write SetSomeField; end; although not required, it is recommended that you use write access to visit Represents private field properties.
□ Property Properties As a private field, follow the same naming rules as the field, but there is no F prefix. The property name should be noun, not the verb. The attribute is data, and the method is the action. The array attribute name should be a plural, and the general attribute should be a single number.
3.3.4 Component Type □ Component Type Name Standard Element Names and Class Naming Similarity, just when it conflicts with other component names, you can add 3 characters prefixed to identify companies, individuals or other entities . For example, a clock component can declare this: TDDGCLOCK = Class (Tcomponent) Note: Don't write on three characters as a prefix.
□ The name of the naming rule element instance of the component instance should be able to describe its actual meaning, here the naming rules use a changed Hungarian prefix naming specification. The reason why the prefix does not use the suffix is when searching, the name of the search component in the object inspector and the code explore is easier than the type of search component. In this standard, component instance names include two parts: prefix and nature identification name. ● The prefix of the prefix element of the element is more alphabetic abbreviation. See the component prefix in the table below: Component class element prefix TActionList, TAction represents all of the list items of action ActTbutton, TspeedButton, Tbitbtn, etc. BTNTCHECKBOX, TDBCHECKBOX, etc. All check boxes ChktraDiobutton radical button RDOTTOOLBAR Toolbar TBTMAINMENU All Main menu class MMTMainuitem All menu item class Mitpopupmenu All pop-up menu class PMTPopupMenuitem All pop-up menu items Pmitlabel, TSTATICTEXT, all the panel classes such as LBLTPANEL, etc. All PNLTPAGECONTROL, etc. All page panel PNLTPAGECONTROL All single-line editing boxes such as EDTTMEMO, TRICHEDIT, etc., edit, TrichEdit, etc. MMOTDRID, TSTRINGGRID, all the number of MGDTANIMATE, etc. All Movie class AnitImageList, etc. All picture list Iltimage and other picture class IMGTCHART chart class CHTTCOMBOBOX All drop-down lists such as TDBCOMBOBOX Class CBOTLISTBOX, TDBLIST, all lists of LsttttreeView TVTListView LVTHOTKEY HKTSPLISTVIEW LVTHOTKEY HKTSPLISTVIEW LVTHOTKEY HKTSPLISTVIEW LVTHOTKEY HKTSPLISTVIEW LVTHOTKEY HKTSPLISTVIEW LVTHOTKEY HKTSPLISTVIEW LVTHOTKEY HKTSPLISTVIEW LVTHOTKEY HKTSPLITLITER All Dialog All SPTTopEndialog and so on All dialog Email All data tablets TBLTQuery, etc. All SQL query class element qryTClientDataSet all customer data set element cdsTDataSource dsTDatabase dbTSockConnection, TDCOMConnection like connection element class conTQuickRep, TFastReport elements and all classes of reports rptTDDEClientConv, TDDEClientItem all other DDE elements and all classes ddeTMonthCalendar calTGroupBox other calendars control class class shown above grp The component type prefix is from the type of analysis of the type of description element. Typically, the following rule describes how to define a component type prefix: ◆ Remove the T prefix from the component type name. For example, TButton turns to Button. ◆ In addition to the first vowel, cut out all the vowel letters. For example, Button becomes BTTN, and Edit becomes an EDT. ◆ Compressed double letters. For example, BTTN becomes btn. ◆ If a conflict occurs, add a vowel in a part prefix. For example, adding a vincar to BATN in the prefix of the TBATTON component to distinguish between the prefix of TButton. ◆ However, the above rules must first guarantee the prefix names must be in accordance with the habits, and see the name of the name, such as the prefix of the TDDeclientConv control is an exception. Note: The prefix of the component is to indicate the type of the element, buttons, or label, etc., there is no need to establish a component prefix for each special component class, such as: TMYBUTTON component prefix is BTN.
● Component properties indicate that the nature identification name of the name element is the description of the intent. For example, a TBUTTON component instance for closing the form can be named btnclose. An element instance of an editing name can be named edname.
3.3.5 Forms and Dialog Types □ Form Type Name Standard Forms or Dialog Types The name of the form should express the use of the form. If you are a "TFRM" prefix, if it is the dialog box to add " TDLG ", followed by the descriptive name. For example, the About Form Type Name is: TFRMABOUT = Class (TFORM) The type name of the main form is: TFRMMAIN = Class (TFORM) Customer login form Type name: TFRMCUSTOMERENTRY = Class (TFORM) Type name of the login dialog To: TDLGLOGIN = Class (TFORM) □ The name of the naming standard form instance of the form instance is the same as the corresponding type name, but no prefix t. For example, the previously mentioned form type and instance name is: Type name instance name TFRMabout frMaboutTFrmMain frmmainTfrmcustomERENTRY FRMCUSTOMERENTRYTDLGLOGIN DLGLOGIN
□ Automatically created form unless specifically reasons, only the main form is automatically generated. All other forms must be removed from the auto-generated list of the Project Options dialog. For further information, see the following sections.
□ Mode Form Instantiation Functions All Form Units should contain an instantiation function for creating, setting, mode display, and release forms. This function will return the pattern result returned by the form. Parameters passing to this function follow the rules of the parameters. It is necessary to encapsulate this, which is for the reuse and maintenance of the code. The variable of the form should be removed from the unit, and is changed as a local variable in the form instantiation function (note that the form is required to remove the form from the Auto Generation list of the Project Options dialog. Please see the previous content. For example, , the following documents demonstrate GetUserData unit instantiation function .Unit UserDataFrm; InterfaceUses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; Type TfrmUserData = class (TForm) edtUserName: TEdit; edtUserID: TEdit; private {Private declarations} public {public declarations} end; function GetUserData (var aUserName: String; var aUserID: Integer): Word; implementation {$ R * .DFM} function GetUserData (var aUserName: String; var aUserID: Integer): Word; var frmUserData: TfrmUserData; begin frmUserData: = TfrmUserData.Create (Application); frmUserData.Caption: = 'Getting User Data'; Result: = frmUserData.ShowModal; if Result = mrOK then begin aUserName: = frmUserData.edtUserName.Text AUSERID: = STRTOINT (frmuserdata.edtuserid.text); end; finally fmuserdata.free; end; end; end.
□ Form Frame and Composite Form If a form structure is too complicated, it must differentiate into a main form frame and a number of sub-form frames embedded in the main form frame. Such as: tfrmmainframe: tfrmInfoframe, TFRMEDITORFRAME uses the form frame, mainly to solve the interface and code multiplex issues, and increase the internal strength of the unit code (after division, each form frame is a separate unit), thereby improving the quality of the software engineering. You must refine the interface-related code (which can be used) and application related code (cannot be multiplexed). 3.3.6 Data Module Type □ Data Module Naming Standard Data Module Type Name should express its use, and add "TDM", followed by the descriptive name. For example, the type name of the Customer data module is: TDMCUSTOMER = Class (TDATAMODULE) ORDERS data module Type name: TDMORDER = Class (tdataModule)
□ Instance Naming of Data Modules The name of the standard data module instance should be the same as the corresponding type name, but there is no prefix T. For example, the previous data module type, the instance name is as follows: Type name instance name TDMCUSTOMER DMCUSTOMERTDMORDER DMORDER
3.4 File recommends using structured file header information in all source files, project files, and unit files. One file head should at least contain the following information: {Copyright @ Year By Authors} 3.4.1 The name of the project file project file should have a description. For example, the project name of "The Delphi 5 Developer's Guide Bug Manager" is ddgbugs.dpr, and the name of a system information program is sysinfo.dpr.
3.4.2 The name of the form file form file should express the use of the form and have an FRM suffix. For example, the file name of the About Form is called AboutFrm.dfm, the file name of the main form is called mainfrm.dfm.
3.4.3 Data Module File Data Module file The name of the data module should be used to have a DM suffix. For example, the file name of the CUSTOMERS data module is called Customersdm.dfm.
3.4.4 Remote Data Module File The name of the remote data module file should express the use of the remote data module. After the name is added to add the RDM suffix. For example, the file of the Customers remote data module is called CustomersRDM.DFM.
3.4.5 Unit File □ Normal Unit ● The name of the cell name unit should be descriptive. For example, the main window of the application is called MAIMFRM.PAS. ● The USES clause of the USE clause interface section should only contain the unit required for this part. Do not include a unit name that may be automatically added by Delphi. The USES clause of the Implementation section should only contain the unit required by the part, and do not have extra units. ● The interface section of the Interface section should only contain the type, variable, process and function of the external unit access. Moreover, these statements should be in front of the Implementation section. ● The Implementation section includes the type, variable, process and function implementation of this unit. ● The INITIALIZATION section does not have a lot of code that spends a lot of time in the Initialization section. Otherwise, it will cause a very slow when the application starts. ● Finalization section Make sure all resources allocated in the Initialization section are released.
□ The name of the form cell unit file is the same as the corresponding form name, just turning the prefix into a suffix. For example, the unit name of the About Form is called AboutFrm.PAS. The unit file name of the main form is MAINFRM.PAS.
□ Data Module Unit Data Module Unit File The name is the same as the corresponding data module name. For example, the name of the data module unit is called Customersdm.PAS. □ The name of the general unit universal unit should express its use, and the "U" prefix is added before the name. For example, the name of a practical debug tool unit is Udebugutilities.PAS, which is called UCustomerglobals.PAS. Note: The unit name in a project must be unique. The general unit name cannot be renamed.
□ Component Unit ● The naming element unit should be placed in a separate path to indicate that they are the unit defining components. They are generally not placed under the same path as the project. The unit file name should express its content. Note that more information about component naming standards, see "Naming Standards for Components". Component units can only contain one main component, which means the components currently on the component palette. Other auxiliary components or objects can also be included in the same unit.
● The registration process of the registration unit component should be removed from the component unit and placed in a separate unit. This registration unit is used to register all components, attribute editing, component editing, wizard, and more. Component registration should be carried out in the design package. Therefore, the registration unit should be included in the design period rather than the running period. It is recommended to name the registration unit to name: XXXREG.PAS where the XXX character prefix is identified by the component package name or company, individual, other entity. For example, the registration unit is named XXXREG.PAS.
□ Package (.dpk) Naming Rules ● The running period and the design period will contain only the required units. The units of those attribute editors and component editors should be placed in the design package. The registration unit should also be placed in the design package.
● Naming of file naming rules Follow the following mode: dcliiIndescvvcn.pkg - Design period package IIIDescvvcn.pkg - running the package, III represents a 2-3-character prefix, used to identify the company, individual or other things that you need to identify, You can also; DESC indicates a short description of the control package; VV represents the version number of the package, you can pay as needed; prefix "DCL" indicates the design package, no prefix represents the running period; the letter "CN" means compiler Type and compiler version number, such as: Delphi5 = D5, Delphi4 = D4, CBUILDER3 = C3 .... Note that the lib or STD in the package name indicates that this is a design period or a running period. For example: dclrbstdcompsd5.pkg -delphi 5 design package RBSTDCOMPSD5.PKG-DELPHI 5 running package