2011. február 16., szerda

Draw checkboxes in a virtual mode TListView


Problem/Question/Abstract:

How do I get CheckBoxes when using a TListView with OwnerData set to true and using an OnData event method?

Answer:

{ ... }
const
  W_64: Word = 64; {Width of thumbnail in ICON view mode}
  H_64: Word = 64; {Height of thumbnail size}
  CheckWidth: Word = 14; {Width of check mark box}
  CheckHeight: Word = 14; {Height of checkmark}
  CheckBiasTop: Word = 2; {This aligns the checkbox to be in centered}
  CheckBiasLeft: Word = 3; {In the row of the list item display}

procedure DrawCheckMark(const ListViewX: TListView; Item: TListItem; Checked:
  Boolean);
var
  TP1, TP2: TPoint;
  XBias, YBias: Integer;
  OldColor: TColor;
  BiasTop, BiasLeft: Integer;
  Rect1: TRect;
begin
  GetCheckBias(XBias, YBias, BiasTop, BiasLeft, ListViewX);
  OldColor := ListViewX.Canvas.Pen.Color;
  TP1 := Item.GetPosition;
  if Checked then
    ListViewX.Canvas.Brush.Color := clBlack;
  Rect1.Left := Item.Left - CheckWidth - BiasLeft + 1 + XBias;
  Rect1.Top := Tp1.Y + BiasTop + 1 + YBias;
  Rect1.Right := Item.Left - BiasLeft - 1 + XBias;
  Rect1.Bottom := Tp1.Y + BiasTop + CheckHeight - 1 + YBias;
  ListViewX.Canvas.FillRect(Rect1);
  if Checked then
    ListViewX.Canvas.Brush.Color := clBlue
  else
    ListViewX.Canvas.Brush.Color := clBlack;
  ListViewX.Canvas.FrameRect(Rect1);
  ListViewX.Canvas.FrameRect(Rect(Rect1.Left - 1, Rect1.Top - 1,
    Rect1.Right + 1, Rect1.Bottom + 1));
  if Checked then
  begin
    ListViewX.Canvas.Pen.Color := clLime;
    TP2.X := Item.Left - BiasLeft - 2 + XBias;
    TP2.Y := Tp1.Y + BiasTop + 2 + YBias;
    ListViewX.Canvas.PenPos := TP2;
    ListViewX.Canvas.LineTo(Item.Left - BiasLeft - (CheckWidth div 2) +
      XBias, Tp1.Y + BiasTop + (CheckHeight - 2) + YBias);
    ListViewX.Canvas.LineTo(Item.Left - BiasLeft - (CheckWidth - 2) + XBias,
      Tp1.Y + BiasTop + (CheckHeight div 2) + YBias);
    TP2.X := Item.Left - BiasLeft - 2 - 1 + XBias;
    TP2.Y := Tp1.Y + BiasTop + 2 + YBias;
    ListViewX.Canvas.PenPos := TP2;
    ListViewX.Canvas.LineTo(Item.Left - BiasLeft - (CheckWidth div 2) - 1 + XBias,
      Tp1.Y + BiasTop + (CheckHeight - 2) + YBias);
    ListViewX.Canvas.LineTo(Item.Left - BiasLeft - (CheckWidth - 2) - 1 + XBias,
      Tp1.Y + BiasTop + (CheckHeight div 2) + YBias);
  end;
  ListViewX.Canvas.Brush.Color := ListViewX.Color;
  ListViewX.Canvas.Pen.Color := OldColor;
end;

procedure GetCheckBias(var XBias, YBias, BiasTop, BiasLeft: Integer;
  const ListView: TListView);
begin
  XBias := 0;
  YBias := 0;
  if ListView.ViewStyle = vsICON then
  begin
    YBias := H_64 - CheckHeight;
    XBias := 0;
  end;
  BiasTop := CheckBiasTop;
  BiasLeft := CheckBiasLeft;
  if ListView.ViewStyle <> vsReport then
  begin
    BiasTop := 0;
    BiasLeft := 0;
  end;
end;

In the OnCustomDrawItem event you would do something like this:

DrawCheckMark(FileListMenu.ListView1, Item, Item.Checked);

Nincsenek megjegyzések:

Megjegyzés küldése