//如何实现 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;
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;
你实际需要listview的自定义绘图。
单纯使用api,需要截获WM_MEASUREITEM消息处理绘图区尺寸,然后截获WM_DRAWITEM消息处理绘图。
当然,VCL已经为你做好了一切,使用TlistView控件,实现OnMeareItem事件和ONDrawItem事件。可参阅help和Win32 SDK.有不明白的还可以直接问我。
我不太想使用重绘实现。楼上的,怎么跟你联系?
//------------------------------------------------------------
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;
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;
microsoft留给你的就是wm_drawitem和wm_Measureitem,不要再走弯路了。
另外,再次层面的编程,c++和delphi没有太大区别。如果c++实现了你说的功能,delphi照搬就可以。
另外,你说的分组功能是什么?在详细列表视图下吗?