Einzelnen Beitrag anzeigen

Popov
(Gast)

n/a Beiträge
 
#14

AW: Idee für Auswahlfunktion

  Alt 13. Okt 2012, 19:37
An für sich ist das nicht kompliziert, eher nur malen nach Zahlen, d. h. du hast deine Canvas auf der du zeichnest. Das ist fast genauso wie zeichnen auf dem Canvas des Formulars, einer Bitmap oder Image. Allerdings müssen hier vor allem drei Punkte beachtet werden.

Der erste ist, dass du schon auf der richtigen Canvas zeichnen mußt. Als Parameter bekommst du nur Control: TWinControl und nicht TListBox . Du mußt Control also sagen, dass es eine TListbox ist. Das machst du mit with (Control as TListbox) do
Delphi-Quellcode:
procedure TForm1.ListBox1DrawItem(Control: TWinControl;
  Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
  with (Control as TListbox) do
  begin
    ...
  end;
end;
Ob du nun mit With arbeitest (mußt du nicht, du kannst aber) oder anders, z. B. so

Delphi-Quellcode:
procedure TForm1.ListBox1DrawItem(Control: TWinControl;
  Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
  MyListBox: TListBox;
begin
  MyListBox := (Control as TListbox);
  MyListBox.Canvas. ...
ist eigentlich egal. Beides geht.

Der zweite wichtige Punkt ist, dass du eigentlich auf der ganzen ListBox Canvas zeichnen kannst, aber das willst du ja nicht. Du willst nur auf dem kleinem Streifen des Items zeichnen. Dazu bekommst du den Parameter Rect: TRect . Jedes Item hat seinen eigenen Rect Bereich. Du mußt beim Zeichnen also in dem Bereich bleiben.

Die Prozedur OnDrawItem funktioniert so: sie wird so oft aufgerufen wie viele Items sichtbar sind. Sind fünf Items sichtbar, wird die Prozedur auch fünf mal aufgerufen. Nur bekommst du jedes Mal passend zu dem Item andere Rect Werte. Willst du also an Koordinate 1 und 1 einen Punkt setzten, dann nicht MyListBox.Canvas.Pixels[1, 1] := clBlack , sondern MyListBox.Canvas.Pixels[Rect.Left + 1, Rect.Top + 1] := clBlack . Du mußt also immer im Verhältnis zu Rect zeichnen. Läßt du es weg, zeichnest du alles oben in der ListBox.

Nur bedenke, man kann auch drüberzeichen in das darunterliegende Item. Die Begrenzung nach unten ist Rect.Bottom , nach rechts Rect.Right . Also immer schön im im Bereich bleiben und es immer wieder überprüfen. Außerdem sollte man bedenken, dass es auch eine Funktion Rect gibt. Die Namenswahl des Parameters ist nicht sonderlich glücklich, aber auch keine Katastrophe. Man muß eben aufpassen. Wenn eine Fehlermeldung kommt, dann sollte men es nur wissen um was es geht.

Der dritte wichtige Punkt ist, dass man die State: TOwnerDrawState Parameter betrachten sollte. Denn die sagen einem was für ein Item das aktuelle Item ist. Ist es ein normales Item oder eine der den Fokus besitz oder ist er gerade selektiert.

Delphi-Quellcode:
  with (Control as TListbox) do
  begin
    if odSelected in State then
      Canvas.Font.Color := clInactiveCaptionText
    else
      Canvas.Font.Color := clWindowText;
Das Beispiel fragt ab ob der Item gerade selektiert ist. In diesem Fall ändert sich die Schriftfarbe. Die Hintergrundfarbe ist schon automatisch in Brush.Color eingestellt. Eigentlich mußt du die Textfarbe und Hintergrundfarbe nicht einstellen, da sie schon voreingestellt sind. Das ist nur dann wichtig wenn du deine eigenen Farben wählen willst. Ansonsten bekommst du die Systemfarben voreingestellt.

Wenn man sein eigenes Design wählen will, dann muß man die Hintergrundfarbe ändern, die Schriftfarbe, dann den Focus löschen und durch seinen eigenen ersetzte. Aber das erkläre ich evt. später, sonst verwirrt das alles nur.

Zuletzt noch der Hinweis, dass Index: Integer den Index beinhaltet der bei dem Durchlauf gerade gezeichnet wird.
  Mit Zitat antworten Zitat