Grafikebenen in Delphi

V0.0 rev000 12.12.2004 (fs)

Es sollen also zwei Grafikebenen programmiert werden, ein Hintergrund und ein Vordergrund. In die Hintergrundebene wird ein Bild geladen. Die Vordergrundebene soll transparent sein, und man soll darauf malen können.

Beide Ebenen sollen vom Programm erzeugt werden und nicht im Formulareditor angelegt. Dadurch wird es später möglich sein, dynamisch so viele Ebenen wie nötig, etwa für Kacheln, zu erzeugen.

Das leere Formular

Zunächst erstellen wir ein leeres Formular mit Hilfe des Formulardesigners. Es soll 300 x 300 Pixel groß sein und heisst 'PlaneTestMainForm'. Das Projekt speichern wir unter dem Namen 'PlaneTest' ab.

Der Code sieht dann so aus:

unit PlaneTestMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

const Revision = 'Step 0.0 Revision 000 12.12.2004 (fs)';

type
  TPlaneTestMainForm = class(TForm)
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  PlaneTestMainForm: TPlaneTestMainForm;

implementation

{$R *.dfm}

end.

Und so sieht das dann aus:

Die Hintergrundebene

Für die Darstellung des Hintergrunds benützen wir ein Objekt vom Typ TImage. Zitat Hilfetext: "Die Grafikkomponente (TImage) zeigt Grafiken wie Bitmaps, Symbole oder Zeichnungen an. Die Eigenschaft Picture bestimmt die betreffende Grafik."

Die Variable, die den Hintergrund enthalten soll, wird im Implementation-Abschnitt deklariert:

var BackGroundPlane: TImage;

Dann lassen wir uns von der IDE eine OnActivate-Routine für das Hauptformular erstellen. In dieser Prozedur initialisieren wir dann die Hintergrundgrafik:

 1: procedure TPlaneTestMainForm.FormActivate(Sender: TObject);
 2: begin
 3: BackGroundPlane:=timage.create(application);
 4: with BackGroundPlane do
 5:   begin
 6:    parent := PlaneTestMainForm;
 7:    Picture.LoadFromFile('Test.bmp');
 8:    height:=200;
 9:    width:=200;
10:    top:=10;
11:    left:=10;
12:   end;
13: end;

In Zeile 3 wird die Instanz für die Hintergrundgrafik erzeugt. Der Parameter application für den Eigentümer bewirkt, dass der Speicher mit Beendigung des Programms automatisch wieder freigegeben wird.

In den Zeilen 4 - 12 erhält die Hintergrundgrafik ihre ursprünglichen Eigenschaften zugewiesen.

In Zeile 6 wird aus unserer Hintergrundgrafik ein Kind des Hauptformulars. Mit ihm wird sie überhaupt erst angezeigt aber auch verschoben und bei Bedarf neu gezeichnet. Die Eigenschaft picture enthält die eigentliche Grafik. Mit der Methode LoadFromFile wird bequem eine Bitmap geladen. Ohne die Zeilen 6 und 7 wird die Hintergrundgrafik nicht angezeigt.

Die Zeilen 8 und 9 legen die Abmessungen der Grafik fest, in unserem Fall orientieren sie sich an der wirklichen Größe der geladenen Bitmap. Alternativ könnten Sie auch die Eigenschaft autosize auf true setzen.

Die Eigenschaften top und left schließlich bestimmen die Ausrichtung der Hintergrundgrafik zum Elternformular. Und so sieht dieser Schritt dann aus:

Die Vordergrundebene

Auch für die Darstellung des Vordergrunds benützen wir ein Objekt vom Typ TImage. Dieses mal aber soll dessen Eigenschaft picture eine 'leere' Bitmap zugeordnet werden. Diese wird so erzeugt:

 TempBitmap:=TBitmap.create;
 with TempBitMap do
  begin
   height:=200;
   width:=200;
  end;

und so zugewiesen:

 ForeGroundPlane:=TImage.create(application);
 ForeGroundPlane.Picture.Bitmap:=TempBitmap; // Die temporäre Bitmap dem TImage zuordnen
 TempBitmap.Free; // Dann brauchen wir sie nicht mehr

Danach ist mit der ForeGroundPlane gleich wie mit der BackGroundPlane zu verfahren: Elternformular, Höhe und Breite müssen zugeordnet werden.

Und so sieht dieser Schritt dann aus:

Transparenter Vordergrund

Bevor wir versuchen die Vordergrundebene transparent zu machen, sollten wie etwas darauf malen. Sonst sehen wir sie nicht mehr und sind gar nicht sicher, ob sie nun transparent geworden oder einfach nur verschwunden ist.

Aber worauf malen wir? In Delphi malen wir stets auf eine Zeichenoberfläche, eine Canvas. Die Canvas gehört in unserem Fall zur Bitmap, die zur Vordergrundebene gehört, also zu ForeGroundPlane.Picture.Bitmap.

Zunächst wird die gesamte Canvas in der Farbe eingefärbt, die später transparent werden soll.

 With ForeGroundPlane.Picture.Bitmap.Canvas do
  begin
   Brush.Color := clWhite;
   FillRect(Rect(0,0,200,200));
  end;

Für unseren Zweck malen wir dann am besten ein liegendes Kreuz, das die jeweils gegenüberliegenden Ecken der Fläche verbindet, auf die Canvas. Der zugehörige Codeschnipsel und das Ergebnis sehen so aus:

 With ForeGroundPlane.Picture.Bitmap.Canvas do
  begin
   Pen.Color := clRed;
   Pen.Width := 2;
   MoveTo(0, 0);
   LineTo(200, 200);
   MoveTo(0, 200);
   LineTo(200, 0);
  end;

Jetzt zur Transparenz: Hier ist die einfachste Form der Transparenz gemeint, die eine bestimmte Farbe als unsichtbar definiert. Zunächst muss die Eigenschaft Transparent der Vordergrundebene eingeschaltet werden. Welche Farbe unsichtbar sein soll, wird in der Eigenschaft TransparentColor der zugeordneten Bitmap festgelegt.

 ForeGroundPlane.Transparent:=true;
 ForeGroundPlane.Picture.Bitmap.TransparentColor:=clWhite;