[gelöst] ListView Canvas OwnerDraw

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

[gelöst] ListView Canvas OwnerDraw

Beitrag von sstvmaster »

Hi,

ich brauche eure Hilfe. Im angehängten Programm weis nicht mehr weiter.
Zum Testen benötigt ihr ein zip Archiv.

In "TForm1.LVCustomDrawItem" setze ich die Texte und Brushes usw. aber irgendwie zeigt es mir das nicht so an wie ich gern will.
Wo ist mein Fehler?

Vielen Dank, erst mal.
Dateianhänge
ListviewCanvasOwnerDraw.zip
(153.28 KiB) 153-mal heruntergeladen
Zuletzt geändert von sstvmaster am Mo 30. Sep 2019, 11:59, insgesamt 2-mal geändert.
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: ListView Canvas OwnerDraw

Beitrag von wp_xyz »

Wenn ich jetzt noch wüsste, was du willst, könnte ich dir vielleicht helfen. So muss ich wieder raten...

Möglicherweise stört dich der weiße Hintergrund in der ersten Spalte? Den kriegst du mit Brush.Style := bsClear vor der Textausgabe weg.

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: ListView Canvas OwnerDraw

Beitrag von sstvmaster »

Ja das hat schon mal das erste Problem mit den wechselten hintergrund farben gelöst.

Code: Alles auswählen

 
    // draw mainitems text
    Brush.Style := bsClear; // <-- hinzugefügt
    for i := 0 to LV.Items.Count - 1 do begin
      rMainItem := LV.Items.Item[i].DisplayRect(drLabel);
      tsMainItem.Alignment := taLeftJustify;
      tsMainItem.Layout := tlCenter;
      TextRect
      (
        rMainItem,
        rMainItem.Left + 2,
        rMainItem.Top,
        LV.Items.Item[i].Caption,
        tsMainItem
      );
    end;
    // end 
 


Nun wäre noch schön das nun in Liste die Namen nicht Fett dargestellt werden.
Habe schon Pen.Width := 1 Pen.Color Brush.Color auf weiß gesetzt.

Also ich denke ich muss irgendwo einen Standard setzen?
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: ListView Canvas OwnerDraw

Beitrag von wp_xyz »

sstvmaster hat geschrieben:Nun wäre noch schön das nun in Liste die Namen nicht Fett dargestellt werden.

Ist mir beim ersten Blick gar nicht aufgefallen. Aber ja, die 1. Spalte sieht irgendwie fett aus, aber "seltsam fett", eher wie mehrmals mit leichten Unterschieden übermalt.

In diesem Zusammenhang fällt mir auf, dass du in der Routine immer alle Items durchläufst. Das ist so nicht gedacht, denn das OnDrawEvent wird für jeden Item separat aufgerufen. Es gibt ja auch den Parameter "Item", der signalisiert, welcher Item gerade dran ist. Außerdem gibt es separate Events für die 1.Spalte (OnCustomDrawItem) und SubItems (OnCustomDrawSubitem). Außerdem gibt es noch die ominösen OnAdvancedCustomDrawItem und OnAdvancedCustomDrawSubItem Events, die sich mir nie erschlossen haben.

Schau dir mal http://delphidabbler.com/articles?article=16 an - sieht recht verständlich aus. (Und auch die mit Google-Translate erzeugte Übersetzung ins Deutsche erscheint vernünftig - falls du nicht ausreichend Englisch kannst).

Achtung: Ich habe einen uralten Bug-Report auf meiner Watch-Liste (https://bugs.freepascal.org/view.php?id=25397): Man kann einzelne Items nicht fett darstellen (aber das ist ja nicht das Problem bei dir).

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: ListView Canvas OwnerDraw

Beitrag von sstvmaster »

Ja diese Seite hatte ich schon mal gefunden, ich lese die mir mal durch. Englisch ist kein Problem.

Dann werde ich mein Programm mal umbauen.

Danke erst mal!
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: ListView Canvas OwnerDraw

Beitrag von sstvmaster »

So anbei mal zwei Beispiele:

1. Beispiel:
- Konvertiertes Demo von der angegebenen Seite
- Hier funktioniert die Darstellung im 2. TabSheet mit Odd row

2. Beispiel:
- SimpleDemoListView: Erstellt mit Laz204 x32
- Hier nur ein ListView mit den gleichen Einträgen
- hier wird nur col 0 mit odd row versehen

Wenn man sich beide Beispiel genau anschaut stellt man fest, das
im konvertierten Demo der ListView "TitleStyle" tsStandard steht.

Im 2. Beispiel steht der Style auf tsNative.

Vielleicht hat es in diesen Beispielen damit was zu tun.
Dateianhänge
SimpleDemoListView.zip
2. Beispiel
(127.12 KiB) 159-mal heruntergeladen
SiteDemoListView.zip
1. Beispiel
(13.03 KiB) 148-mal heruntergeladen
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: ListView Canvas OwnerDraw

Beitrag von wp_xyz »

Ich verstehe nicht. Ist das eine Info oder eine Frage? TitleStyle sagt mir in Bezug auf TListView gar nichts.

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: ListView Canvas OwnerDraw

Beitrag von sstvmaster »

Thema beendet!!!
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: [nix mehr] ListView Canvas OwnerDraw

Beitrag von fliegermichl »

Ui, das Thema hat aber ein schroffes Ende gefunden.

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: [gelöst] ListView Canvas OwnerDraw

Beitrag von sstvmaster »

Hi,

ich habe es mir schon fast gedacht, ListView verhält sich in Lazarus anders als in Delphi.
Auch im englischen Forum wurde sich des öfteren schon gewundert.

Hier nur ein Beispiel:
https://forum.lazarus.freepascal.org/in ... ic=31945.0

Also Danke nochmal.
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: [gelöst] ListView Canvas OwnerDraw

Beitrag von wp_xyz »

Schon klar. LCL ist intern anders als VCL, da gibt es Unterschiede, wobei aber nicht gesagt ist, dass ein 3 Jahre alter Post noch zutrifft. Ich verstehe immer noch nicht, was dein letzter Post von gestern aussagen will. Wenn etwas nicht funktioniert, dann sage es, und ich kann es mir anschauen.

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: [gelöst] ListView Canvas OwnerDraw

Beitrag von sstvmaster »

Mit dem TitleStyle hat es nichts zu tun, da hast du Recht.

Beispiel.JPG

Im Bild links sieht man das "Odd Row" durchgezogen ist (Das ist das konvertierte Demo).
Rechts das selbst erstellte Programm mit Laz204, hier nur "Col 0" mit "Odd row".
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: [gelöst] ListView Canvas OwnerDraw

Beitrag von wp_xyz »

Das ist offenbar, weil du einen leeren Handler für OnCustomDrawSubItem eingebunden hast. Entferne diesen, dann werden auch die SubItems mit der entsprechenden Hintergrundfarbe hinterlegt. Allerdings wird das Verhalten der TCustomListView stark vom Widgetset dominiert. Daher kann man sich nicht darauf verlassen, dass bei einer Cross-Platform-Anwendung sich alle Widgetsets genauso verhalten wie das für Windows. Ich würde daher auch den OnCustomDrawSubitem-Handler implementieren und ihm denselben Code geben wie dem OnCustomDrawItem-Handler:

Code: Alles auswählen

procedure TForm1.LVCustomDrawItem(Sender: TCustomListView; Item: TListItem;
  State: TCustomDrawState; var DefaultDraw: Boolean);
begin
  if Odd(Item.Index) then
    LV.Canvas.Brush.Color:=$CCFFCC
  else
    LV.Canvas.Brush.Color:=clWindow;
end;
 
procedure TForm1.LVCustomDrawSubItem(Sender: TCustomListView; Item: TListItem;
  SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
  LVCustomDrawitem(Sender, Item, State, DefaultDraw);
end

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: [gelöst] ListView Canvas OwnerDraw

Beitrag von sstvmaster »

Hallo wp,

ich habe es geschafft. So wie du weiter oben schon richtig bemerkt hast darf man die Spalte 0 nicht selbst mit "for i:=0 to ..."
durchlaufen lassen. Das macht "CustomDrawItem" selbst. Bei den SubItems muss das natürlich gemacht werden.

Code: Alles auswählen

 
procedure TfrmMain.LVCustomDrawItem(Sender: TCustomListView; Item: TListItem;
  State: TCustomDrawState; var DefaultDraw: Boolean);
var
  i: Integer;
  r: TRect;
  ts: TTextStyle;
begin
 
  // text style pre defs
  ts.Layout      := tlCenter;
  ts.Clipping    := True;
  ts.RightToLeft := False;
  ts.Wordbreak   := False;
 
  // lets draw
  with Item.ListView.Canvas do begin
 
    // draw rect for mouse move
    if (Item.Index = iItemIndex) then begin
      r := Item.DisplayRect(drBounds);
      with Item.ListView.Canvas do begin
        Pen.Color := RGBToColor(184,214,251); // frame color
        Brush.Color := RGBToColor(235,243,253);
        RoundRect(r,4,4);
      end;
    end;
    // end
 
    // draw rect if selected
    if Item.Selected then begin
      r := Item.DisplayRect(drBounds);
      Pen.Color := RGBToColor(125,162,206);
      Brush.Color := RGBToColor(193,219,252);
      RoundRect(r,4,4);
    end;
    // end
 
    // draw icons
    with LV.SmallImages do begin
    Draw
    (
      Item.ListView.Canvas,
      Item.DisplayRect(drIcon).Left,
      Item.DisplayRect(drIcon).Top + 1,
      Item.ImageIndex,
      DrawingStyle,
      ImageType
    );
    end;
    // end
 
    // draw mainitems text
    r := Item.DisplayRect(drLabel);
    ts.Alignment := Item.ListView.Column[0].Alignment;
    TextRect(r, r.Left + 2, r.Top, Item.Caption, ts);
    // end
 
    // draw subitems text
    for i := 0 to Item.SubItems.Count - 1 do begin
      r := Item.DisplayRectSubItem(i + 1, drLabel); // get rect for current subitem
      r := Rect(r.Left + 6, r.Top, r.Right - 6, r.Bottom); // set margins for rect
      ts.Alignment := Item.ListView.Column[i + 1].Alignment; // get textstyles
      TextRect(r, r.Left, r.Top, Item.SubItems[i], ts); // draw subitems
    end;
    // end
 
  end;
  // end with
 
  DefaultDraw := False;
 
end;
 
 
Dateianhänge
ListviewCanvasOwnerDraw_2.zip
(155.07 KiB) 169-mal heruntergeladen
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

Antworten