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;