给 TTreeView 添加复选框 - 疯狂delphi

时间:2024-03-10 09:19:32

给 TTreeView 添加复选框

 

  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;