标题
OnAdvancedCustomDrawSubItem 自绘事件的处理 (TCustomListView)
我是马甲
浏览(0) +
2007-05-18 13:12:55 发表
编辑
关键字:
OnAdvancedCustomDrawSubItem 自绘事件的处理 (TCustomListView) -------------------------------------------------- 先看一篇文章,比较复杂 :) -------------------------------------------------- TListView的ListItem完全自绘 因工作需要完全自绘ListItem,模仿成电驴的样式,查找了N久相关的资料,发现很少有这方面的,最后用ListView_GetSubItemRect关键词在一个小日本的网站上找到一点相关的代码,修改后解决该问题。 至于是否存在BUG,偶用了几天还木有发现,如果有什么问题,请大家回复一下,谢谢 注意:代码只支持ViewStyle=vsReport 效果图如下: uses CommCtrl; procedure LVDrawItem(Sender: TListView; Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean); var BoundRect, Rect: TRect; i: integer; TextFormat: Word; LV: TListView; procedure Draw_CheckBox_ImageList(r: TRect; aCanvas: TCanvas; Checked: Boolean); var R1: TRect; begin if Sender.Checkboxes then begin aCanvas.Pen.Color := clBlack; aCanvas.Pen.Width := 2; //画CheckBox外框,也可以修改成你想要的图标显示 aCanvas.Rectangle(r.Left + 2, r.Top + 2, r.Left + 14, r.Bottom - 2); if Checked then begin //画CheckBox的勾 aCanvas.MoveTo(r.Left + 4, r.Top + 6); aCanvas.LineTo(r.Left + 6, r.Top + 11); aCanvas.LineTo(r.Left + 11, r.Top + 5); end; aCanvas.Pen.Width := 1; end; //开始画图标 if (Item.ImageIndex > -1)and(LV.SmallImages <>nil) then begin //获取图标的RECT if Boolean(ListView_GetSubItemRect(sender.Handle, item.Index, 0, LVIR_ICON, @R1)) then begin LV.SmallImages.Draw(LV.Canvas, R1.Left, R1.Top, Item.ImageIndex); end; end; end; begin LV := Sender; BoundRect := Item.DisplayRect(drBounds); InflateRect(BoundRect, -1, 0); if Item.Selected then begin if cdsFocused in State then begin LV.Canvas.Brush.Color := $00ECCCB9; // //clHighlight; // LV.Canvas.Font.Color := clBtnText; //clHighlightText; end else begin LV.Canvas.Brush.Color := $00F8ECE5; //clSilver; // LV.Canvas.Font.Color := clBtnText; end; end else begin // LV.Canvas.Brush.Color := clWindow; // LV.Canvas.Font.Color := clWindowText; end; LV.Canvas.FillRect(BoundRect); //初始化背景 for i := 0 to LV.Columns.Count - 1 do begin //获取SubItem的Rect ListView_GetSubItemRect(LV.Handle, Item.Index, i, LVIR_LABEL, @Rect); case LV.Columns[i].Alignment of taLeftJustify: TextFormat := 0; taRightJustify: TextFormat := DT_RIGHT; taCenter: TextFormat := DT_CENTER; end; case i of 0: //画Caption begin Draw_CheckBox_ImageList(BoundRect, LV.Canvas, Item.Checked); InflateRect(Rect, -3, 0); //向后移3个像素,避免被后面画线框时覆盖 DrawText( LV.Canvas.Handle, PCHAR(Item.Caption), Length(Item.Caption), Rect, DT_VCENTER or DT_SINGLELINE or DT_END_ELLIPSIS or TextFormat); end; 1..MaxInt: //画Subitems[i] begin if i - 1 <= Item.SubItems.Count - 1 then DrawText( LV.Canvas.Handle, PCHAR(Item.SubItems[i - 1]), Length(Item.SubItems[i - 1]), Rect, DT_VCENTER or DT_SINGLELINE or DT_END_ELLIPSIS or TextFormat); end; end; end; LV.Canvas.Brush.Color := clWhite; if Item.Selected then //画选中条外框 begin if cdsFocused in State then LV.Canvas.Brush.Color := $00DAA07A // $00E2B598; //clHighlight; else LV.Canvas.Brush.Color := $00E2B598; //$00DAA07A // clHighlight; LV.Canvas.FrameRect(BoundRect); // DrawFocusRect(Item.DisplayRect(drBounds)); // end; DefaultDraw := False; //True;//cdsSelected in State; with Sender.Canvas do if Assigned(Font.OnChange) then Font.OnChange(Font); end; //使用技巧 procedure TFormDownLoad.LV_ResourceListCustomDrawItem( Sender: TCustomListView; Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean); begin if (Item.Index mod 2) = 0 then Sender.Canvas.Brush.Color := clWhite else Sender.Canvas.Brush.Color := $00EBEBEB; LVDrawItem(LV_ResourceList, Item, State, DefaultDraw); end; -------------------------------------------------- 我的简单一点 procedure TForm1.ListView1AdvancedCustomDrawSubItem( Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; Stage: TCustomDrawStage; var DefaultDraw: Boolean); var s1:string; s2:string; rect: TRect; begin if (SubItem = 4)or(SubItem = 5) then begin s1:=Item.SubItems[SubItem-1]; //s1:='sssssss'; if s1<>'' then s1:=datetostr(UnixToDateTime(strtoint64def(s1, 0))); if Boolean(ListView_GetSubItemRect(sender.Handle, Item.Index, SubItem, LVIR_LABEL, @Rect)) then begin DrawText( Sender.Canvas.Handle, PCHAR(s1), Length(s1), Rect, DT_VCENTER or DT_SINGLELINE or DT_END_ELLIPSIS); end; DefaultDraw := false; end else begin DefaultDraw := true; end; end; 关键是用 win32api 取得的rect也只能用 win32api 的 DrawText 来操作,除非你自己转换一下位置.
我是马甲
http://www.programbbs.com/doc/1345.htm 处也有一篇不错的文章.
NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.