Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Listview, CustomDrawSubItem, Text wird schwarz (https://www.delphipraxis.net/163949-listview-customdrawsubitem-text-wird-schwarz.html)

FrankJ28 23. Okt 2011 11:58

Listview, CustomDrawSubItem, Text wird schwarz
 
Hallo,
ich habe mit dem folgenden Code das CustomDrwawSubItem-Event befüllt. Der Testrahmen wird auch prima gezeichnet, die normal darzustellenden Spalten jedoch erhalten einen schwarzen Kasten, wenn text enthalten ist, Das aber auch nur, wenn der Cursor/Maus nach unten bewegt wird. Die Richtung nach oben erfolgt korrekt.

Delphi-Quellcode:
procedure TInfoAuftrDlg.PlanViewCustomDrawSubItem(Sender: TCustomListView;
  Item: TListItem; SubItem: Integer; State: TCustomDrawState;
  var DefaultDraw: Boolean);
var r : TRect;
    i : Integer;
begin
 if SubItem<5
    then begin
          DefaultDraw:=true;
          exit;
         end;
  r := Item.DisplayRect(drBounds);
  for i := 0 to SubItem-1 do begin
    r.Left := r.Left + PlanView.Columns.Items[i].Width;
    r.Right := r.Left + PlanView.Columns.Items[i+1].Width;
  end;
  if SubItem=5
     then PlanView.Canvas.Pen.Color := clRed
     else PlanView.Canvas.Pen.Color := clBlue;

  PlanView.Canvas.Rectangle(r.Left, r.Top, r.Right, r.Bottom);
  DefaultDraw := False;
end;
ListView ist vom Typ vsReport
Jemand eine zündene Idee?
Danke und ciao
Frank

Bummi 23. Okt 2011 13:19

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
ich verwende Listview eigentlich nie, aber so bekomme ich das IMHO gewünschte Ergebnis:


(kann sicher noch optimiert werden)

Delphi-Quellcode:
var r : TRect;
    i : Integer;
    s : String;
begin
  PlanView.Canvas.Brush.Color := clWhite;
  PlanView.Canvas.Brush.Style := bsclear;

 if SubItem<1
    then begin
          DefaultDraw:=true;
          exit;
         end;
  r := Item.DisplayRect(drbounds);


  for i := 0 to SubItem-1 do begin
    r.Left := r.Left + PlanView.Columns.Items[i].Width;
    r.Right := r.Left + PlanView.Columns.Items[i+1].Width;
  end;

  if SubItem=1
     then PlanView.Canvas.Pen.Color := clRed
     else PlanView.Canvas.Pen.Color := clBlue;


  PlanView.Canvas.FillRect(r);

  PlanView.Canvas.Rectangle(r.Left, r.Top, r.Right, r.Bottom);
  r.Left := r.Left +1;
  r.Right := r.Right - 1;
  r.Top := r.Top + 1;
  r.Bottom := r.Bottom - 1;
  if item.SubItems.Count >= SubItem then s := item.SubItems[SubItem-1];
  PlanView.Canvas.TextRect(r,s);
  DefaultDraw := false;
end;

FrankJ28 23. Okt 2011 13:42

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Thomas,
danke für deinen Einsatz, ich habe mich nur etwas blöd ausgedrückt. Nicht der Text in dem selbstgemalten SubItem, sondern alle Anderen werden schwarz. Un das nur, wenn Cursor oder Maus auf dem Weg nach unten sind, nach oben ist alles sichtbar.
siehe Bild
Anhang 35420
Noch eine Idee?
Ciao
Frank

DCoderHH 24. Mai 2018 09:04

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Genau das selbe Problem habe ich jetzt auch mit Delphi Tokyo: Wenn Items ausgewählt werden, wird der Text schwarz, wie auf dem Bildschirmfoto im letzten Post zu sehen. Hat da jemand in den letzten Jahren schon eine Lösung gefunden?

Whookie 24. Mai 2018 09:57

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Liste der Anhänge anzeigen (Anzahl: 1)
Habe das mit 10.2.3 als Minimalbeispiel umgesetzt und es funktioniert bei mir ohne schwarze Felder...

KodeZwerg 24. Mai 2018 10:00

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Hier wurde das
Zitat:

This is a workaround for the defective behavior rather than being an answer to the question if there's a bug in the VCL, and a few thoughts.

The workaround is to set the background mode of the device context assigned by the common control for item painting cyle to transparent after carrying out custom drawing:

Delphi-Quellcode:
procedure TForm1.ListViewCustomDrawSubItem(Sender: TCustomListView;
  Item: TListItem; SubItem: Integer; State: TCustomDrawState;
  var DefaultDraw: Boolean);
var
  R: TRect;
begin
  if not [CustomDrawing] then // <- If we're not gonna do anything do not
    Exit;                     //    fiddle with the DC in any way

  DefaultDraw := False;
  ListView_GetSubItemRect(Sender.Handle, Item.Index, SubItem, LVIR_BOUNDS, @R);
  Sender.Canvas.MoveTo(R.Left, R.Top);
  Sender.Canvas.LineTo(R.Right-1, R.Bottom-1);

  SetBkMode(Sender.Canvas.Handle, TRANSPARENT); // <- will effect the next [sub]item
end;

In an [sub]item paint cycle, the painting is always done in a top-down fashion, items having a lower index are sent NM_CUSTOMDRAW notification prior to ones with higher indexes. When the mouse is moved from one row to another, two rows need to be re-drawn - the one loosing the hot state, and the one gaining it. It would seem, when custom drawing is in-effect, drawing the row that's loosing the hot-state leaves the DC in an undesirable state. This is not a problem when moving the mouse upwards, because that item gets drawn last.

Custom drawing ListView and TreeView controls are different than custom drawing other controls and somewhat complicated (see: Custom Draw With List-View and Tree-View Controls). But you have full control over the entire process. The code in the NM_CUSTOMDRAW case of TCustomListView.CNNotify in 'comctrls.pas' of the VCL is equally complicated. But despite being provided a bunch of custom drawing handlers (half of them being advanced), you have no control over what the VCL does. For instance you can't return the CDRF_xxx you'd like or you can't set the clrTextBk you want. My biased opinion is that, there's a bug/design issue in the Delphi list view control, but I have nothing more concrete than an intuition as in finding a workaround.
als Lösung gepostet.

Gerade seh ich Rot und eine Whookie Lösung... ich schick die Info trotzdem ab:)

DCoderHH 24. Mai 2018 12:23

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Danke, aber bei beiden Lösungen ist das Problem, dass der Text in der der Spalte, die rechts neben der Owner-Draw-Spalte liegt, pixelig und fett wird. Ein manuelles setzten der Font schafft keine Abhilfe. Die Schrift ist immer pixelig und fett...

KodeZwerg 24. Mai 2018 12:31

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Poste noch mal Dein Projekt damit es nachvollziehen kann.

DCoderHH 24. Mai 2018 12:50

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hier das Projekt zum Testen und ein Screenshot mit dem Fehler (Text wird pixelig und fett)

Luckie 24. Mai 2018 14:03

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Das ist nicht pixelig und fett, das ist eine andere Schriftart.

DCoderHH 24. Mai 2018 14:09

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Zitat:

Zitat von Luckie (Beitrag 1402867)
Das ist nicht pixelig und fett, das ist eine andere Schriftart.

OK, aber warum ist es eine andere Schriftart und wie verhindere ich, dass diese für die Darstellung ausgewählt wird?

KodeZwerg 24. Mai 2018 14:41

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Ich habe alles was nicht zum Projekt gehört gelöscht so das nurnoch
Delphi-Quellcode:
Projekt1.dpr, Project1.res, Unit1.dfm, Unit1.pas
übrig blieb.
Delphi Tokyo mit der .dpr gestartet, auf Release gestellt, kompiliert, alles hat die gleiche Schrift. Ich kann Fehler nicht reproduzieren.

DCoderHH 24. Mai 2018 14:47

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Zitat:

Zitat von KodeZwerg (Beitrag 1402873)
Ich habe alles was nicht zum Projekt gehört gelöscht so das nurnoch
Delphi-Quellcode:
Projekt1.dpr, Project1.res, Unit1.dfm, Unit1.pas
übrig blieb.
Delphi Tokyo mit der .dpr gestartet, auf Release gestellt, kompiliert, alles hat die gleiche Schrift. Ich kann Fehler nicht reproduzieren.

Hab ich eben auch gemacht. Fehler ist trotzdem da. Die Windows-Version und Themes scheinen den Fehler zu beeinflussen, sagt eine Google-Recherche. Ich nutze Windows 10 mit der Standard-GUI, wie Windows ausgeliefert wird.

KodeZwerg 24. Mai 2018 14:48

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Ahh ok, ich nutze Windows Version 7. Ich schau mal im Code wegen Custom-Font setzen.

edit
Jetzt habe ich Deine .exe mal gestartet. Da erscheint der Fehler wie auf dem Bild.

himitsu 24. Mai 2018 15:10

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Delphi-Quellcode:
Sender.Canvas.Font.Assign(Sender.Font);
könntest du mal ausprobieren, ob es was ändert. (beim DefaultDraw=True)

Sowas wie SetBkMode an der VCL vorbei und nicht wieder zurücksetzen.
Das kann auch Probleme bereiten.

Sich nicht auf einwas zu einigen und dann abwechselnd Sender.Canvas oder PlanView.Canvas zu nutzen bereitet oftmals keine großen Probleme, aber ist dennoch keine gute Idee.

KodeZwerg 24. Mai 2018 15:16

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Ich habe ein wenig gelesen und das hier soll wohl helfen, da ich Fehler nicht habe kann ichs nicht testen.
Delphi-Quellcode:
procedure TForm1.PlanViewCustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer;
  State: TCustomDrawState; var DefaultDraw: Boolean);
var
  r: TRect;
  i: Integer;
begin
  PlanView.Canvas.Font.Style := [fsItalic];
  PlanView.Canvas.Font.Style := [];
//ab hier wie im Original weiter
Ps: Zweimal damit eine Veränderung eintritt.

EWeiss 24. Mai 2018 15:22

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Zitat:

Ich habe ein wenig gelesen und das hier soll wohl helfen, da ich Fehler nicht habe kann ichs nicht testen.
Wenn man den Font Assigned muss man ihn nicht extra nochmal zuweisen.

siehe..@himitsu
Delphi-Quellcode:
Sender.Canvas.Font.Assign(Sender.Font);
Zitat:

Jetzt habe ich Deine .exe mal gestartet. Da erscheint der Fehler wie auf dem Bild.
Ja was denn nu ist er da oder nicht?
Zitat:

da ich Fehler nicht habe kann ichs nicht testen.

Aber verstehe nicht was du da machst.
Du möchtest selbst die Schrift zeichnen mit OwnerDraw?
Wenn dem so ist warum wurde OwnerDraw nicht aktiviert.

So.. Und wenn du es aktivierst dann bist du für das zeichnen der Schrift Font etc.. selbst verantwortlich.

Da scheint mir ein mismatch zwischen OwnerDraw und zeichnen der eigenen Komponente zu sein.

gruss

KodeZwerg 24. Mai 2018 15:29

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
@EWeiss: Wenn ich sein 10mb Kompilat aus dem Anhang starte ist Font "verändert", wenn ich beiliegenden Source selbst kompiliere, auf Release eine 2mb Datei, da erscheint alles ohne Probleme.

EWeiss 24. Mai 2018 16:01

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Zitat:

Zitat von KodeZwerg (Beitrag 1402881)
@EWeiss: Wenn ich sein 10mb Kompilat aus dem Anhang starte ist Font "verändert", wenn ich beiliegenden Source selbst kompiliere, auf Release eine 2mb Datei, da erscheint alles ohne Probleme.

Na ok.. hab kein Tokyo daher bin ich raus.

gruss

KodeZwerg 24. Mai 2018 17:25

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von KodeZwerg (Beitrag 1402879)
Ich habe ein wenig gelesen und das hier soll wohl helfen, da ich Fehler nicht habe kann ichs nicht testen.
Delphi-Quellcode:
procedure TForm1.PlanViewCustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer;
  State: TCustomDrawState; var DefaultDraw: Boolean);
var
  r: TRect;
  i: Integer;
begin
  PlanView.Canvas.Font.Style := [fsItalic];
  PlanView.Canvas.Font.Style := [];
//ab hier wie im Original weiter
Ps: Zweimal damit eine Veränderung eintritt.

Das ist die Lösung auch wenn Ihr dagegen seid. Ich habe vom TE das Projekt auf Delphi2009 Niveau gebracht, lustiger Weise mit dem Fehler vom Bild, mit himitsus Methode streikt IDE oder ich wende es falsch an, IDE sagt E2362 Auf protected-Symbol TControl.Font kann nicht zugegriffen werden

Im Anhang ist das Projekt für viele Delphis verfügbar mit gleicher Font in allen Feldern.

DCoderHH 25. Mai 2018 07:12

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Danke an alle! Insbesondere an KodeZwerg: Seine zuletzt gepostete Löung funktioniert eiwandfrei. Das Problem geistert ja seit mehreren Jahren durch diverse Foren und Newsgroups und wurde nie gelößt. Ich bin begeistert!

Edit: Die Lösung von himitsu funktioniert auch, wenn man sie leicht modifiziert:
Sender.Canvas.Font.Assign(TListView(Sender).Font);
Edit2: Die Lösung von himitsu funktioniert manchmal doch nicht. Beim nächsten Start ist der Text manchmal trotzdem fett. Ganz komisch. Die Lösung von KodeZwerg läuft immmer.

KodeZwerg 25. Mai 2018 09:15

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Defaultdraw False dann True scheint die Font zu beeinflussen.
Ich habe ja nichts gegen himitsus Vorschlag, nur bringt der leider nichts.
Es muss effektiv einmal eine Fontveränderung eintreten sonst bleibts beim Fehler.
Wenn Du die selbstgemalte Spalte nach ganz rechts verlagerst ist Fehler auch behoben.
Freut mich das ich helfen konnte.

Luckie 25. Mai 2018 14:08

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Das ist übrigens die Standardschrift die Windows setzt, wenn man ohne VCL arbeitet und man keine Schrift setzt*, entweder in der Dialog-Ressource oder im Fenster per Code. Ich nehme das OwnerDraw arbeitet ähnlich: "Du willst selber zeichnen? Dann musst du aber auch alles selber zeichnen. Und mir sagen, was du für eine Schrift willst."

*) Siehe dazu meine Screenshots aus meinen nonVCL Tutorials von den ersten Demos.

himitsu 25. Mai 2018 14:17

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
DevExpress-Grigs und auch teilweise die VCL-Grids/List-Komponenten setzen oft vor den CustomDrawEvents den Pen/Brush/Font.

Klar, "falls" man dann im CustomDraw was Anderes setzt, ist das dann doppelt (Zeitverschwendung), aber es gibt weniger Probleme, vor allem wenn man dann doch nicht alles selber zeichnet. (z.B. nur Hintergrund- oder Textfarbe ändern und den Rest wieder das DefaulDraw machen lassen)

EWeiss 25. Mai 2018 18:26

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Zitat:

"Du willst selber zeichnen? Dann musst du aber auch alles selber zeichnen.
Das sagte ich schon bereits in diesem Beitrag..

Dabei spielt es keine rolle ob man das über Win32 API mitteln macht oder in der VCL.
Das andere ist alles ein Workaround mag funktionieren die Lösung ist aber nicht das gelbe vom Ei. (Meine persönliche Meinung)
Wenn man schon OwnerDraw verwendet dann bitte richtig mit allen Konsequenzen.

Zitat:

Es muss effektiv einmal eine Fontveränderung eintreten sonst bleibts beim Fehler.
Nö.. Man muss nur OwnerDraw richtig verwenden entweder ganz oder gar nicht.

Ich möchte einen Porsche, Kohle fehlt also nehme ich einen Käfer und rüste ihn mit den Schlufen eines Porsche aus.
So in etwa geht das hier ab.

gruss

KodeZwerg 25. Mai 2018 19:24

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Mit fehlt da die Erfahrung aber ich kenn da jemand der ist Experte in OwnerDraw hehe
Tutorials darüber sind auch rar gesät.

EWeiss 25. Mai 2018 20:27

AW: Listview, CustomDrawSubItem, Text wird schwarz
 
Zitat:

Zitat von KodeZwerg (Beitrag 1403006)
Mit fehlt da die Erfahrung aber ich kenn da jemand der ist Experte in OwnerDraw hehe
Tutorials darüber sind auch rar gesät.

Na ja ich helfe gern habe aber kein Tokyo und keine Lust immer alles um zu modeln. ;)

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:18 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