Thursday 28 May 2015

Learn Delphi Quickly


1. Language Overview

DELPHI LANGUAGE OVERVIEW:-
  •  Delphi was originally developed by Borland as a RAD tool for windows and as a successor of Borland pascal, later on it was sold to Embarcadero Technologies in 2008.
  •  Delphi is a high level, compiled and strongly typed language.
  • It supports both structured and object oriented design.
  • Support RAD application development environment and borland's component framework.
  • Delphi compiler uses object pascal and generate source code for several platforms like  Win32,.Net,IOS mac and android.
  • IDE -Integrated Development Environment for writing code.
  • VCL - visual component library.
  • Borland development tools handle many details of setting up projects and source files, such as maintenance of dependency information among units.

PROGRAM ORGANIZATION:-

Delphi programs are usually divided into source-code modules called units. Most programs begin with a program heading, which specifies a name for the program. The program heading is followed by an optional uses clause, then a block of declarations and statements. The uses clause lists units that are linked into the program; these units, which can be shared by different programs, often have uses clauses of their own.

Delphi source files :-
  • Unit source files (.pass ext).
  • Project files (.dpr ext).
  • Package source files (.dpk ext).

Unit source files:-
    Delphi programs are usually divided into source code modules called Units.
    most of the source code of the application is written into unit files.
    one program/application can contains multiple unit files.
   
Project files :-
    Each application has single project files and multiple unit files.
    Project file corresponds to program file, organize the unit files into an application.
   
    If you are compiling your delphi program from command line, put all your code in unit file (.pass).
    if you are compiling your delphi program form IDE , then it will generate a project file (.dpr).
   
Package source files:-
    Similar to project files, used to construct special dynamically linkable libraries called packages.


 Other files used to build application:-

In addition to source code module, it uses several non pascal files to build application.
These files are maintained by IDE.
  • VCL (visual component library ) form file (.dfm on Win32 and .nfm on .Net)
  • Resource files (.res ).
  • project option files (.dof )
VCL form file:-
  • contains description and properties of the form and components.
  • Each form represent a single form, usually corresponds to window or dialog box in an application.
  • Each application has atleast one form and has associated unit files (.pass).
  • by default it has the same name as of unit file.

Resource file:-
  • It holds application's icon.
  • By default its name is same as of project file.
Project options file :-
  • contains compiler and linker setting,search path information, version information etc.
 Compiler generated files :-

  • compiling first time, compiler will generate compiled unit files corresponds to each unit file (.dcu on Win32 and .dcuil on .Net), and then all .dcu files linked to create a single executable file.
  • If you added some new unit files in project or application then it will compile only new added unit files and linked with already compiled unit files and create a single executable files.
  • On compilation only modified unit files are compiled not all. (just like makefile used in C/C++)
 Delphi Program:
 Mainly two types of program can be develop in Delphi.
  • Console application
  • VCL(GUI) based application
 Both type of environment is available on Embarcaredo IDE.

Console based application:-
Console environment is provided by Embarcaredo IDE or a separate exe file dcc32 or dcc64 for 32 bit and 64 bit windows can be downloaded for console environment.

Example: Write a simple 'Hello Word' program in console environment.

program greeting;
{$APPTYPE CONSOLE}
         var MyMessage string;

begin
         MyMessage := 'Hello world!';
         Writeln(MyMessage);
end.


The first line declares a program called Greeting. The {$APPTYPE CONSOLE} directive tells the compiler that this is a console application, to be run from the command line. The next line declares a variable called MyMessage, which holds a string. (Delphi has genuine string data types.) The program then assigns the string "Hello world!" to the variable MyMessage, and sends the contents of MyMessage to the standard output using the Writeln procedure. (Writeln is defined implicitly in the System unit, which the compiler automatically includes in every application.)

You can type this program into a file called greeting.pas or greeting.dpr.
compile:
dcc32 greeting
to produce a Win32 executable

VCL (GUI) based application:
Here developed application is created using visual component library in IDE. This
program uses automatically generated form and resource files, so you won't be able to compile it from the source code alone. But it illustrates important features of the Delphi Language. In addition to multiple units, the program uses classes and objects.

Example:
Suppose you a developing a VCL application having one button on form by clicking on that, it will show a popup message 'hello world' in message box.

when you will open new VCL application it will opened form. look at the bottom right, search for button and drag that button on form.






On IDE you will see two tab Code and Diagram. By clicking on the code tab you can go to the GUI corresponding code generated by IDE.

Code:-

unit Unit1;
interface
              uses SysUtils, Types, Classes, Graphics, Controls, Forms, Dialogs;
type
              TForm2 = class(TForm)
              Button1: TButton;
               procedure Button1Click(Sender: TObject);
end;
var
         Form1: TForm1;
implementation

      






  {$R *.dfm}
          procedure TForm1.Button1Click(Sender: TObject);
          begin
                  showMessage("Hello World");
           end;
end.


Save the  program as <name> it will saved as name.pas
save project as <name> it will save as name.dpr



Unit file structure and syntax:
A unit consists of types (including classes), constants, variables, and routines (functions and procedures).

unit Unit1;

interface // its a public section of the unit, declare function / procedures, variables which will be accessible by other units and programs


uses // List of unit dependencies goes here...

implementation // its a private section of the unit, elements defined/declared here is private to that unit only.

uses // List of unit dependencies goes here...
// Implementation of class methods, procedures, and functions goes here...

initialization (optional)
// Unit initialization code goes here...and its optional
So, for example, if you have defined data structures that need to be initialized, you can do this in the initialization section.

finalization (optional)
// Unit finalization code goes here...
end.


The Unit heading:
Name of the heading.Unit names must be unique within a project. Even if their unit files are in different directories, two units with the same name cannot be used in a single program.

The Interface section:
The interface section declares constants, types, variables, procedures, and functions that are available to clients. That is, to other units or programs that wish to use elements from this unit. These entities are called public because code in other units can access them as if they were declared in the unit itself.
The interface declaration of a procedure or function includes only the routine's signature.
   
The Implementation section:
This section defines the procedures and functions declare in Interface section.The implementation section can declare constants, types (including classes), variables, procedures, and functions that are private to the unit.
   
The Initialization section:
The initialization section is optional. It begins with the reserved word initialization and continues until the beginning of the finalization section or, if there is no finalization section, until the end of the unit.So, for example, if you have defined data structures that need to be initialized, you can do this in the initialization section.
For units in the interface uses list, the initialization sections of the units used by a client are executed in the order in which the units appear in the client's uses clause.
   
   
The finalization section:  
 The finalization section is optional and can appear only in units that have an initialization section. The finalization section begins with the reserved word finalization and continues until the end of the unit. It contains statements that are executed when the main program terminates (unless the Halt procedure is used to terminate the program). Use the finalization section to free resources that are allocated in the initialization section.
Finalization sections are executed in the opposite order from initialization sections. For example, if your application initializes units A, B, and C, in that order, it will finalize them in the order C, B, and A.
Once a unit's initialization code starts to execute, the corresponding finalization section is guaranteed to execute when the application shuts down.


2.Data Types,Variables and Constants

Data Types:-

1)Ordinal Type:
Integer type
character type
boolean type
enumerated type


Definition of the all these are same as in C++.

2) String Type:
    Short strings (ShortString)
    8bit
    
   ANSI strings (AnsiString)
    8 bit` : only use for dynamic memory creation, space allotted in heap)

    Unicode strings (UnicodeString and WideString)
    Unicode strings: 8 bit (default string used in Delphi) --use for both static as well as dynamic     memory creation.
     
     Wide String: some character are 16 bit and some are more than 16 or less than 16 bit. Uses multibyte string.
   
3) Structured type:-

    Sets
    Arrays, including static and dynamic arrays
    Records
    File types

a) Sets:    A set is a collection of values of the same ordinal type. The values have no inherent order, nor is it meaningful for a value to be included twice in a set.

   Examples:-
   type
   TSomeInts = 1..250;
   TIntSet = set of TSomeInts;
  
   type TIntSet = set of 1..250;
   
    var Set1, Set2: TIntSet;
     ...
     Set1 := [1, 3, 5, 7, 9];
     Set2 := [2, 4, 6, 8, 10]
   
    var MySet: set of 'a'..'z';
   
b) Array:    An array represents an indexed collection of elements of the same type (called the base type). Because each element has a unique index, arrays, unlike sets, can meaningfully contain the same value more than once. Arrays can be allocated statically or dynamically.
   
    static array:
        var MyArray: array [1..100] of Char;
       
    A multidimensional array is an array of arrays. For example:
        type TMatrix = array[1..10] of array[1..50] of Real;
   
    is equivalent to
    type TMatrix = array[1..10, 1..50] of Real;
   
    Dynamic array:
    Dynamic arrays do not have a fixed size or length. Instead, memory for a dynamic array is reallocated when you assign a value to the array or pass it to the SetLength procedure.
    Ex:-
    var MyFlexibleArray: array of Real;
    SetLength(MyFlexibleArray, 20);

    allocates an array of 20 reals, indexed 0 to 19.
   
    Dynamic-array variables are implicitly pointers and are managed by the same reference-counting technique used for long strings. To deallocate a dynamic array, assign nil to a variable that references the array or pass the variable to Finalize;
   

4) Pointer and pointer type:
 1         var
 2           X, Y: Integer;  // X and Y are Integer variables
 3           P: ^Integer     // P points to an Integer    {its similar to int * P;}
 4         begin
 5           X := 17;      // assign a value to X
 6           P := @X;      // assign the address of X to P
 7           Y := P^;      // dereference P; assign the result to Y { and its similar to Y = *P}
 8         end;
 


 5) Procedural type :-
Procedural types allow you to treat procedures and functions as values that can be assigned to variables or passed to other procedures and functions.
   
    Ex:-
    function Calc(X,Y: Integer): Integer;
    You can assign the Calc function to the variable F:
    var F: function(X,Y: Integer): Integer;
    F := Calc;


   
 The assignment makes the variable on the left a pointer to the function or procedure indicated on the right. In other contexts, however, using a procedural variable results in a call to the referenced procedure or function. You can even use a procedural variable to pass parameters:
   
   Ex:-
   var
   F: function(X: Integer): Integer;
   I: Integer;
   function SomeFunction(X: Integer): Integer;
     ...
   F := SomeFunction;    // assign SomeFunction to F
   I := F(4);            // call function; assign result to I

  
   Ex:-
  
   var
   F, G: function: Integer;
   I: Integer;
   function SomeFunction: Integer;
     ...
   F := SomeFunction;      // assign SomeFunction to F
   G := F;                 // copy F to G
   I := G;                 // call function; assign result to I



6) Variant Type:-
Sometimes it is necessary to manipulate data whose type varies or cannot be determined at compile time. In these cases, one option is to use variables and parameters of type Variant, which represent values that can change type at run time. Variants offer greater flexibility but consume more memory than regular variables, and operations on them are slower than on statically bound types.

Ex:-

var
   V1, V2, V3, V4, V5: Variant;
   I: Integer;
   D: Double;
   S: string;
 begin
    V1 := 1;         { integer value }
    V2 := 1234.5678; { real value }
    V3 := 'Hello world!'; { string value }
    V4 := '1000';         { string value }
    V5 := V1 + V2 + V4;   { real value 2235.5678}
    I  := V1;             { I = 1 (integer value) }
    D  := V2;              { D = 1234.5678 (real value) }
    S  := V3;              { S = 'Hello world!' (string value) }
    I  := V4;              { I = 1000 (integer value) }
    S  := V5;              { S = '2235.5678' (string value) }
 end;

    Variant Arrays:-
        V: Variant;
        ...
        V := VarArrayCreate([0,9], varInteger)
;
   

creates a variant array of integers (of length 10) and assigns it to the variant V. The array can be indexed using V[0], V[1], and so forth, but it is not possible to pass a variant array element as a var parameter. Variant arrays are always indexed with integers.
       

 3. Procedures and Functions:

About Procedures and Functions:
Procedures and functions, referred to collectively as routines, are self-contained statement blocks that can be called from different locations in a program. A function is a routine that returns a value when it executes. A procedure is a routine that does not return a value.

Function call:-
I := SomeFunction(X);
if extended syntax ({$X+}) is enable, then function call can used as complete statement.
Example:
SomeFunction(x)
in this case return value of function is disable.

Procedure Declarations:
 procedure procedureName(parameterList); directives;
 localDeclarations;
 begin
   statements;
 end;



Function declaration:-
 function functionName(parameterList): returnType; directives;
 localDeclarations;
 begin
      statements
 end;
 

 Result and the function name always represent the same value. Hence:
 Example:-
 function MyFunction: Integer;
 begin
   MyFunction := 5;
   Result := Result * 2;
   MyFunction := Result + 1;
 end;


***But Result is not completely interchangeable with the function name. When the function name appears on the left side of an assignment statement, the compiler assumes that it is being used (like Result) to track the return value; when the function name appears anywhere else in the statement block, the compiler interprets it as a recursive call to the function itself. Result, on the other hand, can be used as a variable in operations, typecasts, set constructors, indexes, and calls to other routines.

If the function exits without assigning a value to Result or the function name, then the function's return value is undefined.


4. Classes and Objects

Private, Protected,Public Members and Published or Automated access specifier :-A private member is invisible outside of the unit or program where its class is declared. In other words, a private method cannot be called from another module, and a private field or property cannot be read or written to from another module.

A protected member is visible anywhere in the module where its class is declared and from any descendent class, regardless of the module where the descendent class appears. A protected method can be called, and a protected field or property read or written to, from the definition of any method belonging to a class that descends from the one where the protected member is declared.
A public member is visible wherever its class can be referenced.


Strict visibility specifier:-
Class members with strict private visibility are accessible only within the class in which they are declared. They are not visible to procedures or functions declared within the same unit.

Class members with strict protected visibility are visible within the class in which they are declared, and within any descendent class, regardless of where it is declared.


Published Members:-
Published members have the same visibility as public members. The difference is that runtime type information(RTTI) is generated for published members.

Automated Members (Win32 Only):-

Automated members have the same visibility as public members. The difference is that Automation type information(required for Automation servers) is generated for automated members.
The automated reserved word is maintained for backward compatibility.


Object Creation:-
Given this declaration, you can create an instance of class TMemoryStream as follows:

var
  stream: TMemoryStream;

begin
  stream := TMemoryStream.Create;

end

Inheritance:-
type TSomeControl = class(TControl);

declares a class called TSomeControl that descends from  TControl.
If we compare it with java or C++ then TSomeControl is the derived class and TControl is the base class.

 TObject and TClass:-
The System.TObject class, declared in the System unit, is the ultimate ancestor of all other classes. System.TObject defines only a handful of methods, including a basic constructor and destructor. In addition to System.TObject, the System unit declares the class reference type System.TClass:

 TClass = class of TObject;

If the declaration of a class type does not specify an ancestor, the class inherits directly from System.TObject. Thus:

type TMyClass = class
      ...
     end;

is equivalent to:

type TMyClass = class(TObject)
      ...
     end;


Fields:-A field is like a variable that belongs to an object. Fields can be of any type, including class types. (That is, fields can hold object references.) Fields are usually private.
Fields are statically bound; that is, references to them are fixed at compile time.
Example:
type
    TAncestor = class
    Value: Integer;
end;

TDescendant = class(TAncestor) //TDescendant class is derived from class TAncestor
    Value: string; // hides the inherited Value field
end;

var
    MyObject: TAncestor; // object of base class
   
begin
    MyObject := TDescendant.Create; // referring to derived class
    MyObject.Value := 'Hello!' // error
    (MyObject as TDescendant).Value := 'Hello!' // works!
end;



Class fields:-
Class fields are data fields in a class that can be accessed without an object reference.
class fields can be listed under 'class var' block.
class var block can be terminated by the following.
1) By declaring another class var block.
2) By declaring routines (functions/procudures)
3) By declaring constructor/destructor.
4) Property declaration.
5) visibility scope specifier (public/protected/private/published)





Example:
type
TMyClass = class
    public
        class var // Introduce a block of class static fields.
            Red: Integer;
            Green: Integer;
            Blue: Integer;
        procedure Proc1; // Ends the class var block.
end;


The above class fields can be accessed with the code:
TMyClass.Red := 0;
TMyClass.Green := 0;
TMyClass.Blue := 0;
 


Methods:-
Method declaration:-

type
        TMyClass = class(TObject) // class
        ...
            procedure DoSomething; //method declaration
        ...
    end;


 Method definition :-
    procedure TMyClass.DoSomething;
    begin
        ...
    end;


    self :-
        self is like a this pointer in C++, which represent the object of the class where its used.
      
Method binding:-
Method binding can be static (by default), dynamic or virtual. Dynamic and virtual methods can be overridden and they can be abstract.

Static methods:-
Method are by default static. This method get bind to respective object at compile time only.

Example:
type
    TFigure = class
    procedure Draw; // here method draw is static
end;

TRectangle = class(TFigure)
    procedure Draw; //here method draw is static
end;

var
    Figure: TFigure;
    Rectangle: TRectangle;
begin
    Figure := TFigure.Create;
    Figure.Draw; // calls TFigure.Draw
    Figure.Destroy;
    Figure := TRectangle.Create; //Figure is the object of TFigure and here it reference to derived class TRectangle
    Figure.Draw; // calls TFigure.Draw ..as this draw got bound to TFigure class at compile time.
    TRectangle(Figure).Draw; // calls TRectangle.Draw
    Figure.Destroy;
    Rectangle := TRectangle.Create;
    Rectangle.Draw; // calls TRectangle.Draw
    Rectangle.Destroy;
end;


Virtual and Dynamic methods:-
To make a method virtual or dynamic, include the virtual or dynamic directive in its declaration. Virtual and dynamic methods, unlike static methods, can be overridden in descendant classes.

Example:

type
    TFigure = class
    procedure Draw; virtual;
end;
    TRectangle = class(TFigure)
    procedure Draw; override;
end;
    TEllipse = class(TFigure)
    procedure Draw; override;
end;
var
    Figure: TFigure;
begin
    Figure := TRectangle.Create;
    Figure.Draw; // calls TRectangle.Draw
    Figure.Destroy;
    Figure := TEllipse.Create;
    Figure.Draw; // calls TEllipse.Draw
    Figure.Destroy;
end;


Overriding Versus Hiding:-
If the method declare in base class is virtual and same method name is declared in derived class without including override then the new declaration hides the inherited one without overriding it.

Example:
type
    T1 = class(TObject)
    procedure Act; virtual;
end;
    T2 = class(T1)
    procedure Act; // Act is redeclared, but not overridden
end;

var
    SomeObject: T1;
begin
    SomeObject := T2.Create;
    SomeObject.Act; // calls T1.Act
end;


Abstract Methods:-
An abstract method is a virtual or dynamic method that has no implementation in the class where it is declared. Its implementation is deferred to a descendant class. Abstract methods must be declared with the directive abstract after virtual or dynamic.

For example,
procedure DoSomething; virtual; abstract;

You can call an abstract method only in a class or instance of a class in which the method has been overridden.

Reintroduce:-
The reintroduce directive suppresses compiler warnings about hiding previously declared virtual methods.

For example,
procedure DoSomething; reintroduce; // the ancestor class also has a DoSomething method

Use reintroduce when you want to hide an inherited virtual method with a new one.

Overloading Methods:-
A method can be redeclared using the overload directive. In this case, if the redeclared method has a different parameter signature from its ancestor, it overloads the inherited method without hiding it.

If you overload a virtual method, use the reintroduce directive when you redeclare it in descendant classes.
Example:
type
    T1 = class(TObject)
    procedure Test(I: Integer); overload; virtual;
end;
    T2 = class(T1)
    procedure Test(S: string); reintroduce; overload;
end;
    ...
    SomeObject := T2.Create;
    SomeObject.Test('Hello!'); // calls T2.Test
    SomeObject.Test(7); // calls T1.Test


Constructor and Destructor:-

Constructor:-

The declaration of a constructor looks like a procedure declaration, but it begins with the word constructor.

Examples:
constructor Create;
constructor Create(AOwner: TComponent);

constructor returns a reference to the object it creates or is called in.
MyObject := TMyClass.Create;

This allocates storage for the new object, sets the values of all ordinal fields to zero, assigns nil to all pointer and
class-type fields, and makes all string fields empty.

Destructor:-
A destructor is a special method that destroys the object where it is called and deallocates its memory.
It begins with word destructor.

Example:
MyObject.Destroy;

Destructor implementation:-
Example:
destructor TShape.Destroy;
begin
    FBrush.Free;
    FPen.Free;
    inherited Destroy;
end;


here the last action in a destructor's implementation is typically to call the inherited destructor to destroy the object's inherited fields.
When an exception is raised during creation of an object, Destroy is automatically called to dispose of the unfinished object. This means that Destroy must be prepared to dispose of partially constructed objects.


Properties:-
  • Property access
  • Array properties
  • Index specifiers
  • Storage specifiers
  • Property overrides and redeclaration. 

 

5. Exception Handling

Exception Handling:
its the same like we uses in C++/java.

c++/java try/throw/catch or try/throw/finally -----> Delphi try/raise/except or try/raise/finally.
Example1:
try
    X := Y/Z;
except
    on EZeroDivide do HandleZeroDivide;
end;


Example2:
Except block support else clause.

try
...
except
    on EZeroDivide do HandleZeroDivide;
    on EOverflow do HandleOverflow;
    on EMathError do HandleMathError;
else
    HandleAllOthers;
end;



Example3:
HandleException handles any type of exception.

try
...
except
    HandleException;
end;


Example4:
try
...
except
    on E: Exception do ErrorDialog(E.Message, E.HelpContext);
end;



6. Memory Management

Memory Management:-
Here in Delphi, memory management is same as in C/C++.
If you have created memory in heap, you will have to free it manually.
There is nothing like JVM in Delphi.

Here memory created by class object in Heap not in stack. So if you have created a class object, you will have to free it.

Example:
myObject := myClass.create; // object created

myObject.destroy; //object destroyed


Memory creation:-
new() and getMem() functions are used to create dynamic memory at run time.

Memory clean up:-
free() and destroy are used to free memory, dynamically created.

7. Libraries and Packages:

Dynamic loadable library:- 
This is a Dynamic link library. It is a collection of routines that can be called by applications and by other DLLs or shared objects.
Like units, dynamically loadable libraries contain sharable code or resources.
But this type of library is a separately compiled executable that is linked, at run time, to the programs that use it.
Application written in other languages can call DLL written in Delphi.
And application written in delphi can call DLL written in other language.


Calling Dynamically Loadable Libraries:-
Before you can call routines defined in DLL or assembly, you must import them. This can be done by declaring an external procedure or function.
Example:
 
procedure DoSomething; external 'MYLIB.DLL';

Note;-this is called static loading , here library will get loaded, when program starts. Later on will see to load library dynamically.

If you include this declaration in a program, MYLIB.DLL is loaded once, when the program starts.
Throughout the execution of the program, the identifier DoSomething always refers to the same entry point in the same shared library.

Delay Loading:-
The delayed directive can be used to decorate an external routine to delay the loading of the library containing the routine.
The actual loading happens when the routine is called for the first time.
 Example: 
function GetSomething: Integer; external 'somelibrary.dll' delayed;

Dynamic Loading (Windows-only) :- 
you can also import routines or load libraries by direct call to windows API including LoadLibrary, FreeLibrary, and GetProcAddress.
These functions are declared in Windows.pas. So we have to use uses clause window in our module/unit file where we are importing routines.

Note: here library gets loaded when LoadLibrary gets called.

Writing dynamically loaded library:-
Writing DLL has following elements.
  • The export clause.
  • Library Initialization code.
  • Global Variable
  • Libraries and system variables.
Using Export clause:-library MinMax; // name of library MinMax.dll
function Min(X, Y: Integer): Integer; stdcall; //function definition
begin
  if X < Y then Min := X else Min := Y;
end;
function Max(X, Y: Integer): Integer; stdcall; //function definition
begin
  if X > Y then Max := X else Max := Y;
end;
exports // Export functions , which can be imported from other applications.
  Min,
  Max;
  begin
 end.
 


If you want your library to be available to applications written in other languages, it's safest to specify stdcall in the declarations of exported functions.

Use a name clause when you want to export a routine under a different name.
Example:
exports
DoSomethingABC name 'DoSomething'; // can be imported by the name DoSomething.