Canvas i Delphi 2

Tags:    delphi
Skrevet af Bruger #66 @ 14.06.2001
Canvas i Delphi (part 2)

Som lovet, kom også det andet kapitel i Canvas-serien. I dette kapitel skal vi se nærmere på brugen af Canvas i mere praktisk forstand - i dette tilfælde, til at lave et simpelt tegneprogram. Bemærk at dette ikke er en opskrift til hvordan man laver et stort program, men blot en håndsrækning til det at tegne med Canvas. Hvis du ikke ved, hvad Canvas er, vil jeg foreslå dig at læse part 1 først.

En begyndelse

Som i første kapitel af Canvas-serien, skal vi også i dette kapitel bruge et Timage til at tegne på, hvilket selvfølgelig ikke betyder du ikke kan gøre det på andre visuelle komponenter, det er sådan set præcis de samme metoder man kan benytte :-).

Vi lægger ud med at lave et lille program, der kan tegne en oval (en ellipse), ved hjælp af at trække cursoren fra a til b, men slå nu ørene ud, for dette er lidt kompliceret.

Først skal vi have et par variabler på plads,
startpunkt, slutpunkt: TPoint; 
tegner : boolean;
De to variabler startpunkt og slutpunkt vil komme til at indeholde oplysningerne om, hvilket punkt musen er trykket ned på og hvilket punkt musen bliver sluppet igen, altså x og y. De skal dog siges, at Tpoint bare er en type der indeholder både x og y som integers, så når vi skal hente x fra startpunkt, skriver vi bare x:=startpunkt.x; Hvis vi så skal definere variablen startpunkt til x, y skriver vi bare startpunkt:= point(x,y). Booleanen ’Tegner’ er til for at holde styr på, om musen er trykket ned eller ej. Placer variablerne efter public. Den første procedure vi skal bruge er jo selvfølgelig også en onmousedown på Timaget, Papir. Det skulle se nogenlunde sådan ud:
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Tegner := True;                   //når der er klikket, bliver tegner til sand
  papir.Canvas.MoveTo(X, Y);  //sætter canvas´s pointer til der hvor der blev trykket
  startpunkt := Point(X, Y);     //her sætter vi startpunktet til der, hvor der blev trykket
  slutpunkt := startpunkt;       //indtil videre er musen ikke flyttet, så slutpunkt er det samme
end;
Nu har vi så fortalt programmet, hvor der er blevet trykket henne, og at den er i gang med at tegne. Nu mangler vi så bare at få programmet til at tegne, når musen bliver sluppet. Vi skal nu igen have fat i vores Papirs events (Timaget). Nu vælger vi onmouseup:
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Tegner then
  begin
    papir.Canvas.Pen.Mode := pmCopy; //default penindstillinger
    papir.Canvas.Ellipse(startpunkt.x, startpunkt.y, x, y); //udfører tegningen af ovalen
    Tegner := False; //da musen er sluppet, tegner programmet ikke mere
  end;
end;
Hvis alt er i orden, kan man nu, i programmet, holde musen nede, slippe den og få en oval ud af det - hvis ikke, læs da ovenstående en ekstra gang. Alt dette er desværre ikke nok for en krævende bruger – ” man kan jo ikke engang se, hvordan ovalen kommer til at se ud før man slipper ”, ville han sige. For at lukke munden på ham, laver vi da bare en onmousemove procedure:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  if tegner then
  begin
    papir.Canvas.Pen.Mode := pmNotXor; //laver linien vi skal til at tegne midlertidig
    papir.Canvas.Ellipse(startpunkt.X, startpunkt.Y, slutpunkt.X,slutpunkt.Y); //tegner gamle
    slutpunkt := Point(X, Y); //presser cursorens x og y ned I slutpunktvariablen
    papir.Canvas.Ellipse(startpunkt.X, startpunkt.Y, slutpunkt.X,slutpunkt.Y); //tegner nye
  end;
end;
Det er jo selvfølgelig ikke sådan, at man ikke kan lave andet end ovaler med drag´n´drop metoden. Grunden til, jeg valgte dette eksempel var bare at illustrere, at det vigtigste i de fleste geometriske former, Canvas kan lave, er at have x1, y1, x2 og y2 - selv i en rund metode.

Pen Modes

I det forrige eksempel brugte vi canvas.pen.mode til at bestemme hvilken type der skulle tegnes med. Da vi valgte canvas.pen.mode:= pmcopy , sagde vi til programmet, at tegningens farve skulle være den, som canvas.pen.color var sat til. Da vi skulle tegne et midlertidigt aftryk af ovalen bruge vi canvas.pen.mode:=omNotXor . Den fjerner sådan set sig selv efter tegningen. Der findes selvfølgelig også mange andre modes, faktisk hele 16 forskellige:

pmBlack, pmWhite, pmNop, pmNot, pmCopy, pmNotCopy, pmMergePenNot, pmMaskPenNot,
pmMergeNotPen, pmMaskNotPen, pmMerge, pmNotMerge, pmMask, pmNotMask, pmXor, pmNotXor
Du kan selv eksperimentere med dem, ved at ændre linien
papir.Canvas.Pen.Mode := pmCopy; 
under vores onmouseup event til
papir.Canvas.Pen.Mode := pmVælgEnAfOvenstående; 
Til slut har jeg kun at sige, held og lykke.


Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.

Del også gerne artiklen med dine Facebook venner:  

Kommentarer (3)

User
Bruger #2779 @ 26.01.04 10:56
Ikke en god artikel for begyndere. Man kan simpelthen ikke gennemskue, hvor koden skal placeres. Ellers et godt initiativ.
User
Bruger #2779 @ 09.02.04 11:45
Jeg tager min tidligere kommentar til mig igen. Efter at have arbejdet med det, har jeg faktisk fundet artiklen yderst interessant og hjælpsom. Man skal ikke regne med, at man med artiklen her kan gå hen og lave et tegneprogram fra bunden. Men hvis du sætter dig lidt ind i tingene først, så kan du bruge meget af koden herfra :)
User
Bruger #6261 @ 29.01.05 17:54
God artikel :) havde lidt svært med den i starten men så kikkede jeg godt efter og fandt fejlen også virkede det nice herfra! :)
Du skal være logget ind for at skrive en kommentar.
t