登录 用户中心() [退出] 后台管理 注册
   
您的位置: 首页 >> 程序员学前班[不再更新,只读] >> 主题: OnAdvancedCustomDrawSubItem 自绘事件的处理 (TCustomListView)     [回主站]     [分站链接]
标题
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 来操作,除非你自己转换一下位置.

我是马甲
2007-5-18 13:16:39 发表 编辑

http://www.programbbs.com/doc/1345.htm
处也有一篇不错的文章.


总数:1 页次:1/1 首页 尾页  
总数:1 页次:1/1 首页 尾页  


所在合集/目录



发表评论:
文本/html模式切换 插入图片 文本/html模式切换


附件:



NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.

Copyright © 2005-2020 clq, All Rights Reserved
版权所有
桂ICP备15002303号-1