Delphi: Difference between revisions

From miki
Jump to navigation Jump to search
(→‎Class Basics: Constructors and destructors)
Line 36: Line 36:
|}
|}


== Basics ==
== Class Basics ==
Some very basic stuff, but which are particular to Delphi language.
Some very basic stuff on classes in Delphi.
* All classes in Delphi always derives by default from the class <tt>TObject</tt>. The 2 declarations below are identical:
* Class object are not created by default. One must call the constructor explicitly...
<div style="padding-left:2em;"><source lang="delphi">
<div style="padding-left:2em;"><source lang="delphi">
type
type
TMyClass = class
TMyFirstClass = class;
TMySecondClass = class(TObject);
</source></div>
* Constructors and destructors are declared like this:
<div style="padding-left:2em;"><source lang="delphi">
type
TMyClass = class;
public
constructor Create;
destructor Destroy; override;
end;
</source></div>
* Constructors are not '''virtual''' function, but destructors usually are (so that it can be called by <tt>Free</tt> declared in <tt>TObject</tt>.
* '''Constructors''' are never automatically called for objects declared as global variables or as member of other classes. They must be called explicitly...
<div style="padding-left:2em;"><source lang="delphi">
type
TMyClass = class;
public
public
constructor Create;
constructor Create;
Line 51: Line 67:
procedure TFrmForm1.FormCreate(Sender: TObject);
procedure TFrmForm1.FormCreate(Sender: TObject);
begin
begin
myObject := TMyClass.Create(); // objects are assigned result of constructor call!
myObject := TMyClass.Create; // objects are assigned result of constructor call!
end;
end;
</source></div>
</source></div>

* Same applies to '''destructors'''. However never call destructors directly. Instead call <tt>Free</tt> which test for '''nil''' before calling the destructor:
<div style="padding-left:2em;"><source lang="delphi">
myObject := TMyClass.Create;
// ...
myObject.Destroy; //Dangerous. Fail if myObject is nil
myObject.Free; //Safer. Doesn't fail if myObject is nil
</source></div>
* This is also true for '''arrays''' of objects. Arrays will only contain the ''reference'' to the object. These references must be initialized with a call to the constructors for each element in the array. Elements must be destroyed


== Dialog box ==
== Dialog box ==

Revision as of 10:36, 19 March 2009

A meager attempt to recover my old knowledge on Delphi 7...

References

  • The ultimate reference on Delphi with lots of examples at [1]

Keyboard shortcuts

Some frequently used keyboard shortcuts that any decent programmer should always use:

Shortcut Description
Ctrl+Shift+↑ Go to method declaration
Ctrl+Shift+↓ Go to method definition
Ctrl+Shift-C Auto-complete class (eg. use it when declaring new class method, and cursor still on method declaration)
Ctrl+J Insert code template
Ctrl+Space Code auto-complete
Ctrl+K+I Indent code
Ctrl+K+U Unindent code
Ctrl+left click Go to identifier definition

Class Basics

Some very basic stuff on classes in Delphi.

  • All classes in Delphi always derives by default from the class TObject. The 2 declarations below are identical:
type
  TMyFirstClass = class;
  TMySecondClass = class(TObject);
  • Constructors and destructors are declared like this:
type
  TMyClass = class;
  public
    constructor Create;
    destructor Destroy; override;
  end;
  • Constructors are not virtual function, but destructors usually are (so that it can be called by Free declared in TObject.
  • Constructors are never automatically called for objects declared as global variables or as member of other classes. They must be called explicitly...
type
  TMyClass = class;
  public
    constructor Create;
  end;

var
  myObject: TMyClass;

procedure TFrmForm1.FormCreate(Sender: TObject);
begin
  myObject := TMyClass.Create;        // objects are assigned result of constructor call!
end;
  • Same applies to destructors. However never call destructors directly. Instead call Free which test for nil before calling the destructor:
  myObject := TMyClass.Create;
  // ...
  myObject.Destroy;            //Dangerous. Fail if myObject is nil
  myObject.Free;               //Safer. Doesn't fail if myObject is nil
  • This is also true for arrays of objects. Arrays will only contain the reference to the object. These references must be initialized with a call to the constructors for each element in the array. Elements must be destroyed

Dialog box

  • Use InputBox to bring up an input dialog box ready for the user to enter a string in its edit box. InputQuery offers similar functionality.
procedure TForm1.Button1Click(Sender: TObject);
begin
  Label1.Caption:=InputBox('Question', 'Enter string', 'Default');
end;
  • Use MessageDlg to display a message dialog box in the center of the screen
  • Use ShowMessage to display a message box with an OK button.
  • See help on QDialogs routines for more.
  • Add a Don't show this message again to a standard dialog box:
procedure TForm1.Button1Click(Sender: TObject) ;
var
  AMsgDialog: TForm;
  ACheckBox: TCheckBox;
begin
  AMsgDialog := CreateMessageDialog('This is a test message.', mtWarning, [mbYes, mbNo]) ;
  ACheckBox := TCheckBox.Create(AMsgDialog) ;
  with AMsgDialog do
  try
    Caption := 'Dialog Title' ;
    Height := 169;

    with ACheckBox do
    begin
      Parent := AMsgDialog;
      Caption := 'Don''t show me again.';
      Top := 121;
      Left := 8;
    end;

    if (ShowModal = ID_YES) then
    begin
      if ACheckBox.Checked then
        //do if checked
      else
        //do if NOT checked 
    end;
  finally
    Free;
  end;
end;

TStringGrid, TDBGrid

  • Check this great post to know how to use colors in TDBGrid [2].
  • Here an example on how to format cells in TStringGrid. Use the OnDrawCell event. Note that property DefaultDrawing is set to True so that cells are drawn with default formatting (incl. focus and background).
procedure TFrmMultiply.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
begin
  if(ACol=5) then
  begin
    if(StringGrid1.Cells[6,ARow]='') then
    begin
      StringGrid1.Canvas.Font.Color := clGreen;
      StringGrid1.Canvas.Font.Style := [fsBold,fsStrikeOut]
    end;
    //Redraw the current cell - code took from TStringGrid.DrawCell
    StringGrid1.Canvas.TextRect(Rect, Rect.Left+2, Rect.Top+2, StringGrid1.Cells[ACol, ARow]);
  end;
end;

TEdit

  • Use OnKeyPress event to filter or react to some keypress
procedure TFrmForm1.Edit1KeyPress(Sender: Tobject; var Key: Char);
begin
  if( Key = #13 ) then
  begin
    //Some code here when Enter key is pressed
  end;
  if( not(Key in [#8, '0'..'9']) ) then Key:=#0;     //Ignore all key presses but Tab or digits