Autor Beitrag
Popov
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1655
Erhaltene Danke: 13

WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
BeitragVerfasst: Di 03.02.04 15:13 
Dazu benötigt man zuerst Funktionen die einen Farbverlauf generieren. Zu Auswahl gibt es zwei Funktionen:

  • Farbverlauf von links nach recht
  • Farbverlauf von oben nach unten

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:

ausblenden volle Höhe 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:

ausblenden 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:

ausblenden 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;

_________________
Popov


Zuletzt bearbeitet von Popov am Di 03.02.04 23:05, insgesamt 2-mal bearbeitet