开发者

Delphi: bug when resizing columns of List View (on DrawItem)

开发者 https://www.devze.com 2023-03-18 20:51 出处:网络
Enable Autosize of columns and enable OwnerDraw for a List View. Then add a code below from HERE: procedure TForm1.ListView1DrawItem(Sender: TCustomListView; Item: TListItem;

Enable Autosize of columns and enable OwnerDraw for a List View. Then add a code below from HERE:

procedure TForm1.ListView1DrawItem(Sender: TCustomListView; Item: TListItem;
  Rect: TRect; State: TOwnerDrawState);
var
  i: Integer;
  x1, x2: integer;
  r: TRect;
  S: string;
const
  DT_ALIGN: array[TAlignment] of integer = (DT_LEFT, DT_RIGHT, DT_CENTER);
begin
  if SameText(Item.SubItems[1], 'done') then
  begin
      Sender.Canvas.Font.Color := clWhite;
      Sender.Canvas.Brush.Color := clGreen;
  end
  else
    if Odd(Item.Index) then
    begin
      Sender.Canvas.Font.Color := clBlack;
      Sender.Canvas.Brush.Color := $F6F6F6;
    end
    else
    begin
      Sender.Canvas.Font.Color := clBlack;
      Sender.Canvas.Brush.Color := clWhite;
    end;
  if odSelected in State then                                                    // NEW!
  begin                                                                          // NEW!
    Sender.Canvas.Font.Color := clWhite;                                         // NEW!
    Sender.Canvas.Brush.Color := clNavy;                                         // NEW!
  end;                                                                           // NEW!
  Sender.Canvas.Brush.Style := bsSolid;
  Sender.Canvas.FillRect(Rect);
  x1 := 0;
  x2 := 0;
  r := Rect;
  Sender.Canvas.Brush.Style := bsClear;
  Sender.Canvas.Draw(3, r.Top + (r.Bottom - r.Top - bm.Height) div 2, bm);
  for i := 0 to ListView1.Columns.Count - 1 do
  begin
    inc(x2, ListView1.Columns[i].Width);
    r.Left := x1;
    r.Right := x2;
    if i = 0 then
    begin
      S := Item.Caption;
      r.Left := bm.Width + 6;
    end
    else
      S := Item.SubItems[i - 1];
    DrawText(Sender.Canvas.Handle,
      S,
      length(S),
      r,
      DT_SINGLELINE or DT_ALIGN[ListView1.Columns[i].Alignment] or
        DT_VCENTER开发者_C百科 or DT_END_ELLIPSIS);
    x1 := x2;
  end;
  if odFocused in State then                                                     // NEW!
    DrawFocusRect(Sender.Canvas.Handle, Rect);                                   // NEW!
end;

Actively resize the penultimate column if it has autosize. It bill be bugs:

Delphi: bug when resizing columns of List View (on DrawItem)

Delphi: bug when resizing columns of List View (on DrawItem)

Delphi: bug when resizing columns of List View (on DrawItem)

Delphi: bug when resizing columns of List View (on DrawItem)

How to prevent these bugs?­­­­­­­­

Thanks!


The bug is in the TListColumn.GetWidthin 'comctrls.pas'. The VCL is retrieving a wrong column width while resizing columns when 'AutoSize' on the columns is set, hence you're drawing item text all over the columns.

I looked at the VCL code for a few minutes and couldn't figure out what's wrong, but setting the value in a getter is suspicious enough.

Anyway, for a workaround, instead of

inc(x2, ListView1.Columns[i].Width);

use this:

inc(x2, ListView_GetColumnWidth(ListView1.Handle, ListView1.Columns[i].Index));
0

精彩评论

暂无评论...
验证码 换一张
取 消