//如何实现 ListView 的平铺视图,以下代码没有成功!procedure TForm1.Button1Click(Sender: TObject);
const
  LVM_SETVIEW = LVM_FIRST + 142;
  LVM_SETTILEINFO = LVM_FIRST + 164;
  g_Columns: array[0..0] of UINT = (1);
type
  tagLVTILEINFO = packed record
    cbSize: UINT;
    iItem: Integer;
    cColumns: UINT;
    puColumns: PUINT;
    piColFmt: PInteger;
  end;
  LVTILEINFO = tagLVTILEINFO;
var
  tileInfo: LVTILEINFO;
begin
  SendMessage(ListView1.Handle, LVM_SETVIEW, 4, 0); 
  { 可以使 ListView 平铺显示,但只有一行名称 }
  
  tileInfo.cbSize := SizeOf(LVTILEINFO);
  tileInfo.iItem := 0;
  tileInfo.cColumns := 1;
  tileInfo.puColumns := @g_Columns[0];
  SendMessage(ListView1.Handle, LVM_SETTILEINFO, 0, lparam(@tileInfo));
  { 以上代码毫无反应 }
  { 我是想实现 Windows 那种平铺视图后,图标右侧的名称下面还可以灰色显示文件类型、文件大小这样的功能 }
end;

解决方案 »

  1.   

    {   我是想实现   Windows   那种平铺视图后,图标右侧的名称下面还可以灰色显示文件类型、文件大小这样的功能   } 
    你实际需要listview的自定义绘图。
    单纯使用api,需要截获WM_MEASUREITEM消息处理绘图区尺寸,然后截获WM_DRAWITEM消息处理绘图。
    当然,VCL已经为你做好了一切,使用TlistView控件,实现OnMeareItem事件和ONDrawItem事件。可参阅help和Win32 SDK.有不明白的还可以直接问我。
      

  2.   

    我想一定可以单纯使用 API 或者 MSDN 上那些提供的 ListView 的消息实现,
    我不太想使用重绘实现。楼上的,怎么跟你联系?
      

  3.   

    重绘实现比你想象的简单,你只需要关注单个item就可以,它不是针对整个listview控件的。我读过很多win32开发方面的书,listview的控制没有相关实现api,它的好多函数也只是对于message的封装而已。你可以简单改变item的caption,但要实现你想要的显示效果,强烈建议使用重绘,很简单。以你的要求看,50行代码都用不了。由问题,给我留言!
      

  4.   

    以下是我在很早以前编写的一个自定义listview类,你参考以下,使用的是消息截获,如果使用消息比较困难,可以直接使用Tlistview的事件。由于比较忙,可能说得不是很透彻,需要你自己多看帮助文件。
    //------------------------------------------------------------
    procedure Tlgdrawlist.Createparams(var params : TcreateParams);
    begin inherited;
     with params do
       style := style or lvs_OWNERDRAWFIXED;// or LVS_REPORT or LVS_ICON or LVS_SMALLICON;
    end;
    //--------------------------------------------------------------------
    procedure Tlgdrawlist.cnDrawItem(var msg : Twmdrawitem) ;
    begin
    if Assigned(FONDrawitem) then FOnDrawitem(self,msg.drawitemstruct^)
    else begin
     with msg.drawitemstruct^ do begin
      if ctlType <> ODT_LISTVIEW then exit;
         if (itemstate AND ODS_SELECTED) = ODS_SELECTED then begin
            setTextColor(hdc,FselTextcolor);
            setBkcolor(hdc,fselbkcolor);
          end else begin
            if itemId mod 2 = 0 then begin
              setTextcolor(hdc,Ftextcolor1);
              setBkColor(hdc,fbkColor1);
            end else begin
              setTextcolor(hdc,Ftextcolor2);
              setBkcolor(hdc,Fbkcolor2);
            end;
          end;//if
       drawsubitems(hdc,rcitem,itemId,itemstate); //virtual  end;//with
     end;//if
    end;
    //-------------------------------------------------------------------
    procedure TlgdrawList.drawsubitems(dc : hdc;r : Trect;id : uint;state : uint);
    var
     tmpr,tr : Trect;
     i : integer;
     str : pchar;
     iCl : integer;
     //oldPen,newpen : Hpen;
    begin
     tmpr := r;
     tmpr.right := tmpr.left;
     str := allocmem(255);
     for i := 0 to Columns.count - 1 do begin
       iCl := ListView_GetColumnWidth(handle,i);
       tmpr.right := tmpr.right + iCl;
       tr := tmpr;
       Strcopy(str,'');
       LIstview_GetitemText(handle,Id,i,str,255);   if Fisdrawhline then begin
         //newpen := createPen(PS_SOLID,1,clBlack);
         //oldPen := selectObject(
         moveToEx(dc,tmpr.left,tmpr.bottom-1,nil);
         lineTo(dc,tmpr.right,Tmpr.bottom-1);
         dec(tr.bottom);
       end;
       if FisDrawvline then begin
         moveToex(dc,tmpr.right-1,tmpr.top,nil);
         lineto(dc,tmpr.right-1,tmpr.bottom);
         dec(tr.right);
       end;   extTextout(dc,Tmpr.left + 2,tmpr.top + 2,ETO_CLIPPED OR ETO_OPAQUE,
                  @tr,str,strlen(str),nil);   tmpr.left := tmpr.right;
     end;
     freemem(str,255);
      if (State and ODS_FOCUS) = ODS_FOCUS then begin
        tmpr.left := r.left;
        DrawFocusRect(dc,tmpr);
      end;
    end;
    //-------------------------------------------------------------------
    procedure Tlgdrawlist.cnMeasureitem(var msg : TWmmeasureitem);
    begin
     if assigned(FOnMeasureItem) then
        FOnMeasureItem(self,msg.MeasureItemstruct^)
     else begin
      with msg.measureitemStruct^ do
          itemheight := DL_ITEMHEIGHT;
     END;
    end;
      

  5.   

    我查遍了互联网,大部分是 C++ 或 VB 代码,这是我整理并翻译成 Delphi 的代码,还是不成功!procedure TForm1.Button1Click(Sender: TObject);
    const
      LVM_SETVIEW = LVM_FIRST + 142;
      LVTVIF_AUTOSIZE = 0;
      LVTVIF_EXTENDED = 4;
      LVTVIF_FIXEDSIZE = 3;
      LVTVIM_COLUMNS = 2;
      LVTVIM_TILESIZE = 1;
      LVM_SETTILEVIEWINFO = LVM_FIRST + 162;
      LVM_SETTILEINFO = LVM_FIRST + 164;  g_Columns: array[0..1] of UINT = (2, 1);
      
    type
      tagLVTILEVIEWINFO = packed record
        cbSize: UINT;
        dwMask: DWORD;
        dwFlags: DWORD;
        sizeTile: SIZE;
        cLines: Integer;
        rcLabelMargin: TRect;
      end;
      LVTILEVIEWINFO = tagLVTILEVIEWINFO;
      
      tagLVTILEINFO = packed record
        cbSize: UINT;
        iItem: Integer;
        cColumns: UINT;
        puColumns: PUINT;
        piColFmt: PInteger;
      end;
      LVTILEINFO = tagLVTILEINFO;
    var
      i: Integer;
      tileInfo: LVTILEINFO;
      tileviewInfo: LVTILEVIEWINFO;
    begin
      SendMessage(ListView1.Handle, LVM_SETVIEW, 4, 0);  tileviewInfo.cbSize := SizeOf(tileviewInfo);
    //  tileviewInfo.dwFlags := LVTVIF_AUTOSIZE;
      tileviewInfo.dwMask := LVTVIM_COLUMNS;
      tileviewInfo.cLines := 3;
      tileviewInfo.sizeTile.cx := 200;
      tileviewInfo.sizeTile.cy := 150;
      SendMessage(ListView1.Handle, LVM_SETTILEVIEWINFO, 0, LPARAM(@tileviewInfo));  tileInfo.cbSize := SizeOf(tileInfo);
      tileInfo.cColumns := 2;
      tileInfo.puColumns := @g_Columns;
      for i := 0 to ListView1.Items.Count - 1 do
      begin
        tileInfo.iItem := ListView1.Items.Item[i].Index;
        SendMessage(ListView1.Handle, LVM_SETTILEINFO, 0, LPARAM(@tileInfo));
      end;
    end;
      

  6.   

    哈哈!非常喜欢你的钻研精神!^.^
    microsoft留给你的就是wm_drawitem和wm_Measureitem,不要再走弯路了。
    另外,再次层面的编程,c++和delphi没有太大区别。如果c++实现了你说的功能,delphi照搬就可以。
    另外,你说的分组功能是什么?在详细列表视图下吗?