Entwickler-Ecke

Multimedia / Grafik - ...ein Farbverlauf auf dem Formular erstellen?


Popov - Di 03.02.04 15:13
Titel: ...ein Farbverlauf auf dem Formular erstellen?
Dazu benötigt man zuerst Funktionen die einen Farbverlauf generieren. Zu Auswahl gibt es zwei Funktionen:


Die Funktionen benötigen ein TCanvas auf dem gezeichnet wird, zwei TColor Farben für den Farbverlauf und ein TRect um den Bereich zum Zeichnen einzugrenzen.

Aufgerufen werden die Funktionen aus der Formular OnPaint-Prozedur. Das hat den Vorteil, daß die Funktionen automatisch aufgerufen werden. Allerdings hat das auch einen Nachteil: FormPaint liefert einen Clipping-Bereich in den gezeichnet wird. Für das System hat es den Vorteil, daß nur der Bereich gezeichnet wird der neu dazugekommen ist. Für die Farbverlauf-Funktion hat es den Nachteil, daß der alte Bereich nicht überzeichnet wird. Deshalb muß bei allen Fenstern die ihre Größe ändern können, die Funktion noch zusätzlich in die OnResize Prozedur eingetragen werden. Aber nur bei Fenstern die ihre Größe ändern können.

Zuerst die beiden Farbverlauffunktionen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
// Erstellt ein Farbverlauf von links nach rechts
procedure DrawGradientV(Canvas: TCanvas; Color1, Color2: TColor; Rect: TRect);
var
  Y, R, G, B: Integer;
begin
  for Y := Rect.Left to Rect.Right do begin
    R := Round(GetRValue(Color1) + ((GetRValue(Color2) - GetRValue(Color1)) *
      Y / (Rect.Right - Rect.Left)));
    G := Round(GetGValue(Color1) + ((GetGValue(Color2) - GetGValue(Color1)) *
      Y / (Rect.Right - Rect.Left)));
    B := Round(GetBValue(Color1) + ((GetBValue(Color2) - GetBValue(Color1)) *
      Y / (Rect.Right - Rect.Left)));

    Canvas.Pen.Color := RGB(R, G, B);
    Canvas.Pen.Width := 1;
    Canvas.Pen.Style := psInsideFrame;

    Canvas.MoveTo(Y, Rect.Top);
    Canvas.LineTo(Y, Rect.Bottom);
  end;
end;

// Erstellt ein Farbverlauf von oben nach unten
procedure DrawGradientH(Canvas: TCanvas; Color1, Color2: TColor; Rect: TRect);
var
  X, R, G, B: Integer;
begin
  for X := Rect.Top to Rect.Bottom do begin
    R := Round(GetRValue(Color1) + ((GetRValue(Color2) - GetRValue(Color1)) *
      X / (Rect.Bottom - Rect.Top)));
    G := Round(GetGValue(Color1) + ((GetGValue(Color2) - GetGValue(Color1)) *
      X / (Rect.Bottom - Rect.Top)));
    B := Round(GetBValue(Color1) + ((GetBValue(Color2) - GetBValue(Color1)) *
      X / (Rect.Bottom - Rect.Top)));

    Canvas.Pen.Color := RGB(R, G, B);
    Canvas.Pen.Width := 1;
    Canvas.Pen.Style := psInsideFrame;

    Canvas.MoveTo(Rect.Left, X);
    Canvas.LineTo(Rect.Right, X);
  end;
end;


Hier jetzt der Aufruf aus dem Programm. Die Funktionen werden aus der OnPaint Prozedur des Formulars aufgerufen. Damit keine doppelte Pflege nötig ist, wird aus OnResize nicht die Funktion aufgerufen, sondern die OnPaint Prozedur:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm1.FormPaint(Sender: TObject);
begin
  DrawGradientH(Canvas, $00A2AA77$00FFFFE3, Rect(00, Width, Height));
end;

//bei Dialogfenstern alleine reicht OnPaint Prozedur,
//bei allen anderen Formen muß noch OnResize genutzt werden.
procedure TForm1.FormResize(Sender: TObject);
begin
  FormPaint(Self);
end;


Danke an blackbirdXXX für den Tipp mit OnResize


Noch ein kleiner Hinweis zu TPanes:

Bei TPanel versagt der Tipp, da TPanell keine Canvas-Fläche anbieten. TPanel behält dann ihre graue (oder sonnstige) Farbe und man hat eine graue Insel auf dem Formular.

Anstelle von TPanel kann man aber wunderbar TPaintBox nehmen. Hier kann man auch einen Farbverlauf zeichnen:


Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  if Sender is TPaintBox then with TPaintBox(Sender) do
    DrawGradientH(Canvas, $00000000$00FFFFFF, Rect(00, Width, Height));
end;