unit Unit1;interfaceuses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, ComCtrls, ExtCtrls, ImgList, CommCtrl, StdCtrls, shellapi;//定义一个记录用来存放listview的内容
type
   Plistdata = ^Tlistdata;
   Tlistdata = record
      Caption: string;                  //caption内容
      second: string;                   //第二列内容
      three: string;                    //第三列内容
      picon: TIcon;                     //图标
      picon1: TIcon;   end;
type
   TForm1 = class(TForm)
      ListView1: TListView;
      ImageList1: TImageList;
      Panel1: TPanel;
      procedure FormCreate(Sender: TObject);
      procedure ListView1AdvancedCustomDrawItem(Sender: TCustomListView;
         Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
         var DefaultDraw: Boolean);
   private      { Private declarations }
   public
      { Public declarations }
   end;var
   Form1            : TForm1;
   rect             : TRect;
   BoundRect        : TRect;
   ListViewData     : TList;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
const
   n                = 50;
var
   x1, y1, x2, y2   : Integer;
   imglist          : TImageList;
   i                : integer;
   listdata         : Plistdata;
begin
   //设定一个imagelist,来扩充listview的item的高度
   imgList := timagelist.Create(nil);
   imgList.Width := 1;
   imglist.Height := 30;                //listview的item的设度设置
   listview1.SmallImages := imgList; //这里设置listView的SmallImageList ,用imgList将其撑大   //初使化listview的数据到tlist中
   ListViewData := tlist.Create;
   for i := 0 to 5 do
   begin
      New(listdata);
      listdata^.Caption := '第' + inttostr(i) + '行第一列数据';
      listdata^.second := '第' + inttostr(i) + '行第二列数据';
      listdata^.three := '第' + inttostr(i) + '行第三列数据';
      listdata^.picon := TIcon.Create;
      listdata^.picon1 := TIcon.Create;      ImageList1.GetIcon(0, listdata^.picon);
      ImageList1.GetIcon(1, listdata^.picon1);
      ListViewData.Add(listdata);
   end;   //插入空内容到listview
   for i := 0 to 5 do
      ListView1.Items.Add;
end;procedure TForm1.ListView1AdvancedCustomDrawItem(Sender: TCustomListView;
   Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
   var DefaultDraw: Boolean);
var
   listdata         : Plistdata;
   i                : integer;
begin
   //取每行的数据
   listdata := ListViewData.Items[Item.index];
   //得到每行的rect
   BoundRect := Item.DisplayRect(drBounds);
   // 设定背景色
   if cdsFocused in State then
   begin
      Sender.Canvas.Brush.Color := $00C5F1FF;
   end
   else
   begin
      Sender.Canvas.Brush.Color := clWhite;
   end;
   ListView1.Canvas.FillRect(BoundRect); //填充颜色
   for i := 0 to ListView1.Columns.Count - 1 do
   begin
      //获取每一列item的Rect
      ListView_GetSubItemRect(Sender.Handle, Item.Index, i, LVIR_LABEL, @Rect);
      case i of
         0:
            begin
                       DrawText(
                  ListView1.Canvas.Handle,
                  PCHAR(Trim(listdata.three)),
                  -1,
                  rect,
                  DT_VCENTER or DT_SINGLELINE or DT_END_ELLIPSIS or 0);
            end;
         1:
            begin               //画第二列内容
               DrawText(
                  ListView1.Canvas.Handle,
                  PCHAR(Trim(listdata.second)),
                  -1,
                  rect,
                  DT_VCENTER or DT_SINGLELINE or DT_END_ELLIPSIS or 0);
            end;
         2:
            begin
               //画图标
               ListView1.Canvas.Draw(Rect.Left, Rect.top + (Rect.Bottom - rect.Top -
                  ImageList1.Height) div 2, listdata.Picon);
               InflateRect(rect, -45, 0); //向后移45个像素,避免被后面画字时覆盖
               ListView1.Canvas.Draw(Rect.Left + 17, Rect.top + (Rect.Bottom - rect.Top -
                  ImageList1.Height) div 2, listdata.Picon1);
               // Sender.Canvas.Font.Color := clBlue;
                { DrawText(
                  ListView1.Canvas.Handle,
                  PCHAR(Trim(listdata.Caption)),
                  -1,
                  rect,
                  DT_VCENTER or DT_SINGLELINE or DT_END_ELLIPSIS or 0);}
            end;
      end;
      //画个线分开
      ListView1.Canvas.Pen.Color := clblue;
      ListView1.Canvas.MoveTo(BoundRect.Left, BoundRect.Bottom - 1);
      ListView1.Canvas.LineTo(BoundRect.right, BoundRect.Bottom - 1);
   end;
   //防止闪屏
   Sender.DoubleBuffered := true;end;

解决方案 »

  1.   

    你只能判断鼠标位置了,你可以绑定按钮啊(listview上添加按钮),这样不是好控制事件吗
      

  2.   

    listview上添加按钮上面动态添加按钮(button)我也加过了,但是只要鼠标拖到滚动条或调整列宽就会出现残影,刷新貌似都没有效,只有这种方式才没有那种现象
      

  3.   

    另外如果没有别的办法的话,求判断鼠标是否在那个SubItems[i]的计算方法,谢谢
      

  4.   


    var
      Item: TListItem;
      Rect: TRect;
    begin
      Item := lv1.GetItemAt(X, Y);
      if Item <> nil then
        ListView_GetItemRect(lv1.Handle, Item.Index, Rect, LVIR_BOUNDS);
    end;
      

  5.   


    delphi 我基本上都是自学的,刚才我看到一段代码,可以知道当前鼠标的行,列,但是不知道该如何转换,忧闷啊,网上的代码listview 自绘都没有讲消息处理,如果是动态创建的倒是可以处理,可惜的是不能拖到滚动条或调整列宽.procedure TForm1.ListView1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    var
      iRow, iCol, it : Integer;
      li  : TListItem;
      sText : string;
      ttt:Integer;
    begin
      if(not(Sender is TListView))then Exit;
      sText := '(Empty)';
      with TListView(Sender)do
      try
        if(ViewStyle <> vsReport)then
        begin
          sText := 'ViewStyle is not vsReport';
          Exit;
        end;    li  := GetItemAt(5, Y);
        if(not Assigned(li))then Exit;
        iRow  := Items.IndexOf(li);
        for iCol:=0 to Columns.Count-1 do
        begin
          it  := Columns[iCol].Width;      if(X<it)then Break;
          Dec(X, it);
        end;
        if(iCol<Columns.Count)then
          sText := Format('[%d, %d] %s', [iRow, iCol, li.Caption]));  finally
        Caption := sText;
      end;
      end;