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 ListView-Eintrag wird bei Windows 7 schwarz (https://www.delphipraxis.net/152493-listview-eintrag-wird-bei-windows-7-schwarz.html)

Deep-Sea 24. Jun 2010 12:55

ListView-Eintrag wird bei Windows 7 schwarz
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallöchen,
mich plagt seit einiger Zeit ein kleiner Grafikfehler mit der ListView unter Windows 7 - und das soll nun ein Ende haben :-D

Erst einmal ein Bild, damit man sieht, was gemeint ist:
Anhang 31513

Wie man sieht ist der zweite Eintrag schwarz, obwohl dort das gleiche drin steht wie in den anderen beiden. Ein Eintrag wird schwarz, wenn ich mit der Maus darüber fahre - aber auch nicht immer, keine Ahnung woran das liegt. Das passiert aber auch nur, wenn ich selbst etwas zeichne (in dem Beispiel einen Button). Hier mal der Quellcode:
Delphi-Quellcode:
procedure TForm1.ListView1AdvancedCustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
  var DefaultDraw: Boolean);
begin
  If Stage = cdPostPaint then With Sender as TListView do
  begin
    Button1.PaintTo(Canvas, Columns[0].Width, Item.DisplayRect(drBounds).Top);
  end;
end;
Wie man sieht, nichts besonderes. Mehr ist in dem ganzen Beispielprogramm auch nicht enthalten. Der ViewStyle der ListView steht auf vsReport (wie man ja eig. sieht).
Es tritt nur unter Windows 7 auf (ggf. auch Vista, aber das kann ich nicht testen), unter XP aber nicht.
Jemand eine Idee? :stupid:

Deep-Sea 28. Jun 2010 11:06

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
*push*

Och kommt schon, ihr wollt mir doch net sagen, dass noch niemand mal selbst etwas in eine ListView gezeichnet hat?! :-D

ChrisE 28. Jun 2010 13:54

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Kannst du mal das Beispielprojekt anhängen?

Und tritt es nur unter Windows 7 auf oder auch unter Vista?

Greez, Chris

DeddyH 28. Jun 2010 14:04

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Zitat:

Zitat von Deep-Sea (Beitrag 1031282)
Es tritt nur unter Windows 7 auf (ggf. auch Vista, aber das kann ich nicht testen), unter XP aber nicht.

;) Ich hab hier Vista, ein Beispielprojekt kann ich gern mal schnell testen.

Deep-Sea 28. Jun 2010 14:17

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Liste der Anhänge anzeigen (Anzahl: 1)
So, bitte sehr - da habt ihr das riesige Projekt :P

DeddyH 28. Jun 2010 14:24

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Jepp, passiert unter Vista auch. Allerdings ist mir aufgefallen (ich habe 3 Testeinträge gemacht), dass dies nur passiert, wenn man "von oben", d.h. vom vorherigen Eintrag kommt. Zieht man durch bis zum letzten und geht dann wieder zurück, ist die Darstellung normal.

Deep-Sea 28. Jun 2010 14:30

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Gut, dass es unter Vista ähnlich ist, war zu erwarten.

Das mit dem "von oben kommen" ist hier so, stimmt. Im eigentlich Programm um das es geht ist ein Eintrag immer schwarz, egal von wo ich komme. Allerdings nutzt dieses Programm auch Gruppen. Das Problem ist denke ich aber das gleiche ...

ChrisE 28. Jun 2010 14:36

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Zitat:

Zitat von DeddyH (Beitrag 1032097)
Jepp, passiert unter Vista auch...wenn man "von oben", d.h. vom vorherigen Eintrag kommt...

Kann ich bestätigen.

Außerdem scheint es nur der Texthintergrund zu sein. Der scheint schwarz zu werden.

Ich hab mit Delphi 2007 getestet.

Greez, Chris

[Edit]Font.Color := clRed bei Listview1 und man sieht was ich meine[/Edit]

Bummi 28. Jun 2010 14:39

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Delphi-Quellcode:
procedure TForm1.ListView1AdvancedCustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
  var DefaultDraw: Boolean);
begin
If (Stage = cdPostPaint) then
With Sender as TListView do
  begin

     Button1.PaintTo(Canvas, Columns[0].Width, Item.DisplayRect(drBounds).Top);
     Brush.Style := bsClear;
  end;

end;

ChrisE 28. Jun 2010 14:49

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Oh man, dass hatte ich doch auch probiert...

Sch... With-Anweisungen. Immer das selbe. Da sehe ich doch jedes mal den Kontext nicht mehr :-(

Aber so geht es zumindest bei mir (Vista -> Delphi 2007)

Greez, Chris

Deep-Sea 28. Jun 2010 15:02

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Jap, TWinControl.Brush.Style := bsClear; löst das Problem (es reicht aber aus, wenn man es einmal aufruft, es muss nicht bei jedem Draw-Ereignis sein. Zumindest bei meinem kurzen Test eben, oder?)
Super, was für ein Schei* wieder mal ...
Danke Bummi :-D

Edit:
Zu früh gefreut. Es geht nicht. Es ist eig. noch schlimmer. Wenn man Gruppen nutzt, geht ja nichts mehr (beim eig. Programm ist alles außer den Items schwarz, beim Test aktualisieren sich die Einträge nicht mehr beim scrollen, ...)

Bernhard Geyer 28. Jun 2010 15:17

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Du musst schon dafür sorgen das dein Canvans mit deinen gewünschten Werten (Hintergrundfarbe, ...) belegt ist. Du weißt ja nicht für das er schon "mißbraucht" wurde. Bei Gruppierung wird ja die Gruppierungszeile auch mit dem Canvas gezeichnet so das dieser zwangsweise "verstellt" ist.

Deep-Sea 28. Jun 2010 15:21

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1032109)
Du musst schon dafür sorgen das dein Canvans mit deinen gewünschten Werten (Hintergrundfarbe, ...) belegt ist.

Ich zeichne den (fehlerhaft dargestellten) Text aber doch gar nicht :?

Edit:
Selbst wenn ich immer - unabhängig von Stage - folgendes mache: Canvas.Brush.Color := clRed; tritt der Fehler weiterhin genau so in Erscheinung.

ChrisE 28. Jun 2010 15:30

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Wobei dein Beispiel-Projekt so ja funktioniert, oder?
Delphi-Quellcode:
var
  lv: TListView;
begin
  If (Stage = cdPostPaint) and (Sender is TListView) then
  begin
    lv := Sender as TListView;
    Button1.PaintTo(lv.Canvas, lv.Columns[0].Width, Item.DisplayRect(drBounds).Top);
    lv.Brush.Style := bsClear;
  end;
end;
Greez, Chris

Deep-Sea 28. Jun 2010 15:34

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Zitat:

Zitat von ChrisE (Beitrag 1032112)
Wobei dein Beispiel-Projekt so ja funktioniert, oder? [...]

Siehe den Nachtrag von Post #11. Es geht, aber nicht mit Gruppen (die ich eben auch nutze).

Bummi 28. Jun 2010 15:37

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Ich nutze ListView nie, aber wenn Du auf den Hoovereffekt verzichten kannst, oder mehr zu Fuß machen willst könntest auch OwnerDraw auf true setzen?

ChrisE 28. Jun 2010 15:43

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Zitat:

Zitat von Deep-Sea (Beitrag 1032113)
Siehe den Nachtrag von Post #11. Es geht, aber nicht mit Gruppen (die ich eben auch nutze).

Dann werde ich hier wohl aussteigen müssen. Hab nur D2007. Da gibts keine Groups.
Ein Tipp wäre noch, dass ganze nicht in OnAdvancedCustomDrawItem sondern in OnAdvancedCustomDrawSubItem aus zu probieren und es nur zu machen wenn SubItem = 1 ist.

Greez, Chris

Deep-Sea 28. Jun 2010 15:50

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Zitat:

Zitat von Bummi (Beitrag 1032115)
[...] wenn Du auf den Hoovereffekt verzichten kannst, oder mehr zu Fuß machen willst könntest auch OwnerDraw auf true setzen?

Mh ... Hoover brauch ich für den konkreten Fall zwar nicht, aber alles selbst zu zeichen und den wahren Fehlergrund nicht zu kennen sehe ich nicht wirklich als befriedigende Lösung an :stupid:


Zitat:

Zitat von ChrisE (Beitrag 1032117)
Dann werde ich hier wohl aussteigen müssen. [...] Ein Tipp wäre noch, dass ganze nicht in OnAdvancedCustomDrawItem sondern in OnAdvancedCustomDrawSubItem aus zu probieren [...]

Schade. Und: In OnAdvancedCustomDrawSubItem geht es genau so wenig.

Bummi 28. Jun 2010 15:55

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Zitat:

Mh ... Hoover brauch ich für den konkreten Fall zwar nicht, aber alles selbst zu zeichen und den wahren Fehlergrund nicht zu kennen sehe ich nicht wirklich als befriedigende Lösung an
stimmt, befriedigend ist es nicht ...
mit Deinem ursprünglichen Code und Ownerdraw=true sieht es bai mir aber halbwegs brauchbar aus, auch ohne zusätzlicuen Code.

Muß los
LG
Bummi

Deep-Sea 29. Jun 2010 07:17

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Zitat:

Zitat von Bummi (Beitrag 1032120)
mit Deinem ursprünglichen Code und Ownerdraw=true sieht es bai mir aber halbwegs brauchbar aus, auch ohne zusätzlicuen Code.

Sofern man keine SubItems nutzt, denn diese werden dann nicht mehr automatisch gezeichnet.

Deep-Sea 5. Jul 2010 08:10

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
So, noch mal ein kleiner push ...
Vielleicht hat ja heute jemand einen Geistesblitz?! :-D
Denn der Fehler ist doof und alles selber Zeichnen ist auch net schön ...

ChrisE 5. Jul 2010 09:19

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Hallo,

versuch doch mal bitte folgendes:
Delphi-Quellcode:
procedure TForm1.ListView1AdvancedCustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
  var DefaultDraw: Boolean);
var
  lv: TListView;
  ACanvas: TCanvas;
begin
  if (Sender is TListView) and (Stage = cdPostPaint) then
  begin
    lv := Sender as TListView;
    ACanvas := TCanvas.Create;
    ACanvas.Handle := GetWindowDC(Item.Handle);
    try
      Button1.PaintTo(ACanvas, lv.Columns[0].Width, Item.DisplayRect(drBounds).Top);
    finally
      ReleaseDC(Item.Handle, ACanvas.Handle);
      ACanvas.Free;
    end;
  end;
end;
Funktioniert bei mir. Aber eben nur unter D2007 und Vista ohne Groups.

Greez, Chris

Deep-Sea 5. Jul 2010 09:50

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Wenn man einen TControlCanvas nimmt klappt es wunderbar (sonst gibt es Grafikfehler etc.). DoubleBuffered kann man dann zwar nicht mehr benutzen aber das ist erst mal egal.
Danke :thumb:

ChrisE 27. Sep 2011 10:45

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Hallo,

ich hole diesen Thread nochmal hoch. Ich habe ganz konkret dieses Problem (also von diesem Thread) und brauch aber DoubleBuffered.

Das Problem ist: Reagiert man auf OnAdvancedDrawItem und OnAdvancedDrawSubItem (OwnerDraw = FALSE) um quasi noch etwas zu ergänzen, dann bekommt man diesen Schwarz-Effekt, sobald man auf die Canvas von Listview zeichnet. Zeichnet man auf eine ACanvas deren Handle man per GetWindowDC holt, wird die Zeichenaktion nicht / selten sichtbar.:shock:
Es muss irgendetwas mit dem DoubleBuffered-Mechanismus zu tun haben - aber da steig ich irgendwie nicht durch :-(

Kennt jemand eine Lösung?

Gruß, Chris

P.S.: System Win 7 / Applikation mit Themes

CCRDude 27. Sep 2011 10:51

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Wenn ich jetzt sage, daß ich das Problem auch schon hatte, aber irgendwie gelöst habe, ohne mich daran erinnern zu können, hilft das auch nicht weiter, oder? :shock:

Also habe ich nochmal gesucht und den von mir gefundenen Workaround im Embarcadero-Forum gefunden :)

Auch wenn der Schwarz-Effekt dort nicht explizit steht, mit SetBkMode plus Font-Anpassung waren bei mir beide Probleme verschwunden.

ChrisE 27. Sep 2011 14:25

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Hallo,

danke, das hat geklappt. :thumb:

Gruß, Chris

Deep-Sea 1. Nov 2011 11:14

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Nebenbei gibt es von mir auch mal was neues.
Ich habe bei mir das Problem erneut aufgegriffen, um ebenfalls DoubleBuffered wieder nutzen zu können. Irgendwie erscheint mir die Lösung extrem banal. In den ganzen Posts haben wir nur versucht, den Brush-Style der ListView selbst zu ändern, aber nicht den von ihrem Canvas.
Delphi-Quellcode:
Sender.Canvas.Brush.Style := bsClear;

Dieser kleine Code - vor allen anderen Zeichenaktionen ausgeführt - hat mein Problem behoben :thumb: DoubleBuffered ist ebenfalls wie gewohnt nutzbar.

Helmi 28. Jun 2014 10:13

AW: ListView-Eintrag wird bei Windows 7 schwarz
 
Hallo,

ich habe bei einer Software das gleiche Problem.

Den Vorschlag mit
Delphi-Quellcode:
Sender.Canvas.Brush.Style := bsClear;
hab ich ausprobiert, nur leider ohne Erfolg.
Das dumme ist, dass das Problem auf meinem Win8-Rechner nicht mehr auftaucht - nur auf meinem (neuen)
Win7-Rechner in der Firma (und kann es somit nicht testen)

Hab ich das
Delphi-Quellcode:
Sender.Canvas.Brush.Style := bsClear;
an der falschen Stelle drin oder generell einen
Fehler diesbezüglich?

Bei XP hat es bislang ohne dieser Zeile funktioniert (danach anscheinend auch wieder)

Delphi-Quellcode:
procedure TMainForm.ListView_DateienCustomDrawSubItem(Sender: TCustomListView;
  Item: TListItem; SubItem: Integer; State: TCustomDrawState;
  var DefaultDraw: Boolean);
var
  S_Text   : String;
  Diff_Top : Integer;
  Rect     : TRect;
  Textfarbe : TColor;

begin
  //Rect der Zelle erhalten
  ListView_GetSubItemRect(Sender.Handle, Item.Index, SubItem, LVIR_BOUNDS, @Rect);

  Sender.Canvas.Brush.Style := bsClear;

  //Hintergrundfarbe
  Sender.Canvas.Brush.Color := clWindow;

  //Farbe?
  If ListViewTextFarbe(Textfarbe, S_Text, Item.SubItems[SubItem - 1]) then
    begin
      //Schriftfarbe
      Sender.Canvas.Font.Color := Textfarbe;

      //Hintergrundfarbe und Textfarbe setzen, wenn die Zeile markiert ist
      If Item.Selected then
        begin
          Sender.Canvas.Font.Color := clHighlightText;
          Sender.Canvas.Brush.Color := clHighlight;
        end;

      //Differenz für Top berechnen, um Text mittig darzustellen
      Diff_Top := (Rect.Height - Sender.Canvas.TextHeight(S_Text)) div 2;

      //Text ausgeben
      Sender.Canvas.TextRect(Rect, Rect.Left + 5, Rect.Top + Diff_Top, S_Text);

      DefaultDraw := False;
    end;
end;


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