
1 //1.引用单元
2 uses Commctrl ;
3
4 //2.定义私有过程
5 procedure tvToggleCheckbox(TreeView: TTreeView;Node: TTreeNode;isclick:boolean =false);
6 procedure SetChecked(Node: TTreeNode; Checked: Boolean);
7 function IsChecked(Node: TTreeNode): Boolean;
8
9 //3.过程体代码
10 //检查某个节点是否被 选中
11 function TForm1.IsChecked(Node: TTreeNode): Boolean;
12 var
13 TvItem :TTVItem;
14 begin
15 TvItem.Mask := TVIF_STATE;
16 TvItem.hItem := Node.ItemId;
17 TreeView_GetItem(Node.TreeView.Handle, TvItem);
18 Result := (TvItem.State and TVIS_CHECKED) = TVIS_CHECKED;
19 end;
20 //让 某个节点被 选中
21 procedure TForm1.SetChecked(Node: TTreeNode; Checked: Boolean);
22 var
23 TvItem :TTVItem;
24 begin
25 FillChar(TvItem, SizeOf(TvItem), 0);
26 with TvItem do
27 begin
28 hItem := Node.ItemId;
29 Mask := TVIF_STATE;
30 StateMask := TVIS_STATEIMAGEMASK;
31 if Checked then
32 TvItem.State :=TVIS_CHECKED
33 else
34 TvItem.State :=TVIS_CHECKED shr 1;
35 TreeView_SetItem(Node.TreeView.Handle, TvItem);
36 end;
37 end;
38 // 对节点中所有 子节点 都 选中或 未选中 状态
39 procedure TForm1.tvToggleCheckbox(TreeView: TTreeView;
40 Node: TTreeNode ;isclick :boolean=false);
41 var CurNode, ParentNode, GrandSonNode,sonNode: TTreeNode;
42 flg1: boolean;
43 begin
44 CurNode :=node;
45 with TreeView do
46 begin
47 if IsChecked(CurNode) then //
48 begin
49 sonNode := CurNode.GetFirstChild; //遍历子树,选中 则子节点 全部 为选中;
50 while sonNode<>nil do
51 begin
52 SetChecked(sonNode, true);
53 tvToggleCheckbox(TreeView,sonNode,true);
54 sonNode := sonNode.GetNextSibling;
55 end;
56 ParentNode:= CurNode.Parent; //父;
57 if ParentNode<>nil then
58 begin
59 if not isChecked(parentNode) then
60 begin
61 GrandSonNode := ParentNode.GetFirstChild; //遍历子树;
62 flg1 := false;
63 while GrandSonNode<>nil do
64 begin
65 if (not IsChecked(GrandSonNode)) then //true,有未选中
66 flg1 := true;
67 if flg1 then //已有、退出loop;
68 GrandSonNode := nil
69 else
70 GrandSonNode := GrandSonNode.GetNextSibling;
71 end;
72 SetChecked(ParentNode, not flg1);
73 tvToggleCheckbox(TreeView,ParentNode,false);
74 end;
75 end; // end parentNode 不等于空
76 end
77 else if not IsChecked(CurNode) then
78 begin
79 ParentNode := CurNode.Parent; //父;
80 if ParentNode<>nil then
81 begin
82 if isChecked(parentNode) then
83 begin
84 SetChecked(ParentNode, false);
85 tvToggleCheckbox(TreeView,ParentNode);
86 end;
87 end; //end parentnode
88 if (isclick) then
89 begin
90 sonNode := CurNode.GetFirstChild; //遍历子树,未选中 则子节点 全部 为未选中;
91 while sonNode<>nil do
92 begin
93 SetChecked(sonNode, false);
94 tvToggleCheckbox(TreeView,sonNode,true);
95 sonNode := sonNode.GetNextSibling;
96 end;
97 end;
98 end;
99 end;
100 end;
101
102 //4.点击连选处理
103 procedure TForm1.TreeView1Click(Sender: TObject);
104 var
105 P:TPoint;
106 treenode :TTreeNode;
107 begin
108 GetCursorPos(P);
109 P := TreeView1.ScreenToClient(P);
110 if (htOnStateIcon in TreeView1.GetHitTestInfoAt(P.X,P.Y)) then
111 begin
112 treenode := TreeView1.GetNodeAt(P.X,P.Y);
113 tvToggleCheckbox(TreeView1,treenode ,true);
114 end;
115 end;
116
117 //5.生成节点
118 procedure TForm1.FormCreate(Sender: TObject);
119 begin
120 //仅仅这一句话就能让treeview 显示复选框
121 SetWindowLong(TreeView1.Handle, GWL_STYLE, GetWindowLong(TreeView1.Handle, GWL_STYLE) or $00000100);
122 // SetWindowLong(H, GWL_STYLE, GetWindowLong(H, GWL_STYLE) or TVS_CHECKBOXES); //这名同上一个意思
123 {下面的代码只是给 TreeView 添加内容}
124 with TreeView1 do
125 begin
126 Align := alLeft;
127 Items.Add(nil, \'AAA\');
128 Items.Add(nil, \'BBB\');
129 Items.Add(nil, \'CCC\');
130 Items.AddChild(Items[2], \'111\');
131 Items.AddChild(Items[2], \'222\');
132 Items.AddChild(Items[2], \'333\');
133 end;
134 end;
135
136 //6.查看是否选中
137 procedure TForm1.Button1Click(Sender: TObject);
138 var
139 Node: TTreeNode;
140 TVI: TTVItem;
141 begin
142 for Node in TreeView1.Items do
143 begin
144 TVI.mask := TVIF_STATE;
145 TVI.hItem := Node.ItemId;
146 TreeView_GetItem(TreeView1.Handle, TVI);
147 if TVI.state and $2000 = $2000 then
148 ShowMessage(Node.Text);
149 end;
150 end;