Home » Tipps & Tricks » Grafik » Zeichnen » TCanvas

TCanvas

Eigenschaften

Wichtige Grundeinstellungen:

ClipRect: Diese Nur-Lesen-Eigenschaft gibt den Bereich der Komponente an, auf den man zeichnen darf. Im Allgemeinen wird dies von 0-Breite und 0-Höhe sein

Handle: Gibt das GDI-Handle des Zeichenbereichs zurück. Dies wird normalerweise nicht benutzt, ist aber notwendig für die Programmierung mit API-Funktionen oder anderen Grafikmodi (z.B. OpenGL)

LockCount: Zeigt an, wie viele andere Stellen dieses oder anderer Programme das Neuzeichen auf Grund zeitkritischer Operationen verhindern. Für normale Programme nicht von Bedeutung

CopyMode: Erlaubt weitere Einstellungen, wie auf der Zeichenfläche gezeichnet werden soll. Normales Zeichnen geschieht mit der Standarteinstellung cmSrcCopy. Die meisten anderen Einstellungen erlauben das Zeichnen auf die Zielfläche, wobei jedes Pixel von Ziel und Quelle mit Hilfe eines boolsch’en Operators Kombiniert und dann dargestellt wird. Dies ist meistens wenig sinnvoll, und nur in Ausnahmefällen zu benutzen.
TCanvas hat 3 Grundeigenschaften, die beschreiben, wie die eingesetzten Methoden ausgeführt werden. Die erste Eigenschaft ist Pen. In ihm Stehen die Informationen, wie der Vordergrund der Zeichnung aufgebaut ist. Nach Pen werden zum Beispiel Rahmen von Figuren oder Linien gezeichnet. Die zweite Eigenschaft ist Brush, der Hintergrund. Brush beschriebt, wie die Füllfläche aussieht, die innerhalb einer Figur entsteht, den Text hinterlegt etc. Zuletzt gibt es noch Font. Hier wird beschrieben, welche Schriftart oder Schriftgröße verwendet wird, ob der Text fett, kursiv oder unterstrichen ist etc.

Pen

  • Color: Gibt die Farbe für den Pen in TColor an
  • Width: Gibt die Breite an, in der der Rahmen oder eine Linie gezogen wird (Mindestwert=1)
  • Style: Erlaubt es, Linien gestrichelt zu zeichnen. Im Allgemeinen sollte dieser Wert auf der Standarteinstellung psSolid belassen werden. Nur in dem Fall, dass man eine Figur ohne Rahmen zeichnen will, sollte man psClear benutzen, da es nichts nutzt, Width auf 0 zu setzen
  • Mode: TPenMode erlaubt eine Menge Einstellungen, wie denn der Pen nun genau gezeichnet werden soll. Hierbei gilt das gleiche wie bei CopyMode von TCanvas: Die Standarteinstellung der Eigenschaft (pmCopy) sollte in 99% aller Fälle beibehalten werden. Nur für spezielle grafische Effekte sollte man umschalten.

Brush

  • Color: Diese Eigenschaft (natürlich wieder vom Typ TColor) regelt die Füllfarbe für den Hintergrund
  • Style: Mit Hilfe dieser Eigenschaft kann man auch den Hintergrund nicht komplett füllen lassen, sondern ein Muster verwenden. Die Standarteinstellung ist bsSolid, bei der der komplette Hintergrund gefüllt wird. Wird bsClear verwendet, wird der Hintergrund Transparent gezeichnet, ein häufig praktischer Effekt. Die anderen Füllmuster sind von wenig wichtiger Bedeutung. Das 1. Problem ist die mangelnde Anzahl an Muster, die sich aber durch das verwenden einer Bitmap (s.u.) lösen lässt. Andererseits hat man keinen direkten Einfluss auf die Hintergrundfarbe, da die 2. Farbe, die verwendet wird, immer transparent ist. Um einen Hintergrund mit 2 Farben zu verwenden, muss man also vorher füllend mit der anderen Farbe zeichnen
  • Bitmap: Diese Eigenschaft macht es möglich, nicht nur mit einer Farbe oder einem Vorgegebenen Muster zu füllen, sondern auch eigene Füllungen zu verwenden. Dabei sind aber einige Einschränkungen vorhanden, da das Bild genau 8*8 Pixel groß sein muss.
  • Abschließend muss noch die Eigenschaft Handle erwähnt werden, die häufig für die GDI-Funktionen der API benötigt wird und das Handle des Brush zurückgibt

Font

Hier wird die verwendete Schriftart für die Ausgabe von Text verwendet. Font ist vom gebräuchlichen Typ TFont. Die hier eingegeben Werte wirken sich nur auf wenige Canvas-Methoden aus (TextExtent, TextHeight, TextOut, TextRect, TextWidth).

Wichtige Methoden

Allgemeine

  • Create: Diese Standartmethode erzeugt das TCanvas-Objekt und erzeugt außerdem Den Pen, den Brush und die Font
  • Destroy: Der Destruktor. Wie üblich gilt: man sollte Free verwenden
  • Assign: Kopiert die eingetragenen Werte eines anderen TCanvas-Objekts (der Parameter) und weißt sie dem aufrufenden TCanvas-Objekt zu
  • Free: Gibt den Speicher des Objekts frei. Man sollte Free an Stelle des Destruktors Destroy aufrufen

Flächenmethoden

  • Chord: Zeichnet eine Ellipse, die durch eine Gerade getrennt ist. Die 8 Parameter sind jeweils vom Typ Integer und geben Koordinaten an. Die ersten 4 sind jeweils zu Paaren die Eckpunkte des die Ellipse umschließenden Rechteckes (also der 1. Wert der x-Wert der ersten Eckpunktes , der 2. Wert der y-Wert des ersten Eckpunktes…). Die Größe der Ellipse ist durch dieses Rechteck beschränkt. Die Parameter 5-8 geben die Linie an, die die Ellipse trennt. Der fünfte und sechste Parameter sind x- und y-Wert des einen Punktes, der siebte und achte des anderen Punktes.
  • Ellipse: Zeichnet, wie der Name schon sagt, eine Ellipse. Die Ellipse ist durch ein Rechteck beschränkt und füllt dieses Rechteck möglichst voll aus. Das Rechteck selber ist durch 4 Parameter gegeben, die 2 gegenüberliegende Eckpunkte des Rechtecks angeben.
  • FillRect: Füllt ein Reckeck mit der Farbe, die in Brush angegeben ist. Ein Rand wird nicht gezeichnet. Das Rechteck ist durch 4 Koordinaten angegeben, die wie üblich 2 gegenüberliegende Eckpunkte des Rechtecks darstellen. Zu beachten ist, dass die beiden Begrenzungslinien (die in der Brush-Farbe gezeichnet werden), die an den ersten Punkt angrenzen, mitgezeichnet werden, die an den zweiten Punkten angrenzen, werden jedoch nicht mitgezeichnet. Bei dieser Methode gibt es nur einen Parameter vom Typ TRect, der ein Recheck darstellt. Will man trotzdem mit 4 einzelnen Koordinaten arbeiten, sollte man die Funktion Rect verwenden, die 4 Koordinaten in ein TRect umwandelt.
  • FrameRect: Zeichnet nur den Rahmen eines Rechtecks mit der Farbe aus dem Brush (!!!). Der Rahmen ist immer genau einen Pixel breit. Die innere Fläche des Rechtecks wird transparent gezeichnet. Der das Rechteck angebende Parameter ist wieder vom Typ TRect.
  • Pie: Zeichnet ein Kuchenstück, also den Teil einer Ellipse. Die Ellipse ist durch ein Rechteck angegeben (erste 4 Parameter). Vom Mittelpunkt der Ellipse trennen 2 Linien (Endpunkte sind die Parameter 5-8) die Ellipse. Der Bereich der im Uhrzeigersinn zwischen dem ersten und dem 2. Punkt liegt, wird nun gezeichnet. Der Rand sind die Linien, die vom Mittelpunkt der Ellipse ausgehen, und der Rand der Ellipse.
  • Arc: Zeichnet, ähnlich wie Pie, den Ausschnitt einer Ellipse, aber keine Fläche, sondern nur einen Ausschnitt des Randes der Ellipse. Die Parameter sind die gleichen wie bei Pie.
  • Polygon: Diese Procedure zeichnet ein Polygon. Der einzige Parameter ist ein (beliebig) großes Array von Typ TPoint. Alle Punkte werden nacheinander miteinander verbunden, die Linien mit dem Pen gezeichnet und der Raum dazwischen mit dem Brush gefüllt.
  • Rectangle: Zeichnet ein Rechteck. Die Begrenzungslinien, wie üblich, mit Pen und die Fläche mit dem Brush. Als Parameter die 4 Integerwerte, die die Eckpunkte des Rechtecks angeben. In neueren Delphiversionen kann man die 4 Integerwerte auch durch ein TRect ersetzen.
  • RoundRect: Zeichnet, genau wie Rectangle, ein Rechteck. Der einzige Unterschied ist, dass die Ecken leicht abgerundet sind.

Anmerkung: Hier ist häufig von Ellipsen die Rede. Sollte ein Kreis gezeichnet werden, muss das umgebende Rechteck nur ein Quadrat sein.

Methoden, um Bitmaps auf den Zeichenbereich aufzutragen oder herauszukopieren

  • BrushCopy: Zeichnet einen Teil (3. Parameter: TRect) eines Bitmap (2. Parameter: TBitmap) auf die Zeichenfläche. Der Bereich, in den gezeichnet werden soll, ist durch den ersten Parameter (TRect) gegeben. Dabei wird gegebenenfalls die Grafik verzerrt, was aber nicht immer schön aussieht und daher vermieden werden sollte. Eine Farbe (4. Parameter: TColor) des Bitmaps wird nicht mitgezeichnet, sondern diese Pixel werden mit der Brush-Farbe des Ziels gezeichnet. Dies kann verwendet werden, um transparent zu zeichnen oder andere Effekte zu erzielen. BrushCopy ist sehr langsam (Draw und StretchDraw sind ca. 200 mal so schnell) und sollte daher nicht zum normalen zeichnen verwendet werden.
  • CopyRect: Zeichnet in einem Bereich (1. Parameter: TRect) auf dem aktuellen Canvas einen Bereich (3. Parameter: TRect) von einem anderen Canvas (2. Parameter: TCanvas). Mit Hilfe von Einstellungen bei CopyMode lässt sich eine direkte Änderung des Bildes realisieren. Wenn beide Rechtecke nicht gleich groß sind, wird der Bereich gestretcht ausgegeben, was nicht unbedingt gut aussieht.
  • Draw: Zeichnet eine Grafik (3. Parameter: TGraphic) an eine Stelle (1. und 2. Parameter: Integer) des aktuellen Canvas. Da alle wichtigen Grafiktypen (wie TBitmap oder TJPEGImage) von TGraphic abgeleitet sind, lässt sich praktisch jede Grafik auf den Canvas zeichnen. Dabei wird die Graphik in voller Größe (wenn sie nicht Größer als die Zeichenfläche ist) ausgegeben und kann nicht größenverändert werden.
  • StretchDraw: Zeichnet ebenfalls eine Graphik (2. Parameter: TGraphic) auf die Zeichenfläche. Aber der komplette Bereich, in dem gezeichnet wird, ist durch den ersten Parameter (TRect) angegeben, so dass das Bild gestretcht wird, falls es nicht die exakte Größe des Rechtecks hat.
  • DrawFocusRect: Zeichnet einen Rahmen (wie er bei fokkusierten Komponenten üblich ist) um das Rechteck, das mit dem Parameter (TRect) gegeben ist. Dabei wird eine Form des Zeichnens mit XOR verwendet, der Rahmen verschindet also bei erneutem aufrufen. Ist eigentlich nur bei der Programmierung von Komponenten von Bedeutung.

Textmethoden

  • TextWidth: Benötigt als Parameter einen String. Es wird mit dieser Funktion nichts gezeichnet, sondern ermittelt, wie viele Pixel der Übergebene Text bei den aktuellen Fonteinstellungen breit ist. Dieser Wert wird als Integer zurückgegeben. Diese wird benötigt, um evtl. andere Objekte neben dem Text anzuordnen.
  • TextHeight: Ähnlich wie TextWidth, nur wird die Höhe des Textes zurückgegeben.
  • TextExtent: TextHeight und TextWidth in einem. Aus dem String-Parameter wird die Höhe und Breite bei den aktuellen Font-Einstellungen ermittelt und in einem Typ TSize (Mit den Integerwerten cx und cy) zurückgegeben. Ist etwas schneller, als TextHeight und TextWidth für den gleichen Text aufzurufen.
  • TextOut: Gibt einen Text (3. Parameter: String) an einer Position (1. und 2. Parameter: Integer) aus. Der Hintergrund wird dabei in der Brush-Farbe gezeichnet.
  • TextRect: Gibt einen Text (4. Parameter: String) an einer Position (2. und 3. Parameter: Integer) aus. Jeglicher Text, der nicht innerhalb eines angegebenen Rechtecks (1. Parameter: TRect) liegt, wird nicht dargestellt. Die Hintergrundfarbe des Rechtecks wird mit dem Brush gezeichnet. Im Allgemeinen sollte die Position des Textes mit der linken, oberen Ecke des Rechtecks übereinstimmen. Vor allen Dingen praktisch, falls der Text eine bestimmte Größe nicht überschreiten darf (ich stelle mir einem Button vor, bei dem die Caption über den Rahmen geht).

Andere Methoden

  • FloodFill: Füllt einen Bereich mit der im Brush angegebenen Farbe. Die ersten beiden Parameter (jeweils Integer) geben den ersten Punkt an, von dem ausgehend gefüllt wird. Der 4. Parameter erlaubt 2 Einstellungen: Ob solange gefüllt wird, bis die im dritten Parameter (Typ: TColor) angegebene Farbe erreicht wird, diese also eine Grenze der Füllung bildet. Dafür muss der Parameter den Wert fsBorder haben. Soll solange gefüllt werden, bis die Farbe wechselt, muss im dritten Parameter die Farbe an der entsprechenden Position angegeben werden und im vierten Parameter der Wert fsSurface. Dies entspricht dann dem Farbfüller von Paint.
  • MoveTo: Setzt die aktuelle Stiftposition auf den angegeben Punkt (2 Parameter: Integer). Dies ist wichtig für LineTo. Die Stiftposition lässt sich auch mit einer Zuweisung an PenPos (Typ: TPoint) regeln, und mit PenPos lässt sich die Position auslesen.
  • LineTo: Zeichnet von der aktuellen Stiftposition (siehe MoveTo) eine Linie an die durch die beiden Integerparameter angegebene Position. Der letzte Pixel (also die bei LineTo angegebene Position) wird nicht (!!!!) mitgezeichnet. Dies ist aber auch nicht immer notwendig, da LineTo die Stiftposition auf dieses Pixel setz und man so direkt von dort eine neue Linie zeichnen kann.
  • PolyLine: Zeichnet mehrere Linien. Der Endpunkt der ersten Linie ist der Anfangspunkt der zweiten Linie etc. Die einzelnen Punkte werden an PolyLine durch ein Array of TPoint übergeben. Wichtig bei dieser Methode: die Stiftposition wird nicht benutzt oder verändert. Mit PolyLine lässt sich außerdem ein Polygon zeichnen, wenn man der ersten und letzten Punkt als identisch angibt. Beinhaltet das Array nur einen Punkt, wird nichts gezeichnet, beinhaltet es 2 Punkte, wird eine Linie gezeichnet.

Zeichenflächenmethoden

  • Lock: Erhöht die Anzahl von LockCount um 1. Wenn LockCount größer als 0 ist, können andere Threads auf die Zeichenfläche nicht zugreifen. Da es in normalen Anwendungen nicht vorkommt, dass 2 Threads auf eine Zeichenfläche zeichnen, ist Lock nicht unbedingt von großer Bedeutung.
  • TryLock: Wenn LockCount noch 0 ist, wird Lock aufgerufen. Kann praktisch sein, da nur ein Aufruf von UnLock notwendig wird.
  • UnLock: Dekrementiert LockCount um 1. erst wenn LockCount 0 erreicht, können andere Threads wieder auf die Zeichenfläche zugreifen.

TCanvas bietet alle Möglichkeiten, um eigene Komponenten mit neuem Layout zu zeichnen. Auch kleinere Grafiken sind gut möglich. Allerdings ist Canvas mit Abstand nicht so schnell wie DirectX oder OpenGL (besonders für 3D), so dass man gerade bei spielen mit einer feinen Grafik sich mit einem der Grafikmodi beschäftigen sollte. Bei Flackern von Grafiken sollte man sich die Eigenschaft DoubleBuffered (bei allen Nachkommen von TWinControl, aber bei D3 leider noch nicht vorhanden) ansehen und auf true stellen oder aber erst die Grafik auf eine Bitmap zeichnen und diese ausgeben.