Delphi Code Snippets Page
These Code Snippets are contributed by you (our online community members). They are organized by our knowledge base topics. Specifically, by the Delphi sub-topics.
|
55 Pascal and Delphi Coding Code Snippets
Group: Pascal and Delphi Coding
Topic: BDE
|
1. BDE Paradox Robust table openning |
|
This is a rough draft version of a procedure that provides a robust way to open paradox tables in a delphi program
unit DataModule;
interface
uses windows,SysUtils, Classes, DB, DBTables, controls, DateUtils, Dialogs, shellapi;
type TDataModule1 = class(TDataModule) Table1: TTable;
......
......
public SauveTable: boolean; end;
......
.......
procedure TDataModule1.DataModuleCreate(Sender: TObject); var DtBs : string; DirVers : string; DirDepuis: string; TableNam : string; st1,st2 : string; i,j,k : integer; TableTemp, TableSours : TTable; Transefrt : TBatchMove; res : boolean; f: TSearchRec; ListFichier : TStringList; begin SauveTable:=true; DecimalSeparator:='.'; ThousandSeparator:=' ';
Transefrt:=TBatchMove.Create(Self); TableTemp:=TTable.Create(Self);
for i:=0 to Self.ComponentCount-1 do if (self.Components[i] is TTable) and (self.Components[i]<>TableTemp) then begin if not TTable(Self.Components[i]).Exists then if Messagedlg('Erreurr Fatal: La table '+TTable(Self.Components[i]).TableName+' est manquante'#10#13+ 'Voulez vous recuprer la table partir de la dernire sauveguarde',mtError ,mbOKCancel,0)=mrok then begin DirDepuis:=Sessions.FindSession(TTable(Self.Components[i]).SessionName).FindDatabase(TTable(Self.Components[i]).DatabaseName).Directory; if DirDepuis[length(DirDepuis)]='\' then DirDepuis:=copy(DirDepuis,1,length(DirDepuis)-1); ListFichier:=TStringList.Create; res:=false; if FindFirst(DirDepuis+'\sauv_*.*',faDirectory,f)=0 then repeat ListFichier.Add(f.name); until FindNext(f)<>0; FindClose(f); ListFichier.Sorted:=true; if ListFichier.Count<1 then begin ShowMessage('Pas de sauvguard trouv?!! Veuillez contacter l''administrateur informatique'); for k:=0 to Self.ComponentCount-1 do if self.Components[k] is TTable then if TTable(Self.Components[k]).Active then TTable(self.Components[k]).close; ListFichier.Free; FormPrincipal.Close; exit; end; DirVers:=DirDepuis+'\'+ListFichier[ListFichier.count-1]; ListFichier.Free; ListFichier:=TStringList.Create; res:=false; if FindFirst(DirVers+'\' +copy(TTable(Self.Components[i]).TableName,1,pos('.',TTable(Self.Components[i]).TableName)-1)+'.*',faAnyFile,f)=0 then repeat ListFichier.Add(f.name); until FindNext(f)<>0; FindClose(f); for j := ListFichier.Count - 1 downto 0 do CopyFile(Pchar(DirVers+'\' + ListFichier[j]), Pchar(DirDepuis+'\' + ListFichier[j]),res); ListFichier.Free; end;
try TTable(Self.Components[i]).Open; except DirDepuis:=Sessions.FindSession(TTable(Self.Components[i]).SessionName).FindDatabase(TTable(Self.Components[i]).DatabaseName).Directory; if DirDepuis[length(DirDepuis)]='\' then DirDepuis:=copy(DirDepuis,1,length(DirDepuis)-1); DirVers:=DirDepuis+'\Sauv_'+FormatDateTime('dd-mm-yyyy',Date)+'_'+FormatDateTime('hh-mm',time); if not DirectoryExists(DirVers) then CreateDir(DirVers); ListFichier:=TStringList.Create; res:=false; if FindFirst(DirDepuis+'\' +copy(TTable(Self.Components[i]).TableName,1,pos('.',TTable(Self.Components[i]).TableName)-1)+'.*',faAnyFile,f)=0 then repeat ListFichier.Add(f.name); until FindNext(f)<>0; FindClose(f); for j := ListFichier.Count - 1 downto 0 do CopyFile(Pchar(DirDepuis+'\' + ListFichier[j]), Pchar(DirVers+'\' + ListFichier[j]),res); DirVers:=DirDepuis+'\Rindx'; if not DirectoryExists(DirVers) then CreateDir(DirVers); st1:=DirDepuis+'\'+TTable(Self.Components[i]).TableName; st2:=DirVers+'\'+TTable(Self.Components[i]).TableName; copyfile(pchar(st1),pchar(st2),res); if FileExists(DirDepuis+'\'+ChangeFileExt( TTable(Self.Components[i]).TableName,'.MB')) then begin st1:=DirDepuis+'\'+ChangeFileExt( TTable(Self.Components[i]).TableName,'.MB'); st2:=DirVers+'\'+ChangeFileExt( TTable(Self.Components[i]).TableName,'.MB'); copyfile(pchar(st1),pchar(st2),res); end; ListFichier.Free; st1:='-t '+DirDepuis+'\Rindx\' + TTable(Self.Components[i]).TableName + ' -AUTO -CLOSE -p amadou'; ShellExecute(FormPrincipal.Handle, 'open', 'TableRepairCommand.exe', Pchar(st1), nil, 1);
tabletemp.DatabaseName:=DirDepuis+'\Rindx'; TableTemp.TableName:=TTable(Self.Components[i]).TableName; TableTemp.SessionName:=TTable(Self.Components[i]).SessionName; if TTable(Self.Components[i]).Active then TTable(Self.Components[i]).Close; if TTable(Self.Components[i]).Exists then TTable(Self.Components[i]).DeleteTable; TTable(Self.Components[i]).CreateTable; TTable(Self.Components[i]).Open; TableTemp.Open; // Transefrt.Source:=TableTemp; Transefrt.Destination:=TTable(Self.Components[i]); Transefrt.Mode:=batAppend; Transefrt.Execute; TableTemp.Close; end; end; Transefrt.Destroy; TableTemp.Destroy; for i:=0 to Self.ComponentCount-1 do if self.Components[i] is TTable then if not TTable(Self.Components[i]).Active then TTable(self.Components[i]).Open;
SauveTable:=true; end;
......
......
procedure TDataModule.DataModuleDestroy(Sender: TObject);
var DtBs : string; DirVers : string; DirDepuis: string; TableNam : string; st1,st2 : string; i,j,k,l : integer; TableTemp, TableSours : TTable; Transefrt : TBatchMove; res : boolean; f: TSearchRec; ListFichier : TStringList; begin if (Messagedlg('Voulez vous effectuer une sauvguarde?',mtConfirmation ,mbOKCancel,0)=mrok ) and (SauveTable)
then begin for l:=0 to form1.Application.ComponentCount-1 do if (form1.Application.components[l] is TForm) or (form1.Application.components[l] is TDataModule) then begin for i:=0 to form1.Application.components[l].ComponentCount-1 do if (form1.Application.components[l].Components[i] is TTable) and (form1.Application.components[l].Components[i]<>TableTemp) then begin DirDepuis:=Sessions.FindSession(TTable(form1.Application.components[l].Components[i]).SessionName).FindDatabase(TTable(form1.Application.components[l].Components[i]).DatabaseName).Directory; if DirDepuis[length(DirDepuis)]='\' then DirDepuis:=copy(DirDepuis,1,length(DirDepuis)-1); DirVers:=DirDepuis+'\Sauv_'+FormatDateTime('yyyy-mm-dd',Date)+'_'+FormatDateTime('hh-mm',time); if not DirectoryExists(DirVers) then CreateDir(DirVers); ListFichier:=TStringList.Create; res:=false; if FindFirst(DirDepuis+'\' +copy(TTable(form1.Application.components[l].Components[i]).TableName,1,pos('.',TTable(form1.Application.components[l].Components[i]).TableName)-1)+'.*',faAnyFile,f)=0 then repeat ListFichier.Add(f.name); until FindNext(f)<>0; FindClose(f); for j := ListFichier.Count - 1 downto 0 do CopyFile(Pchar(DirDepuis+'\' + ListFichier[j]), Pchar(DirVers+'\' + ListFichier[j]),res); ListFichier.Free; end; end; end; For i:=0 to Self.ComponentCount-1 do if self.Components[i] is TTable then TTable(Self.Components[i]).Close; end;
Posted By Ahmed.A,
Post #102273, KB Topic: BDE
|
Topic: Delphi for Win32
|
2. Delphi Array (x=Array[0..3] of string;) |
|
Delphi supports both static and dynamic arrays.
var MyArray: array[0..3] of string; i: Integer; begin MyArray[0] := 'Mike'; MyArray[1] := 'Lisa'; MyArray[2] := 'Felicia'; MyArray[3] := 'Nathan';
for i := 0 to High(MyArray) do ShowMessage(MyArray[i]); end;
|
|
3. Delphi Empty String Check (length(s) = 0) |
|
Length() or SizeOf() will correctly identify an unassigned string variable or an empty string.
if length(s) = 0 then ShowMessage('empty string');
|
|
4. Delphi Event Handler |
|
Many objects in Delphi have events you can use to trigger code. For example, when you add a form to your project you have access to the form events such as onCreate, onShow, onHide, onDockDrop, etc. In addition, Delphi offers module level events initialization and finalization sections.
|
|
5. Delphi Exception Trapping (try..except, try..finally) |
|
Delphi also offers a try...finally where code will execute in the finally section no matter what. It's common to put a try...except inside a try...finally:
var y : Double; begin try y := 0; y := (1/y); ShowMessage(FloatToStr(y)); except ShowMessage('You cannot divide by zero.'); end; end;
|
|
6. Delphi Inline Code (asm) |
|
In Delphi, you can inline assembler code using the asm keyword.
|
|
7. Delphi Member Events |
|
In Delphi, member events are essentially properties of the type method pointer.
|
Topic: Tool Basics
|
8. Delphi Deployment Overview |
|
Delphi create native code Windows applications so you can create an EXE with no dependencies that will run on any Windows computer. If you add dependencies (reports, database libraries, DLLs, etc.) use a Windows installer to build an installation program.
D2007 and D2009 are bundled with InstallAware Express CodeGear Edition installer.
|
Topic: Language Basics
|
9. Delphi Assignment (:=) |
|
Delphi uses := for it's assignment operator.
var FullName: String; Age: Integer; begin FullName := "Randy Spitz"; Age := 38; end
|
|
10. Delphi Case Sensitivity (No) |
|
Object Pascal is generally not case sensitive.
Variables and commands are not case sensitive. var FullName: String; begin fullname := 'Mike Prestwood'; ShowMessage(fullNAME); SHOWMESSAGE(FULLNAME); showmessage(fullname); end;
|
|
11. Delphi Code Blocks (begin..end) |
|
Object Pascal requires the semi-colon after the "declaration" part.
function DoSomething : integer; var a, b : integer begin a := 1; b := 2; result := a + b; end;
|
|
12. Delphi Comments (// or { ... } or (* ... *)) |
|
Delphi uses // for a single line comment and both {} and (**) for multiple line comments. Although you can nest different types of multiple line comments, it is recommended that you don't. A special comment. Delphi compiler directives are in the form of {$DIRECTIVE}. Of interest for comments is using the $IFDEF compiler directive to remark out code.
//This is a single line comment. { Multiple line comment. } (* This too is a multiple line comment. *) {$IFDEF TEMPOUT} //...code here {$ENDIF}
|
|
13. Delphi Constants (Const kPI: Double=3.1459;) |
|
In Delphi, you define constants similar to how you define variables but use the Const keyword instead of the Var keyword. Declare global constants in a unit's interface section and unit constants (scope limited to unit) in the implementation section. Declare local constants above the begin..end block.
Const kFeetToMeter: Double = 3.2808; kMeterToFeet: Double = .3048; kName: String = "Mike"; //Local constants: procedure SomeProcedure; const kPI: Double=3.1459; begin end;
|
|
14. Delphi Development Tools |
|
Languages Focus: Development ToolsPrimary development tool(s) used to develop and debug code.
Delphi Development ToolsCodeGear Delphi is the primary tool of choice for most developers but other Object Pascal language development tools do exist and some are quite good.
|
|
15. Delphi End of Statement (;) |
|
Languages Focus: End of StatementIn coding languages, common End of statement specifiers include a semicolon and return (others exist too). Also of concern when studying a language is can you put two statements on a single code line and can you break a single statement into two or more code lines.
Delphi End of StatementObject Pascal uses a semicolon ";" as an end of statement specifier and you can put multiple statements on a single line of code and put a single statement on two or more code lines if you wish.
WriteLn('Hello1'); WriteLn('Hello2'); WriteLn('Hello3'); //Same line works too: WriteLn('Hello4'); WriteLn('Hello5'); //Two or more lines works too: WriteLn ('Hello6');
|
|
16. Delphi File Extensions |
|
Common source code file extensions include:
- .BDSPROJ - Project, Borland Developer Studio project file holds compiler options, etc. This is the file you open.
- .DCU - Delphi Compiled Unit file.
- .DFM - Delphi Win32 form file (a text resource file).
- .DPR - Delphi project file. Primary project "source" file.
- .PAS - Delphi unit source file.
|
|
17. Delphi If Statement (If..Else If..Else) |
|
Notice in the more complete example that the semicolon for the begin..end block after end is not included. That tells the compiler something else is coming (the statement is not finished). Also note the semicolon is missing right before the final "else" statement.
Note: The following example uses floating point literals. In Delphi, to specify a fractional floating point literal between 1 and -1, you preceed the decimal with a 0; otherwise, you will get a compiler error (i.e. .1 + .1 does not work).
if (0.1 + 0.1 + 0.1) = 0.3 then ShowMessage('Correct') else ShowMessage('Not correct'); //Complete example: if x = true then begin ShowMessage('x is true'); end Else If y = 'Mike' Then ShowMessage('hello mike') Else ShowMessage('last option');
|
|
18. Delphi Literals (apostrophe) |
|
Literals are single quoted (the apostrophe) as in 'Prestwood'. If you need to embed an apostrophe use two apostrophies in a row.
ShowMessage('Hello'); ShowMessage('Hello Mike''s website.');
|
|
19. Delphi Logical Operators |
|
Delphi logical operators:
and |
and, as in this and that |
or |
or, as in this or that |
not |
Not, as in Not This |
xor |
either or, as in this or that but not both |
//Given expressions a, b, c, and d: if Not (a and b) and (c or d) then //Do something.
|
|
20. Delphi Overview and History |
|
Language Overview: Delphi programming language is a type-safe language consisting of hybrid traditional Pascal and OOP features. You code either in a traditional approach using functions, procedures, and global data, or you code using an OOP approach, or a mixture of both.
Target Platforms: Delphi for Win32 is most suitable for creating native code Win32 applications that run on Microsoft Windows.
|
|
21. Delphi Parameters (var, const) |
|
Object Pascal allows parameters of the same type to be listed together, separated by commas, and followed with a single data type (more params of different data types can follow, after a semi-colon). The default for parameters is by value. For by reference, add var in front of the parameter. Object Pascal also offers constant parameters where you add const in front of the parameter. A constant parameter is like a local constant or read-only parameter the compiler can optimize. You cannot assign a value to a constant parameter, nor can you pass one as a var parameter to another routine.
function Add(a, b: integer) : integer; begin Result := a + b; end; procedure ReplaceTime(var pDT: TDateTime; const pNewDT: TDateTime); begin end;
|
|
22. Delphi Report Tools Overview |
|
Rave Reports comes closest to a Delphi standard now but historically there has been no real standard in Delphi development. Do-it-yourself developers sometimes like to use TPrinter for very simple reports. ReportSmith was bundled with the first few versions of Delphi.
Delphi has offered many embedded VCL component report options. Quick Reports has been a part of Delphi since Delphi 2.0 and has been the default report writer for many Delphi developers. Ace Reporter, ReportBuilder and Rave Reports are also very popular. During the time of Kylix, FastReports was popular because of it's cross-platform nature.
|
|
23. Delphi String Concatenation (+) |
|
Use the + operator to concatenate two strings. Use IntToStr to convert an integer to a string and FloatToStr to convert a floating point number to a string.
var FirstName : String; LastName : String; begin FirstName := 'Mike'; LastName := 'Prestwood'; ShowMessage('Full name: ' + FirstName + ' ' + LastName); ShowMessage(FloatToStr(3.2)); end;
|
|
24. Delphi Unary Operators |
|
An operation with only one operand (a single input). In Object Pascal, a unary operator always precedes its operand (for example, -B), except for ^, which follows its operand (for example, P^). The Delphi unary operators are +, -, and ^ (pointer).
The TYPE operator is also a unary operator and is�evaluated at compile time. The TYPE operator returns the size in bytes of the operand,
|
|
25. Delphi Variables (var x: Integer = 0;) |
|
Declare global variables in the interface section of a unit, variables declared within the implementation section (but not within a method) have a scope limited to the unit. You declare local variables in a var block outside (above) your begin..end code block. You cannot declare variables in-line (inside begin..end). You can initialize global and unit variables but you cannot initialize local variables. Delphi offers many variable types. Some common variable types include String, WideString, PChar, Integer, Boolean, Single, Double, Pointer, and Variant.
procedure SomeProcedure; var Fullname: String; Age: Integer; X, Y, Z: Double; MyArray: array [1..100] of Char; begin end; //You can initialize global variables. var ClickCounter: Integer = 0;
|
Topic: Language Details
|
26. Associative Arrays in Delphi/Object Pascal (Use TStringList) |
|
TStringList Example Object Pascal doesn't have a native associative array, but you can use a TStringList the same way. (Alternatively, search the Internet for TStringHash and THashedStringList classes for implementations of a true associative array).
var StateList : TStringList; begin StateList := TStringList.Create; //Create list.
//Add values comma separated. StateList.CommaText := 'CA=California, AR=Arizona'; StateList.CommaText := StateList.CommaText + ', FL=Florida'; //Also, can add individually. StateList.Add('NV=Nevada'); //Use it. ShowMessage('FL is ' + StateList.Values['FL']); end;
|
|
27. Delphi Associative Array (TStringList Assoc Array) |
|
Object Pascal doesn't have a native associative array, but you can use a TStringList the same way. (Alternatively, search the Internet for TStringHash and THashedStringList classes for implementations of a true associative array).
var StateList : TStringList; begin StateList := TStringList.Create; StateList.CommaText := 'CA=California, FL=Florida'; ShowMessage('FL is ' + StateList.Values['FL']); end;
|
|
28. Delphi Comparison Operators (=, <>) |
|
Common comparison operators:
= |
equal |
<> |
not equal |
< |
less than |
> |
greater than |
<= |
less than or equal |
>= |
greater than or equal |
//Does Delphi evaluate the math correctly? Yes! //Refer to math.pas MaxSingle for more info. if (0.1 + 0.1 + 0.1 = 0.3) then ShowMessage('correct') else ShowMessage('not correct')
|
|
29. Delphi Custom Routines (procedure, function) |
|
Delphi is a hybrid language so you can create either class methods (functions and procedures) or you can create global functions and procedures. When a function or procedure is part of a class, it is a class method. [function/procedure] RoutineName : ReturnType;
As with C++, your custom routine must come before it's first usage or you have to prototype it in the Interface section.
Note: Contrast Delphi with Delphi Prism which is an OOP language (everything is within a class). Both Delphi and Delphi Prism are based on Object Pascal but implement OOP features differently and have some syntax differences too.
procedure SayHello(pName: String); begin ShowMessage('Hello ' + pName); end; function Add(p1, p2 : Double): Double; begin Result := p1 + p2; end;
|
|
30. Delphi Inlining (Inline) |
|
Delphi introduced developer defined function and procedure inlining with Delphi 2005. Use the inline keyword to tell the compiler to inline a routine. Since Delphi will always inline the routine, make sure you test for speed because inlining a routine can lead to slower code under some circumstances.
function Add(a, b: Integer): Integer; inline; begin end;
|
|
31. Delphi LeftStr |
|
Delphi LeftStr
Uses StrUtils; ShowMessage(LeftStr('Prestwood', 3));
|
|
32. Delphi Overloading (overload) |
|
Object Pascal
- Operator - Yes. But not Pascal.
- Method - Yes.
function Add(a, b: integer): Integer; overload; begin Result := a+b; end;
function Add(const msg: String; a, b: integer): String; overload; begin Result := msg + IntToStr(a+b); end;
|
|
33. Delphi Pointers |
|
Although pointer data types in Delphi coding are less important and not required for most general coding, Delphi fully supports developer defined pointers. Use a carrot (^) to declare a pointer data type. Use the @ operator or Addr function to return the current address of a variable.
//Declare a pointer of type integer. PCounter : ^Integer; //Assign a value to the location of a pointer. //Also known as dereferencing. PCounter^ := 8; //Assign address of A to B. PointerB := @PointerA; //or...PointerB := Addr(PointerA);
|
|
34. Delphi Self Keyword (Self) |
|
Within the implementation of a method, the identifier Self references the object in which the method is called. The Self variable is an implicit parameter for each object method. A method can use this variable to refer to its owning class.
ShowMessage('Self=' + Self.ClassName);
|
|
35. Example: Using Sets in Borland Delphi |
|
Simple example of using sets in Delphi. Sets are similar to arrays and are convenient to use with 'in'.
procedure TForm1.Button7Click(Sender: TObject); var ValidStrings: Set of Char; begin ValidStrings := ['Y', 'N', 'X']; If 'Y' in ValidStrings then ShowMessage('Yes, Y is valid'); end;
|
Topic: OOP
|
36. Delphi Abstraction (abstract, override) |
|
Delphi for Win32 supports abstract class members using the abstract keyword. You can even instantiate instances of a class that contains abstract members. Then you override each abstract member in a descendant class with Override. Delphi does not support setting an entire class as abstract. You can create an abstract class (a class with one or more abstract methods), but there is no way to tell the compiler to not allow the instantiation of the abstract class. Delphi does not support abstract member properties directly. To implement an abstract properity, make use of abstract methods. That is, you can read a GetPropertyX abstract function and write to a SetPropertyX abstract procedure. In effect, creating an abstract property.
TCyborg = class(TObject) public procedure Speak(pMessage: String); virtual; abstract; procedure Walk; virtual; abstract; end; TSeries600 = class(TCyborg) public procedure Speak(pMessage: String); override; procedure Walk; override; end;
|
|
37. Delphi Base Class (TObject) |
|
In Delphi programming language (Object Pascal), all classes ultimately inherit from the base class TObject.
//Specify both namespace and class: TCyborg = class(System.TObject) end; //Use shortcut alias: TCyborg = class(TObject) end; //None, default is System.TObject TCyborg = class end;
|
|
38. Delphi Class Helpers (class helper for) |
|
Delphi allows you to extend an existing class without using inheritance. Buggy in 2005 and not officially supported but stable and usable in 2006 and above. You declare a class helper similiar to how you declare a class but use the keywords class helper for.
- You can name a helper anything.
- Helpers have access only to public members of the class.
- You cannot create an object instance directly from a class helper.
- self refers to the class being helped.
TCyborg = class(TObject) public FCyborgName: String; end;
TCyborgHelper = class helper for TCyborg procedure ShowClassName; end;
|
|
39. Delphi Class Members (Class) |
|
Object Pascal supports static methods, but not static member fields. For static member fields, use traditional Pascal-like global variables. Since Object Pascal is a hybrid language, you can use global functions and data so the need for class methods is diminished but still useful. Delphi 1-7: All classes in a unit are friendly (see eachother's private members), some developers like to put each class in it's own unit and reserve putting multiple classes in the same unit until they wish to implement friendly classes. Delphi 2005+: New strict keyword allows you to indicate friendly.
type TMyUtils = class(TObject) public class function MyStaticMethod: Integer; end;
In implimentation: class function TMyUtils.MyStaticMethod: Integer;
|
|
40. Delphi Class..Object (class..end..Create) |
|
Declare your class in the Interface section. Then implement the class in the Implementation section.
//Interface section: TCyborg = class(TObject) public procedure IntroduceYourself; end; //Implementation section; procedure TCyborg.IntroduceYourself; begin ShowMessage('Hi, I do not have a name yet.'); end; //Some event like a button click: var T1: TCyborg; begin T1 := T1.Create; T1.IntroduceYourself; FreeAndNil(T1); //Be sure to clean up! end;
|
|
41. Delphi Constructors (constructor) |
|
In Delphi, use the constructor keyword to signify which method or methods are constructors for a class. It is traditional but not required to use a procedure called Create.
In addition to having multiple named constructors, you can overload constructors.
//Interface section. TCyborg = class(TObject) public constructor Create; end;
Then implement the class constructor in the Implementation section. constructor TCyborg.Create; begin inherited; //Call the parent Create method end;
|
|
42. Delphi Destructor (Free or FreeAndNil) |
|
Object Pascal uses a standard virtual destructor named Destroy which is called by the standard Free method. All objects are dynamic, so you need to call MyObject.Free method or the FreeAndNil(MyObject) routine for each object you create.
var MyObject: TObject; begin MyObject := TObject.Create; //Use it... MyObject.Free //Or use...FreeAndNil(MyObject); end;
|
|
43. Delphi Inheritance (=class(ParentClass)) |
|
In Delphi, you use the class keyword followed by the parent class in parens. If you leave out the parent class, your class inherits from TObject.
In the following example, a terminator T-600 is-an android. TAndroid = class end; T-600 = class(TAndroid) end;
|
|
44. Delphi Inheritance-Multiple (Not Supported) |
|
Delphi does not support multiple implementation inheritance. Each class can have only one parent class (a single inheritance path). In Delphi, you can use multiple interface usage to design in a multiple class way horizontally in a class hierarchy.
|
|
45. Delphi Interfaces (IInterface, TInterfacedObject) |
|
You specify an interface in the type block just like you do for a class but you use the interface keywoard instead of the class keyword and in the interfaces section only. Since interfaces, by definition, do not have any implementation details, all you do is specifiy it in the type block.
//Language interface: //Interface section of unit. IHuman = Interface(IInterface) //Specify interface methods and properties here.
end; TCyborg = class(TInterfacedObject) end; TCyborgHuman = class(TCyborg, IHuman) //Specify each here and implement in //implementation section. end;
|
|
46. Delphi Member Field |
|
In Delphi, it is common to start all member fields with "F" as in FName and FAge. You can initialize the value of member fields. Delphi member fields do not support static data. The workaround is to use the hybrid nature of Delphi and use a unit variable (a variable declared in the implementation section of a unit).
TCyborg = class(TObject) private FSerialNumber: String='A100'; public FCyborgName: String; FCyborgAge: Integer=0; FSeriesID: Integer=100; end;
|
|
47. Delphi Member Method (procedure, function) |
|
Delphi uses the keywords procedure and function. A procedure does not return a value and a function does.
//Interface section: TCyborg = class(TObject) public procedure IntroduceYourself; end; //Implementation section; procedure TCyborg.IntroduceYourself; begin ShowMessage('Hi, I do not have a name yet.'); end; //Some event like a button click: var T1: TCyborg; begin T1 := T1.Create; T1.IntroduceYourself; end;
|
|
48. Delphi Member Modifiers |
|
Specify Delphi member modifiers as follows:
reintroduce; overload; [binding modifier]; [calling convention]; abstract; [warning]
The binding modifiers are virtual, dynamic, or override. The calling conventions are register, pascal, cdecl, stdcall, or safecall. The warnings are platform, deprecated, or library. Additional directives include reintroduce, abstract, class, static, overload, and message.
TCyborg = class(TObject) public procedure Speak(pMessage: String); virtual; end; TSeries888 = class(TCyborg) public procedure Speak(pMessage: String); override; end;
|
|
49. Delphi Member Property (property..read..write) |
|
Delphi uses a special property keyword to both get and set the values of properties. The read and write keywords are used to get and set the value of the property directly or through an accessor method. For a read-only property, leave out the write portion of the declaration. You can give properties any visibility you wish (private, protected, etc). It is common in Delphi to start member fields with "F" ("FName" in our example) and drop the "F" with properties that manage member fields ("Name" in our example).
TCyborg = class(TObject) private FCName: String; public property CyborgName: String read FCName write FCName; end;
|
|
50. Delphi Member Visibility |
|
Up until D2005, private and protected were not implemented strictly. Starting with D2005, a traditional strict versions of OOP are supported using the strict keyword. OO purist will want you to use strict private over private and strict protected over protected. I suggest you follow that advice until you both fully understand the differences and have a specific need. Delphi offers a special published specifier which is the same as public members but runtime type information (RTTI) is generated.
TCyborg = class(System.Object) private //Don't use accept when you really want private friendly members. strict private //Use as your default private members. FName: String; protected //Don't use accept when you really want protected friendly members. strict protected //Use as your default protected members. public
published //RTTI Info
end;
|
|
51. Delphi Overriding (virtual, override) |
|
In Delphi, you specify a virtual method with the virtual keyword in a parent class and replace it in a descendant class using the override keyword. Call Inherited in the descendant method to execute the code in the parent method.
TRobot = class(TObject) public procedure Speak; virtual; end;
TCyborg = class(TRobot) procedure Speak; Override; end;
|
|
52. Delphi Polymorphism |
|
Delphi supports the following types of polymorphism:
|
|
53. Delphi Sealed class (sealed, final) |
|
With Delphi, use the sealed keyword to prevent a class from being inherited from and use the final keyword to prevent a method from being overridden.
type Robot = class sealed(TObject) public procedure Speak(pSentence: String); virtual; final; end;
|
Topic: Using Data
|
54. Application.ProcessMessages |
|
I always found the sleep command in ObjectPAL very useful. The following code does about the same thing in Delphi. It makes use of GetTickCount which is a Win32 API call that retrieves the number of milliseconds that have elapsed since the system was started, up to 49.7 days.
procedure TUtils.Delay(MillisecondsDelay: Integer); var FirstTickCount: LongInt; begin FirstTickCount := GetTickCount; repeat Application.ProcessMessages; until ((GetTickCount-FirstTickCount) >= Longint(MillisecondsDelay)); end;
|
|
55. Create Round Windows |
|
Use SetWindowRgn API call to make a round form. The SetWindowRgn function sets the window region of a window. The window region determines the area within the window where the operating system permits drawing. The operating system does not display any portion of a window that lies outside of the window region.
Simply use this function in the FormCreate event:
procedure TForm.FormCreate(Sender: TObject); var R1: HRGN; R2: HRGN;
begin R1 := CreateEllipticRgn(1, -1, Width - 1, Height); R2 := CreateEllipticRgn(50, 50, Width - 50, Height - 50); CombineRgn(R2, R1, R2, RGN_XOR); SetWindowRgn(Handle, R2, True); end;
|
|
|