AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

ListView - Problem beim Spaltenfärben

Ein Thema von e-gon · begonnen am 27. Jul 2017 · letzter Beitrag vom 28. Jul 2017
Antwort Antwort
e-gon

Registriert seit: 7. Jul 2003
Ort: Stuttgart
163 Beiträge
 
Delphi 6 Enterprise
 
#1

ListView - Problem beim Spaltenfärben

  Alt 27. Jul 2017, 09:47
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:
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;
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.

Aber clWindow sollte sich doch nicht ändern, oder?

Gruß
e-gon
  Mit Zitat antworten Zitat
e-gon

Registriert seit: 7. Jul 2003
Ort: Stuttgart
163 Beiträge
 
Delphi 6 Enterprise
 
#2

AW: ListView - Problem beim Spaltenfärben

  Alt 28. Jul 2017, 09:59
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:
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.
Tritt das Problem bei Euch auch auf? Und falls ja, weiß jemand woran das liegt?

Gruß
e-gon
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

AW: ListView - Problem beim Spaltenfärben

  Alt 28. Jul 2017, 11:37
Also bei mir passierts auch (Delphi 7)
Was geholfen hat ist:
ColorToRGB(clWindow);
Keine Ahnung warum das passiert
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
e-gon

Registriert seit: 7. Jul 2003
Ort: Stuttgart
163 Beiträge
 
Delphi 6 Enterprise
 
#4

AW: ListView - Problem beim Spaltenfärben

  Alt 28. Jul 2017, 13:06
Hallo Neutral General,

danke für die Antwort!

Also mit ColorToRGB(clWindow); könnte ich leben. Aber wundern tut es mich schon. Die beiden Variablen ListView1.Canvas.Brush.Color und clWindow sind schließlich vom gleichen Typ.

Gruß
e-gon
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: ListView - Problem beim Spaltenfärben

  Alt 28. Jul 2017, 13:09
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.

Edit2: Hab grad meine Theorie widerlegt. D.h. hab wieder keine Ahnung
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."

Geändert von Neutral General (28. Jul 2017 um 13:18 Uhr)
  Mit Zitat antworten Zitat
e-gon

Registriert seit: 7. Jul 2003
Ort: Stuttgart
163 Beiträge
 
Delphi 6 Enterprise
 
#6

AW: ListView - Problem beim Spaltenfärben

  Alt 28. Jul 2017, 13:16
Zitat:
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.
Das wäre zumindest eine Erklärung.
  Mit Zitat antworten Zitat
e-gon

Registriert seit: 7. Jul 2003
Ort: Stuttgart
163 Beiträge
 
Delphi 6 Enterprise
 
#7

AW: ListView - Problem beim Spaltenfärben

  Alt 28. Jul 2017, 13:29
Zitat:
Hab grad meine Theorie widerlegt. D.h. hab wieder keine Ahnung
Schade eigentlich...
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.354 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: ListView - Problem beim Spaltenfärben

  Alt 28. Jul 2017, 14:03
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.
Peter
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#9

AW: ListView - Problem beim Spaltenfärben

  Alt 28. Jul 2017, 14:06
Ohne jetzt in die Tiefen einsteigen zu wollen, habe ich mir das auch mal angesehen.
Habe mal statt clWindow manuell eine "zufällige" Farbe benutzt die mit $FF anfängt, aber KEINE Windows Farbe ist. Damit hat es auch funktioniert. (z.B. $FF000101)
Das ist auch was meine Theorien widerlegt hat.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:01 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