News
Photos
Articles
Components
Applications
Kleinkunst

Delphi - Programming graphics

Delphi biedt een hele reeks mogelijkheden voor het manueel tekenen van lijnen, cirkels, rechthoeken, bitmaps, … en het aanpassen van lettertypes en kleuren. In Windows applicaties zal je deze mogelijkheden regelmatig nodig hebben; soms voor kleine zaken zoals het tekenen van een icoontje in een grid maar misschien ook voor het tekenen van complexere scherma’s of figuren.

Canvas

In Delphi kan je tekenen op een TCanvas object. Dit object kan je terugvinden bij de meeste grafische objecten zoals TForm, TImage en TPaintbox. In onderstaande voorbeelden gaan we telkens met de canvas van een paintbox werken. De coördinaten die je moet gebruiken hebben als maateenheid pixels. De resolutie van het scherm is meestal 800 x 600 pixels, 1027 x 768 of 1280 x 1024 pixels.

Properties

De belangrijkste properties van een canvas zijn :

  • Brush
  • CopyMode
  • Font
  • Pen

Brush is van het type TBrush en heeft op zijn beurt ook weer enkele properties zoals Color en Style. Een brush is de opvulinstelling van een figuur. De pen is de instelling van de omtreklijnen. Het is van het type TPen die als belangrijkste properties Color, Width, Mode en Style (psSolid, psClear, pmNotXor) heeft.

Methods

De meestgebruikte methods bij een canvas zijn :

  • Draw(x,y,graphic)
  • Ellipse(x1,y1,x2,y2)
  • LineTo(x,y)
  • MoveTo(x,y)
  • Rectangle(x1,y1,x2,y2)
  • TextOut(x,y,text)

Voorbeeld

Groene rechthoek met dikke rode rand. Blauwe geruite ellips met gele dunne rand. Paarse dikke lijn. Blauwe tekst ‘Delphi’ met als lettertype Times New Roman en grootte 24.

Paintbox1.Canvas.Brush.Color:=clGreen;
Paintbox1.Canvas.Pen.Color:=clRed;
Paintbox1.Canvas.Pen.Width:=5;
Paintbox1.Canvas.Rectangle(10,10,100,100);
Paintbox1.Canvas.Brush.Color:=clBlue;
Paintbox1.Canvas.Brush.Style:=bsDiagCross;
Paintbox1.Canvas.Pen.Color:=clYellow;
Paintbox1.Canvas.Pen.Width:=2;
Paintbox1.Canvas.Ellipse(10,80,200,200);
Paintbox1.Canvas.Pen.Color:=clPurple;
Paintbox1.Canvas.Pen.Width:=6;
Paintbox1.Canvas.MoveTo(0,0);
Paintbox1.Canvas.LineTo(100,200);
Paintbox1.Canvas.Font.Name:='Times New Roman';
Paintbox1.Canvas.Font.Size:=32;
Paintbox1.Canvas.Font.Color:=clBlue;
Paintbox1.Canvas.TextOut(0,100,'Delphi'); 

Kleuren

Om kleuren te gebruiken met je telkens de property Color instellen op een van de vaste constanten (clRed, clGreen, clYellow, ...). Met de functie RGB(r,g,b) kan je zelf een kleur mengen met de 3 hoofdkleuren rood, groen en blauw. De waardes schommelen tussen 0 en 255. Als de 3 kleuren op 0 staan is het zwart en staan ze alledrie op 255 dan is de kleur wit. In een lus kan je op deze manier een of meerdere kleuren systematisch verhogen.

Paintbox1.Canvas.Brush.Color:=RGB(155,10,200);

Voorbeeld

Het volgende voorbeeldje tekent een blauwe kleuroverloop. De rechthoek wordt telkens 10 pixels verder geplaats terwijl de blauwe kleur telkens met 7 toeneemt. De omtrekkleur zetten we af door Pen.Style op psClear te zetten.

procedure TForm1.SpeedButton2Click(Sender: TObject);
var
  x, blauw : integer;
begin
  x:=0;
  blauw:=0;
  repeat
    Paintbox1.Canvas.Pen.Style:=psClear;
    Paintbox1.Canvas.Brush.Color:=RGB(0,0,blauw);
    Paintbox1.Canvas.Rectangle(x,0,x+100,100);
    blauw:=blauw+7;
    x:=x+10;
  until x>300;
end; 

De MouseDown, MouseMove en MouseUp events

Verschillende objecten waaronder een paintbox hebben de MouseDown, MouseMove en MouseUp events. Met MouseDown en MouseUp kan je nagaan of de muisknop is ingedrukt of weer wordt losgelaten. De MouseMove komt voor als je de muis over het object beweegt. In de procedure die bij dit event hoort, krijg je de coördinaten van de huidige muispositie.

Voorbeeld

Deze procedure tekent een rode cirkel op de plaats waar de muis staat. Verander nadien de kleur eens in RGB(x,y,x).

procedure TForm1.PaintBox1MouseMove(Sender: TObject;
Shift: TShiftState; X,Y: Integer);
begin
  Paintbox1.Canvas.Brush.Color:=clRed;
  Paintbox1.Canvas.Ellipse(x,y,x+20,y+20);
end;

Pen Mode

Pen.Mode staat standaard op pmCopy waardoor de gewone instellingen gebruikt worden. Als je Pen Mode echter op pmNotXor zet kan je ervoor zorgen dat je het vorige figuur terug kan wissen. Onderstaand voorbeeld tekent constant een lijn vanuit punt 0,0 tot aan de muiscursor. De vorige lijn wordt telkens gewist. Hiervoor moet je natuurlijk de vorige positie bijhouden en de lijn opnieuw op die positie tekenen. Omdat lokale variabelen die je declareert in de procedure telkens terug hun beginwaarde krijgen als de procedure wordt opgeroepen, moet je nieuwe globale variabelen declareren in het begin van het programma.

Voorbeeld

var
  VorigeX, VorigY : integer;

procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
begin
  with Paintbox1.Canvas do
  begin
    Pen.Mode:=pmNotXor;  
    MoveTo(0,0);
    LineTo(VorigeX,VorigeY);
    MoveTo(0,0);
    LineTo(X,Y);
    VorigeX:=X;
    VorigeY:=Y;
  end;
end;

Timer

In het System-pallet vind je een component TTimer genaamd. De property Interval is de tijd vooraleer het event OnTimer uitgevoerd wordt. 1000 (milliseconden) is gelijk aan 1 seconde. Bij het event OnTimer zet je het stukje programma dat je om een bepaalde tijd wil uitvoeren. Dit componentje wordt vaak gebruikt i.p.v lussen. Het nadeel bij lussen (repeat - until, for - next, ...) is dat er ondertussen niets aangeklikt kan worden. Bij een timer werkt de rest van het programma nog gewoon verder. Met een timer kan je natuurlijk leuke grafische demo’s maken en hieronder volgt dan ook een leuk voorbeeldje. Je moet zeker eens proberen de getallen te wijzigen. Automatisch krijg je andere effecten.

Voorbeeld

var
  Form1: TForm1;
  straal, r,g,b : integer;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  i : real;
  x1,x2,y1,y2 : integer;
begin
  straal:=straal+3;
  if straal>500 then
    straal:=0;
  repeat
    r:=r+16;
    if r>255 then
      r:=0;
    g:=g+13;
    if g>255 then
      g:=0;
    b:=b+10;
    if b>255 then
      b:=0;
    i:=i+pi/65;
    x1:=Round(Sin(i)*straal);
    y1:=Round(Cos(i)*straal);
    x2:=Round(Sin(i)*straal+20);
    y2:=Round(Cos(i)*straal+20);
    Paintbox1.Canvas.Pen.Style:=psclear;
    Paintbox1.Canvas.Brush.Color:=RGB(r,g,b);
    Paintbox1.Canvas.Ellipse(400+x1,300+y1,400+x2,300+y2);
  until i>=2*pi;
end;

Afdrukken

Om in Delphi iets af te drukken kan je het TPrinter object gebruiken. Dit object heeft twee belangrijke methods BeginDoc en EndDoc waarmee je de printopdracht kan starten of stoppen. Voor de rest kan je alles op de canvas van de printer tekenen op dezelfde manier als dit op het scherm gebeurt. De property Title is de titel die in het afdrukbeheer zal verschijnen.

uses 
  ..., Printers;

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  Rij, Regel : Integer;
begin
  with Printer do
  begin
    BeginDoc;
    Title:='Adruktest Delphi';
    Canvas.Font.Name:='Arial';
    Canvas.Font.Size:=18;
    Canvas.TextOut(200,100,'TITEL');
    Canvas.Font.Name:='Times New Roman';
    Canvas.Font.Size:=12;
    Rij:=300; 
    for Regel:=0 to Memo1.Lines.Count-1 do
    begin
      Canvas.TextOut(400,200+Rij,Memo1.Lines[Regel]);
      Rij:=Rij+120;
    end; 
    EndDoc;
  end;
end;