Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi TreeView AdvancedCustomDrawItem - Text färben geht nicht (https://www.delphipraxis.net/151016-treeview-advancedcustomdrawitem-text-faerben-geht-nicht.html)

himitsu 3. Mai 2010 10:40


TreeView AdvancedCustomDrawItem - Text färben geht nicht
 
Liste der Anhänge anzeigen (Anzahl: 1)
Mahlzeit.

Also, wenn ich dort z.B. einfach nur Folgendes reinschreibe und den Text via DefaultDraw zeichnen lasse, dann wird der Text rot.
Delphi-Quellcode:
Sender.Canvas.Font.Color := clRed;
Aber da ich nur einen bestimmten Teil der Zeile umfärben möchte, muß ich selber zeichnen,
allerdings ignoriert Sender.Canvas.DrawText sämtliche Farbangaben
und zeichnet immer nur mit der Systemvorgabe, wenn zusätzlich irgendwo noch ein Bitmap via Draw gezeichnet wird.
(also es bleibt bei der Systemvorgabe von clWindowsText wenn alleinestehend und clWindow, wenn Selektiert (blau hinterlegt).

Wenn man kein Bild gezeichnet wird, dann wird immer nur die erste Farbangabe verwendet.
Hier sollte es ja zweifarbig werden, wird es aber einfach nicht:
Delphi-Quellcode:
Font.Color := clWindowText;
TextOut(R.Left, R.Top, A.Text);
Inc(R.Left, TextWidth(A.Text));
Font.Color := clGrayText;
TextOut(R.Left, R.Top, ' (' + A.Source + ')');
Hab auch schon alle möglichen Farbangaben probiert
Delphi-Quellcode:
Sender.Canvas.Font.Color := clRed;
Sender.Canvas.Pen.Color := clRed;
Sender.Canvas.Brush.Color := clRed;
Und bei keiner ändert sich die Farbe.

Das Selbe gilt auch für Sender.Canvas.Font.Style .


Hier mal meine Methode:
Delphi-Quellcode:
Procedure TInsightForm.TreeView1AdvancedCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode;
  State: TCustomDrawState; Stage: TCustomDrawStage; Var PaintImages, DefaultDraw: Boolean);

Var A: IInsightAction;
  R:  TRect;

Begin
  If (Stage in [cdPrePaint, cdPostPaint]) and Assigned(Node) Then
    If Assigned(Node.Data) Then Begin
      A := IInsightAction(Node.Data);
      With Sender.Canvas do Begin
        R := Node.DisplayRect(False);
        FillRect(R);
        R := Node.DisplayRect(True);
        If Assigned(A.Image) Then Draw(R.Left - 16-1, R.Top, A.Image);
        Inc(R.Left, 1);
        Inc(R.Top, 1);
        //Font.Assign(TTreeView(Sender).Font);
        If cdsHot in State Then Font.Style := Font.Style + [fsUnderline];
        If cdsSelected in State Then Font.Color := clWindow
        Else If cdsHot in State Then Font.Color := clHotLight
        Else Font.Color := clRed;//clWindowText;
        TextOut(R.Left, R.Top, A.Text);
        Inc(R.Left, TextWidth(A.Text));
        If A.Source <> '' Then Begin
          Font.Color := clGrayText;
          TextOut(R.Left, R.Top, ' (' + A.Source + ')');
          Inc(R.Left, TextWidth(A.Source));
        End;
        If A.Hint <> '' Then Begin
          If cdsSelected in State Then Font.Color := clWindow
          Else If cdsHot in State Then Font.Color := clHotLight
          Else Font.Color := clWindowText;
          TextOut(R.Left, R.Top, ' - ' + A.Hint);
        End;
      End;
      DefaultDraw := False;
    End Else
      Sender.Canvas.Font.Style := Sender.Canvas.Font.Style + [fsBold];
End;
und alle von Default abweichende Einstellungen:
Code:
object TreeView1: TTreeView
  Left = 4
  Top = 40
  Width = 312
  Height = 237
  Anchors = [akLeft, akTop, akRight, akBottom]
  AutoExpand = True
  BorderStyle = bsNone
  HideSelection = False
  HotTrack = True
  Images = ImageList1
  Indent = 19
  ParentColor = True
  RightClickSelect = True
  RowSelect = True
  ShowButtons = False
  ShowLines = False
  ShowRoot = False
  TabOrder = 1
  OnAdvancedCustomDrawItem = TreeView1AdvancedCustomDrawItem
  OnChange = TreeView1Change
  OnDblClick = TreeView1DblClick
end
(in OnChange und OnDblClick passiert auch nix Entscheidendes)


Demo im Anhang (restliche Quellcodes in Hier im Forum suchenMyInsight zu finden):
betreffendes TreeView liegt hinter der Taste F6, bzw "call insight"

bei den "Edit"s liegt ein "unsichtbares" Bitmap/Icon davor, deshalb ist auch da der Effekt zu sehn
- Style und Farbe wird ignoriert

bei den Actions gibt es es kein Bild, dort sieht man den anderen Effekt
- nur erste Farbe wird übernommen (eigentlich sollte der Text in den Klammern grau werden)

und die fetten Überschriffen laufen erfolgreich über DefaultDraw



Also ich weiß einfach nicht mehr weiter und hab schon alle möglichen Threads durchgekramt und auch Vieles ausprobiert.


[add]
Hab es jetzt so weit eingrenzen können, daß sobald RequiredState aufgerufen wird
(also beim ersten aufruf einer Zeichenoperation, bzw. schon beim Auslesen des Canvas.Handle),
daß sich ab da nix mehr ändern läßt.
Alles was vorher festgelegt wurde (Canvas.Font.Color ändert nix, sondern speichert nur in FColor).

himitsu 4. Mai 2010 08:02

Re: TreeView AdvancedCustomDrawItem - Text färben geht nicht
 
Toll, ich fürchte ich bin mal wieder auf einen Fehler in der VCL gestoßen. :wall:

Die Fonts und andere Dinge werden nicht entsprechend recreatet (in D2006, D2009 und D2010 ... D7 konnte ich jetzt noch nicht testen)

wenn ich statt
Delphi-Quellcode:
Sender.Canvas.Font.Color := clGrayText;
direkt
Delphi-Quellcode:
SetTextColor(Sender.Canvas.Handle, ColorToRGB(clGrayText));
verwende, dann geht das Umfärben.

[edit]
Jetzt hatte ich schon vieles auf die WinAPI umgestellt
und dann bin ich zufällig auf eine "bessere" Lösung gestoßen.
Ich rufe jetzt einfach ein
Delphi-Quellcode:
Sender.Canvas.Refresh;
auf, bevor ich Farbe oder Style ändere.
Somit werden die Pen-, Brush-, und Color-Handles via Canvas.DeselectHandles freigegeben
und vor dem Zeichnen wieder mit den aktuellen Daten über Canvas.RequiredState neu erstellt. :stupid:


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz