News
Photos
Articles
Components
Applications
Kleinkunst

Delphi - Programming style, avoid problems and use of IDE

Programmeerstijl

Hoofdletters

  • In Delphi kan je zowel kleine- als hoofdletters door elkaar gebruiken, maar de meeste Delphi-programmeurs gebruiken een vaste (Borland) standaard zodat het programma beter leesbaar wordt. Volgende regels worden vaak gebruikt.
  • Alle gereserveerde woorden in kleine letters (begin, end, repeat, if, else, procedure, …)
  • Namen van objecten, properties, functies en procedures beginnen met een hoofdletter en indien nodig komen er meerdere hoofdletters in een woord voor. (bv. EersteGetal, IntToStr).

Variabelen en objecten

  • Zoals elke programmeur wel zal weten is het belangrijk om variabelen en objecten een duidelijke naam te geven. Maak bv. geen variabele A, maar wel Getal1. Sommige programmeurs gaan echter nog iets verder en duiden ook aan van welk type de variabele of het object is. Sommigen zetten na het type een underscore, anderen zetten dan alles weer tegen elkaar. Volgende benamingen zullen het wat duidelijker maken.
var
  IntEersteGetal : Integer;
  BlnReedsUitgevoerd : Boolean;
  Str_Voornaam : String;
  Flt_Resultaat : Real;
  Image_Achtergrond : TImage;
  SpeedButtonAfdrukken : TSpeedButton;
  •  Zelf gebruik ik heel consequent volgende afkortingen voor variabelen. 
int : integers (word, longint, byte, ...)
str : strings
flt : floats (real, extended, ...)
bln : booleans
sl : stringlist

Constanten

  • Vermijd in je programma’s getallen die een bepaalde betekenis hebben. Voor zulke getallen kan je het beste constanten definiëren, waarvan je later gemakkelijk de waarde kan wijzigen en waarop je snel kan zoeken. Ook hier is het weer beter dat je een duidelijke naam gebruikt.
const
  Const_BMP = 1;
  Const_ICO = 2;
  BefNaarEuro = 40.3399;

Fouten vermijden

Begin en end

  • In Delphi moet je begin en end gebruiken om meerdere regels samen te houden. Het is voor sommigen echter niet altijd duidelijk wanneer ze deze moeten gebruiken. Onder een for en if mag je slechts 1 regel zetten, maar dit kan wel een with of opnieuw een for of if zijn. Als je diep genestelde instructies krijgt en niet altijd een begin plaatst, kan het moeilijk worden om nadien het juiste aantal ends te zetten. Wanneer je twijfelt, gebruik je best altijd begin en end.
  • Als je onderstaande voorbeelden bekijkt, dan lijkt het of het tweede en derde voorbeeldje hetzelfde resultaat hebben, maar eigenlijk geven voorbeeld 1 en voorbeeld 2 hetzelfde effect.
for i:=1 to 10 do
  ShowMessage(IntToStr(i));
  ShowMessage(IntToStr(i*2));


for i:=1 to 10 do
  ShowMessage(IntToStr(i));
ShowMessage(IntToStr(i*2));


for i:=1 to 10 do
begin
  ShowMessage(IntToStr(i));
  ShowMessage(IntToStr(i*2));
end;

Hints en warnings

  • Tijdens het compileren komen er in het Message-venster Errors, Warnings en Hints te staan.
  • Bij Errors zal het programma niet verder compileren, maar Warnings en Hints worden gewoon genegeerd. Delphi Hints en Warnings zijn meestal vrij duidelijk en het is beter deze probleempjes ook op te lossen want ze kunnen in bepaalde gevallen toch fouten veroorzaken.
  • Een goed programmeur vermijdt dus alle Warnings en Hints.

Waarden aan velden toekennen

  • Let goed of de Edit/Insert-status van een dataset aanstaat vooraleer je waarden aan een veld toekent. Anders krijg je de foutmelding ‘Dataset not in Edit or Insert mode’.
  • Deze fout kan je op 2 manieren voorkomen. Controleer eerst de status ofwel, maar dit is niet altijd mogelijk, zet je zelf de status op Edit.

if Table1.State in [dsEdit, dsInsert] then
  Table1.FieldByName('Naam').AsString:='Stefan';
Table1.Edit;
Table1.FieldByName('Naam').AsString:='Stefan';

Try .. Except / finally 

  • Delphi beschikt over de zeer interessante mogelijkheid om allerlei fouten op te vangen via try, except en finally. Gebruik deze commando’s dan ook zo vaak mogelijk.
  • Wanneer je een actie wil uitvoeren die fouten zou kunnen geven, gebruik dan altijd een try … except en tracht in de except de fout te herstellen. De mogelijke fouten kan je terugvinden in de Delphi Help. (EConvertError, EFOpenError, EInvalidImage, …).
  • Je kan met try ... except ook fouten totaal onderdrukken, maar dit kan je best niet te vaak gebruiken. 
try
  Getal:=StrToInt(Edit1.Text);
except
  on EConvertError do
    ShowMessage('Dit is geen geldig getal');<
end;
Wanneer je objecten in run-time aanmaakt moet je bijna altijd een try … finally gebruiken om nadien het object ook terug te verwijderen. Het aanmaken van het object moet altijd voor de try gebeuren ! Mocht het object niet aangemaakt zijn, dan zal je programma toch geen foutmeldingen geven.

MijnBitmap:=TBitmap.Create;
try
  ...
finally
  MijnBitmap.Free;
end;

Bij het nesten van try moet je in de binnenste except een raise plaatsen anders worden de fouten totaal onderdrukt.

try
  try
  ...
  except
    raise;
  end;
finally
end;

Forms

  • De formulieren die slechts af en toe opgeroepen worden kan je best in run-time aanmaken. Delphi creëert standaard alle formulieren bij het opstarten van de applicatie. Dit vraagt natuurlijk veel geheugen en in Windows 95/98 kan dit resource problemen opleveren. Daarom kan je beter een form zelf creëren en ook terug verwijderen.
  • In het menu Project >> Options moet je eerst het formulier toevoegen aan de Available Forms i.p.v aan de ‘Auto-create Forms’.
    Wanneer je het form wil oproepen, moet je het op volgende manier aanmaken. Als het geen MDI Child is moet je nadien nog een Form1.Show of Form1.ShowModal gebruiken.
Form1:=TForm1.Create(Self);
  • In het event OnClose van dit formulier moet je er wel voor zorgen dat het formulier niet alleen gesloten wordt, maar ook verwijderd. Dit doe je met volgende regel.
Action:=caFree;

SetFocus

  • Wanneer je een PageControl (tabbladen) gebruikt, let dan goed op wanneer je de method SetFocus gebruikt. Wanneer de control niet zichtbaar is, krijg je foutmeldingen en daarom moet je altijd eerst controleren welke TabSheet actief is.
if PageControl1.ActivePage = TabSheet1 then
  Edit1.SetFocus;

Variants

Variant is een special datatype waarin je zowel integers, floats, strings, … kan bewaren. Dit kan zeer gemakkelijk zijn, maar het grote nadeel is echter dat dit meer geheugenruimte vraagt en het omzetten van variant naar een andere datatype kan problemen geven. Een variant kan namelijk ook geen waarde hebben en dan is de variabele gelijk aan NULL. Wanneer dit het geval is krijg je foutmeldingen bij het converteren. Daarom kan je best onderstaande functies gebruiken om een variant om te zetten naar een integer of float. Om een variant te converteren naar een string kan je de Delphi functie VarToStr gebruiken. Vanaf Delphi 6.0 moet je de unit Variants toevoegen om hiermee te kunnen werken

function SCVarToInt(Variant : Variant) : Integer;
begin
  Result:=0;
  if VarType(Variant) in [varInteger,varSmallInt,varByte] then
    Result:=Variant;
  if VarType(Variant) = varString then
    Result:=StrToIntDef(Variant,0);
end;
function SCVarToFloat(Variant : Variant) : Extended;
begin
  Result:=0;
  if VarType(Variant) in [varSingle, varDouble, varInteger,varSmallInt,varByte] then
    Result:=Variant;
  if VarType(Variant) = varString then
    Result:=StrToFloatDef(Variant,0);
end;

NOT

Let op bij het gebruik van NOT in een IF. De eerste if in het programma is verkeerd geformuleerd en deze if zal dan ook nooit aan de voorwaarde
voldoen. De tweede if met haakjes is wel een goede oplossing.

var
  a : integer;
begin
  a:=4;
  if not a = 10 then
    showmessage('ok');
  if not (a = 10) then
    showmessage('ok');
end;

Bookmark

Wanneer je een bookmark gebruikt op een dataset, denk er dan altijd aan om deze uiteindelijk terug te verwijderen met FreeBookmark. Als je een dataset (table of query) wil doorlopen kan je best ook DisableControls en EnabeleControls gebruiken zodat bij het doorlopen de controls op het
form niet meescrollen.

var
  PtBookmark : TBookmark;
begin
  with Query1 do
  begin
    PtBookmark:=GetBookmark;
    DisableControls;
    try
      First;
      while not EOF do
      begin
         ...
         Next;
      end;
    finally
      EnableControls;
      GotoBookmark(PtBookmark);
      FreeBookmark(PtBookmark);
    end;
  end;
end;

Active

Als je in bepaalde events gegevens uit een dataset gebruikt, controleer dan altijd even of het dataset actief is. Sommige events zouden kunnen voorkomen terwijl de dataset nog niet geopend is, en dan krijg je natuurlijk errors.

if Table1.Active then
begin
  
end;

IDE en debugger gebruiken

Wisselen tussen interface en implementation

  • Zet de cursor op de gewenste functie of procedure in de interface-sectie van de unit en druk op Ctrl+Shift+Pijl omlaag. De cursor springt automatisch naar de juiste functie of procedure. Omgekeerd gebruik je dezelfde combinatie maar dan met Pijl omhoog.

Bookmarks

  • Bookmarks zijn, zoals de naam al doet vermoeden, boekenleggers of liever gezegd markeringspunten in de programmacode. Zeker tijdens het gebruik van grotere units zijn deze bookmarks onmisbaar, omdat de programmeur snel naar de juiste code kan springen.
  • Gebruik op de gewenste plaats de toetscombinatie Ctrl+Shift+cijfertoets 0..9 om een plaats te markeren. In de verticale balk voor de code verschijnt het bookmark-nummer.
  • Gebruik de toets Ctrl+cijfertoets om naar de bookmark te springen.
  • Om een bookmark te verwijderen moet op de bookmark-positie weer op Ctrl+Shift+ de betreffende cijfertoets gedrukt worden.

Focus zetten op de parent van een component

  • Wel eens een panel met Align = alClient op een formulier geplaatst en geprobeerd de focus op het formulier zelf te krijgen ? Dit is meestal een hele opgave door de Align property weer te wijzigen en de componenten te verslepen.
  • Met Escape wordt echter de focus verplaatst naar de parent van een object, dus van bijvoorbeeld een Edit-object naar een Groupbox en vervolgens naar de Form zelf.

Inspringen van code

  • Een goede gewoonte van programmeurs is om bij elkaar horende blokken code in te laten springen, zoals begin..end, repeat..until. Maak een blok van de code die moet inspringen en gebruik de toetscombinatie Ctrl+Shift+I om in te springen en Ctrl+Shift+U om de code naar links te verschuiven.

Sneltoetsen

  • In Delphi zijn er heel wat verschillende sneltoetsen die je onmogelijk allemaal kan onthouden. Toch zijn er enkelen die je zeker moet leren wil je snel met de editor van Delphi kunnen werken. Buiten de bovenvermelde toetsencombinaties zijn ook onderstaande ‘onmisbaar’.
WERKEN MET EDITOR
CTRL + X Knippen
CTRL + C Kopiëren
CTRL + V Plakken
CTRL + Z Undo/Ongedaan maken
CTRL + S Save/Opslaan
F11 Object Inspector oproepen
F12 Wisselen tussen unit en bijhorend form
ALT + 0 Lijst met alle venster oproepen
CTRL + SHIFT + nr Bookmark/bladwijzer plaatsen
CTRL + nr Naar bookmark/bladwijzer springen
HOME Naar begin van regel
END Naar einde van regel
CTRL + HOME Naar eerste regel
CTRL + END Naar laatste regel
CTRL + pijl links of rechts Woord terug of verder
SHIFT + pijltjes-toetsen of bovenstaande combinaties Selecteren van tekst
CTRL + F Zoeken
CTRL + R Vervangen
CTRL + K + N Tekstblok naar hoofdlettes omzetten
CTRL + K + O  Tekstblok naar kleine letters omzetten
CTRL + K + U Tekstblok van tekst naar rechts verschuiven
CTRL + K + I Tekstblok van tekst naar links verschuiven
WERKEN MET DEBUGGER
F9 Run/Starten
F8 Naar volgende opdracht springen (Step over)
F7 Naar onderliggende routine van opdracht springen (Trace into)
F4 Naar cursor positie springen
F5 Break plaatsen
CTRL + F5 Watch toevoegen
CTRL + F7 Evalueren en bewerken van expressies (variabelen, properties, ...)
SOURCE CODE BEWERKEN MET EDITOR
CTRL + SHIFT + C  Declaratie of implementatie van functies of procedures aanvullen
CTRL + SHIFT + pijl omhoog of pijl omlaag Wisselen tussen declaratie en implementatie
CTRL + SPACE Lijst van properties/methods/events van huidig object
CTRL + J Lijst van beschikbare code templates

Wisselen tussen form en unit

  • Bewaren van de desktop : Delphi biedt de mogelijkheid de desktopinformatie te bewaren, zodat tijdens het de volgende keer opstarten de situatie van de laatste sessie wordt hersteld. Dit betreft niet alleen welke units en forms geopend waren, maar zelfs de positie van de cursor, de venstergrootte, welke debugtools er in gebruik waren, enz. Om de desktop-instellingen te bewaren kies je Tools >> Environment Options >> Preferences >> Autosave Options en daar vink je Desktop aan.
  • Meerdere desktops : Vanaf Delphi 5 kan je met meerdere desktops werken. Deze meerdere 'desktops' kunnen gebruikt worden zodat je bij het debuggen bijvoorbeeld geen Object Inspector maar wel het Watch en Break venster kan zien. Van zodra je terug naar de 'editor-desktop' overschakelt zie je de vensters die gebruikt worden bij het editeren van je programma. Je kan met een van deze knopjes zelfs instellen welke desktop actief dient te worden bij het debuggen. Deze nieuwe werkwijze is gemakkelijk om bijvoorbeeld bij het debuggen de breakpoint, watch, local variables, … vensters te tonen en deze automatisch te laten verdwijnen wanneer je het programma stopt. Vanaf Delphi 4 kan je deze verschillende venster ook docken en wanneer je deze in elkaar plaatst verschijnen er verschillende tabbladen.