TreeView的列表是怎么绘制的?

yao518 2008-05-13 12:08:38
delphi里面Treeview这个控件里面的TreeNode列表是怎么在VCL里面绘制的?

我想重新写一个这样的控件,把后面的文字变成二行,然后进行一些别的操作。

这个问题我在网上找了他妈的N久都没有找到?
...全文
209 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
飞天揽月 2008-05-17
  • 打赏
  • 举报
回复
OnCustomDrawItem
yao518 2008-05-17
  • 打赏
  • 举报
回复
我把你的代码放在delphi里面运行了试一下看~!
yao518 2008-05-17
  • 打赏
  • 举报
回复
我最近在研究TreeView里面的东西,看了很久都没有发现他在那里绘制的,呵。

你写的Listbox绘制代码对我的帮助不是很大。不过我也看了,非常不错

你的QQ是。。。?
blazingfire 2008-05-16
  • 打赏
  • 举报
回复
为了赚点粉,这里再粘一次,写这些代码不容易呀?!用TListBox呀
procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
//ListBox.OnDrawItem事件
var
ImgRect, MemoRect: TRect;
Cnvs: TCanvas;
B: TBitmap;
S, Memo: string;
iPos: Integer;
begin
Cnvs := ListBox1.Canvas;
ImgRect := Rect;
ImgRect.Right := ImgRect.Left + (ImgRect.Bottom - ImgRect.Top); //画图区域

if odSelected in State then
begin
Cnvs.Brush.Color := clSkyBlue;
Cnvs.Pen.Color := clNavy;
end
else
begin
Cnvs.Brush.Color := ListBox1.Color;
Cnvs.Pen.Color := ListBox1.Color;
end;
Cnvs.Brush.Style := bsSolid;
Cnvs.Rectangle(Rect);

Cnvs.Brush.Style := bsClear;
if ImageList.Count > 0 then
begin
B := TBitmap.Create;
try
ImageList.GetBitmap(0, B);
B.PixelFormat := pf24bit;
B.Transparent := True;
InflateRect(ImgRect, -2, -2);
Cnvs.StretchDraw(ImgRect, B);
finally
B.Free;
end;
end;

Rect.Left := ImgRect.Right;
MemoRect := Rect;
MemoRect.Top := (Rect.Top + Rect.Bottom) div 2;
Rect.Bottom := MemoRect.Top;
S := ListBox1.Items[Index];

iPos := Pos(#9, S);
Memo := Copy(S, iPos + 1, Length(S)); //提取备注
S := Copy(S, 1, iPos - 1); //提取名称
Cnvs.Font.Assign(ListBox1.Font);


DrawText(Cnvs.Handle, PChar(S), -1,
Rect, DT_SingleLine or DT_VCENTER); //垂直、水平居中 画名字

Cnvs.Font.Color := clGrayText;
DrawText(Cnvs.Handle, PChar(Memo), -1,
MemoRect, DT_SingleLine or DT_VCENTER); //垂直、水平居中 画名字
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
ListBox1.Style := lbOwnerDrawVariable; //自己画每一项,项高度可调
ListBox1.ItemHeight := 30;
ListBox1.Clear;
//名称+#9+备注
ListBox1.Items.Add('yao518'#9 + '一剑飘雪');
ListBox1.Items.Add('blazingfire'#9 + '...该充电了...');
ListBox1.Items.Add('yao518'#9 + '一剑飘雪');
ListBox1.Items.Add('blazingfire'#9 + '...该充电了...');
end;

blazingfire 2008-05-16
  • 打赏
  • 举报
回复
多看Delphi代码,很长劲的。
yao518 2008-05-16
  • 打赏
  • 举报
回复
blazingfire 兄弟,你的回答对我很有用,虽然资料太少,但最起码知道该控件不是Delphi自己绘制。呵。
blazingfire 2008-05-14
  • 打赏
  • 举报
回复
如果要改变绘制的样子要拦截WM_PAINT, WM_NCPAINT....消息去处理
blazingfire 2008-05-14
  • 打赏
  • 举报
回复
其实也没有什么指点的,我在VCL里也没有找到代码,呵呵!
看看TCustomTreeView的CreateParam方法如何作的就知道了
VCL代码
procedure TCustomTreeView.CreateParams(var Params: TCreateParams);
const
BorderStyles: array[TBorderStyle] of DWORD = (0, WS_BORDER);
LineStyles: array[Boolean] of DWORD = (0, TVS_HASLINES);
RootStyles: array[Boolean] of DWORD = (0, TVS_LINESATROOT);
ButtonStyles: array[Boolean] of DWORD = (0, TVS_HASBUTTONS);
EditStyles: array[Boolean] of DWORD = (TVS_EDITLABELS, 0);
HideSelections: array[Boolean] of DWORD = (TVS_SHOWSELALWAYS, 0);
DragStyles: array[TDragMode] of DWORD = (TVS_DISABLEDRAGDROP, 0);
RTLStyles: array[Boolean] of DWORD = (0, TVS_RTLREADING);
ToolTipStyles: array[Boolean] of DWORD = (TVS_NOTOOLTIPS, 0);
AutoExpandStyles: array[Boolean] of DWORD = (0, TVS_SINGLEEXPAND);
HotTrackStyles: array[Boolean] of DWORD = (0, TVS_TRACKSELECT);
RowSelectStyles: array[Boolean] of DWORD = (0, TVS_FULLROWSELECT);
begin
//调用Windows方法来创建一个TreeView组件,其它的绘制动作其实也是Windows实现的
InitCommonControl(ICC_TREEVIEW_CLASSES);
inherited CreateParams(Params);
CreateSubClass(Params, WC_TREEVIEW);
with Params do
begin
Style := Style or LineStyles[FShowLines] or BorderStyles[FBorderStyle] or
RootStyles[FShowRoot] or ButtonStyles[FShowButtons] or
EditStyles[FReadOnly] or HideSelections[FHideSelection] or
DragStyles[DragMode] or RTLStyles[UseRightToLeftReading] or
ToolTipStyles[FToolTips] or AutoExpandStyles[FAutoExpand] or
HotTrackStyles[FHotTrack] or RowSelectStyles[FRowSelect];
if Ctl3D and NewStyleControls and (FBorderStyle = bsSingle) then
begin
Style := Style and not WS_BORDER;
ExStyle := Params.ExStyle or WS_EX_CLIENTEDGE;
end;
WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
end;
end;


其实TButton,TEdit也是这样实现的,Delphi没有绘制过程
yao518 2008-05-14
  • 打赏
  • 举报
回复
shiyj兄:如果用OnCustomDrawItem能绘制出一些特殊的效果,那我就不用看VCL了。你呀……

blazingfire兄:你说的也有道理,我看了VCL源码,那如果我要绘制一个跟QQ好友列表一样的控件出来,不得自己绘制呀。这方面我不懂的,愿听指点。

谢谢
blazingfire 2008-05-13
  • 打赏
  • 举报
回复
其实这个过程是Windows作的和Delphi没有太大关系,可以看一下VCL代码
喝口水 2008-05-13
  • 打赏
  • 举报
回复
帮顶
他山玉 2008-05-13
  • 打赏
  • 举报
回复
楼主讲话不文明啊。
你可以定义节点的 OnCustomDrawItem 事件,实现节点绘制方面的特殊要求。

5,392

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧