TreeView自定义绘图项

时间:2017-01-20 12:06:05

标签: delphi winapi treeview

我想使用带有该功能的Win32 TreeView控件来获取项目,就像在Windows资源管理器的收藏夹/快速访问中一样:

image

我没有找到在两个节点之间启用分隔符的选项,所以我想我必须自己绘制它。

为此,我认为我必须使用CDIS_DROPHILITED项状态的unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Unit2, Vcl.ComCtrls; type TForm1 = class(TForm) TreeView1: TTreeView; procedure TreeView1AdvancedCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage; var PaintImages, DefaultDraw: Boolean); procedure TreeView1Changing(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean); procedure TreeView1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); private procedure WMNotify(var Msg: TMessage); message WM_NOTIFY; end; var Form1: TForm1; implementation uses CommCtrl; {$R *.dfm} procedure TForm1.TreeView1AdvancedCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage; var PaintImages, DefaultDraw: Boolean); begin if (cdsDropHilited in State) then Write; end; procedure TForm1.TreeView1Changing(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean); begin AllowChange := Node <> TreeView1.Items[1]; end; procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); begin Accept := True; GetComCtlVersion(); end; procedure TForm1.WMNotify(var Msg: TMessage); begin case (PNMHdr(Msg.LParam)^.code) of NM_CUSTOMDRAW: if (PNMTVCustomDraw(Msg.LParam)^.nmcd.uItemState and CDIS_NEARHOT <> 0) then Write; end; inherited; end; end. 通知。但我无法理解这一点。为什么呢?

TreeView1AdvancedCustomDrawItem()

WMNotify()Write都未到达{{1}}声明。

有什么建议吗?如何在实现拖拽时绘制节点分隔线?下降功能?

我使用的是Windows 7。

2 个答案:

答案 0 :(得分:3)

如果仔细观察Windows资源管理器如何绘制树节点,您将看到只有当鼠标位于被拖动的节点的顶部或下边缘时才会绘制您感兴趣的分隔符。当鼠标不在其上/下边缘上时,查看分割器相对于目标节点突出显示选择的位置。它们重叠。

您可以在TTreeView.OnAdvancedCustomDraw(Item)事件中完成同样的事情。检查TreeView的DropTarget节点(当用户释放鼠标时将被丢弃的节点)是否是当前正在绘制的节点,如果是,则:

  • 使用TreeView.ScreenToClient(Mouse.CursorPos)检索客户端坐标中的当前鼠标位置。

  • 检索DisplayRect节点的DropTarget

  • 检查鼠标坐标当前是否位于该矩形的顶部或底部几个像素内。

  • 如果是这样,请根据需要在这些坐标处绘制分隔符。

答案 1 :(得分:1)

TreeView_SetInsertMark绘制了问题所示的分隔符。