![]() |
ListView - Problem beim Spaltenfärben
Hallo!
Gerade bin ich auf ein mir unerklärliches Phänomen beim Färben einer Spalte eines ListViews gestoßen. Kann es sein, dass die Systemvariable clWindows während eines CustomDraws den Inhalt ändert? Folgender Code soll die angeklickte Spalte (ListView1SortCol) mit einem hellen Gelb markieren:
Delphi-Quellcode:
Die Spalten vor ListView1SortCol werden mit korrektem Hintergrund angezeigt, während die Spalten danach mit der gleichen Farbe wie die markierte Spalte gefärbt werden. Erstetze ich jedoch clWindow durch clWhite, funktioniert alles.
procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean); begin if ListView1SortCol=0 then ListView1.Canvas.Brush.Color:= $E4FFFF else ListView1.Canvas.Brush.Color:= clWindow; end; procedure TForm1.ListView1CustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean); begin if ListView1SortCol=SubItem then ListView1.Canvas.Brush.Color:= $E4FFFF else ListView1.Canvas.Brush.Color:= clWindow; end; Aber clWindow sollte sich doch nicht ändern, oder? Gruß e-gon |
AW: ListView - Problem beim Spaltenfärben
Guten Morgen!
Entweder nutze ich die falschen Suchbegriffe, dieses Phänomen tritt nur bei mir auf (mit D6 und D2009 unter Windows 7) oder es hat noch niemand entdeckt. Eine Antwort hätte ich aber dennoch gerne. Weiß wirklich niemand etwas dazu? Damit das Nachvollziehen etwas einfacher geht, habe ich den Code erweitert. Diesen einfach in eine leere Unit kopieren, FormCreate und FormDestroy verbinden und nach der Ausführung auf die Spalten klicken.
Delphi-Quellcode:
Tritt das Problem bei Euch auch auf? Und falls ja, weiß jemand woran das liegt?
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure ListView1CustomDrawItem(Sender: TCustomListView; Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean); procedure ListView1CustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean); procedure ListView1ColumnClick(Sender: TObject; Column: TListColumn); procedure FormDestroy(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation var ListView1SortCol: Integer; ListView1: TListView; {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var ListItem: TListItem; ListColumn: TListColumn; x,y: Integer; begin ListView1:= TListView.Create(Self); ListView1.Parent:= Form1; ListView1.Top:= 8; ListView1.Left:= 8; ListView1.Width:= 400; ListView1.OnColumnClick:= ListView1ColumnClick; ListView1.OnCustomDrawItem:= ListView1CustomDrawItem; ListView1.OnCustomDrawSubItem:= ListView1CustomDrawSubItem; ListView1.ViewStyle:= vsReport; for x:= 1 to 6 do begin ListColumn:= ListView1.Columns.Add; ListColumn.Caption:= IntToStr(x); end; for x:= 1 to 7 do begin ListItem:= ListView1.Items.Add; ListItem.Caption:= 'Zeile '+IntToStr(x); for y:= 1 to 6 do ListItem.SubItems.Add('Sub '+IntToStr(x)+'/'+IntToStr(y)); end; ListView1SortCol:= -1; end; procedure TForm1.FormDestroy(Sender: TObject); begin ListView1.Free; end; procedure TForm1.ListView1ColumnClick(Sender: TObject; Column: TListColumn); begin ListView1SortCol:= Column.Index; ListView1.Repaint; end; procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView; Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean); begin if ListView1SortCol=0 then ListView1.Canvas.Brush.Color:= $E4FFFF else ListView1.Canvas.Brush.Color:= clWindow; // <- hier tritt das Problem auf, obwohl Color den richtigen Wert enthält // else ListView1.Canvas.Brush.Color:= clWhite; end; procedure TForm1.ListView1CustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean); begin if ListView1SortCol=SubItem then ListView1.Canvas.Brush.Color:= $E4FFFF else ListView1.Canvas.Brush.Color:= clWindow; // <- hier tritt das Problem auf, obwohl Color den richtigen Wert enthält // else ListView1.Canvas.Brush.Color:= clWhite; // <- hier tritt das Problem auf, obwohl Color den richtigen Wert enthält end; end. Gruß e-gon |
AW: ListView - Problem beim Spaltenfärben
Also bei mir passierts auch (Delphi 7)
Was geholfen hat ist:
Delphi-Quellcode:
ColorToRGB(clWindow);
Keine Ahnung warum das passiert :gruebel: |
AW: ListView - Problem beim Spaltenfärben
Hallo Neutral General,
danke für die Antwort! Also mit
Delphi-Quellcode:
könnte ich leben. Aber wundern tut es mich schon. Die beiden Variablen
ColorToRGB(clWindow);
Delphi-Quellcode:
und
ListView1.Canvas.Brush.Color
Delphi-Quellcode:
sind schließlich vom gleichen Typ. :gruebel:
clWindow
Gruß e-gon |
AW: ListView - Problem beim Spaltenfärben
Der einzige Unterschied ist dass in clWindow nicht die eigentliche Farbe enthalten ist sondern quasi nur eine eine Art ID für die Fensterfarbe.
ColorToRGB wandelt diese "Pseudo-Farbe" um indem es mit einer API den wahren in Windows eingestellten Farbwert für clWindow herausfindet. Was das unterm Strich damit zu tun hat, dass clWindow dieses seltsame Verhalten hervorruft weiß ich allerdings auch nicht. Es sollte eigentlich auch ohne ColorToRGB funktionieren denke ich. Edit: Ich hab eine Theorie: Die ganzen "speziellen" Farben beginnen alle mit 0xFF, statt 0x00. Wenn man dieses Byte als Alphawert deuted (was vllt. die Windows API hinter dem ListView tut), dann ist clWindow einfach nur eine komplett durchsichtige Farbe. Und wenn intern das ListView so gezeichnet wird, dass nicht nur die aktuelle Spalte mit der Farbe gezeichnet wird, sondern von Spalte X bis zum Ende dann hätte man genau das verhalten. :gruebel: Edit2: Hab grad meine Theorie widerlegt. D.h. hab wieder keine Ahnung :mrgreen: |
AW: ListView - Problem beim Spaltenfärben
Zitat:
|
AW: ListView - Problem beim Spaltenfärben
Zitat:
|
AW: ListView - Problem beim Spaltenfärben
Ohne jetzt in die Tiefen einsteigen zu wollen, habe ich mir das auch mal angesehen.
Der Setter für die Farbe vergleicht, ob sich die Farbe überhaupt geändert hat. Falls nicht, macht er auch nichts und die alte Farbe bleibt erhalten. Soweit ist das ja auch ok. Aber, TColor ist definiert als -$7FFFFFFF-1..$7FFFFFFF. clWindow ist aber $FF000005 und liegt somit außerhalb dieses Bereichs, wenn ich das richtig sehe. Ob dann der Setter noch richtig arbeitet bei dem Farb-Vergleich, möchte ich zumindest kritisch beurteilen. Durch das ColorToGRB wird die tatsächliche Farbe verwendet. Der Standard ist wohl clWhite ($FFFFFF). Da das innerhalb des Wertebereichs liegt, funktioniert auch der Vergleich im Setter korrekt. Ich hab mir das wirklich nur kurz angesehen und in keinster Weise überprüft. Wenn ich mehr Zeit hätte, würde ich das mit dem Debugger mal prüfen. Aber vielleicht hat ja ein anderer User mehr Zeit als ich. :wink: |
AW: ListView - Problem beim Spaltenfärben
Zitat:
Das ist auch was meine Theorien widerlegt hat. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:56 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz