https://www.cnblogs.com/FKdelphi/p/5843135.html
在Delphi10.3运行成功
1.引用单元
2.定义私有过程
3.过程体代码
4.点击连选处理
5.生成节点
6.查看是否选中
//1.引用单元 uses Commctrl ;
//2.定义私有过程 procedure tvToggleCheckbox(TreeView: TTreeView;Node: TTreeNode;isclick:boolean =false); procedure SetChecked(Node: TTreeNode; Checked: Boolean); function IsChecked(Node: TTreeNode): Boolean;
//3.过程体代码 //检查某个节点是否被 选中 function TForm1.IsChecked(Node: TTreeNode): Boolean; var TvItem :TTVItem; begin TvItem.Mask := TVIF_STATE; TvItem.hItem := Node.ItemId; TreeView_GetItem(Node.TreeView.Handle, TvItem); Result := (TvItem.State and TVIS_CHECKED) = TVIS_CHECKED; end; //让 某个节点被 选中 procedure TForm1.SetChecked(Node: TTreeNode; Checked: Boolean); var TvItem :TTVItem; begin FillChar(TvItem, SizeOf(TvItem), 0); with TvItem do begin hItem := Node.ItemId; Mask := TVIF_STATE; StateMask := TVIS_STATEIMAGEMASK; if Checked then TvItem.State :=TVIS_CHECKED else TvItem.State :=TVIS_CHECKED shr 1; TreeView_SetItem(Node.TreeView.Handle, TvItem); end; end; // 对节点中所有 子节点 都 选中或 未选中 状态 procedure TForm1.tvToggleCheckbox(TreeView: TTreeView; Node: TTreeNode ;isclick :boolean=false); var CurNode, ParentNode, GrandSonNode,sonNode: TTreeNode; flg1: boolean; begin CurNode :=node; with TreeView do begin if IsChecked(CurNode) then // begin sonNode := CurNode.GetFirstChild; //遍历子树,选中 则子节点 全部 为选中; while sonNode<>nil do begin SetChecked(sonNode, true); tvToggleCheckbox(TreeView,sonNode,true); sonNode := sonNode.GetNextSibling; end; ParentNode:= CurNode.Parent; //父; if ParentNode<>nil then begin if not isChecked(parentNode) then begin GrandSonNode := ParentNode.GetFirstChild; //遍历子树; flg1 := false; while GrandSonNode<>nil do begin if (not IsChecked(GrandSonNode)) then //true,有未选中 flg1 := true; if flg1 then //已有、退出loop; GrandSonNode := nil else GrandSonNode := GrandSonNode.GetNextSibling; end; SetChecked(ParentNode, not flg1); tvToggleCheckbox(TreeView,ParentNode,false); end; end; // end parentNode 不等于空 end else if not IsChecked(CurNode) then begin ParentNode := CurNode.Parent; //父; if ParentNode<>nil then begin if isChecked(parentNode) then begin SetChecked(ParentNode, false); tvToggleCheckbox(TreeView,ParentNode); end; end; //end parentnode if (isclick) then begin sonNode := CurNode.GetFirstChild; //遍历子树,未选中 则子节点 全部 为未选中; while sonNode<>nil do begin SetChecked(sonNode, false); tvToggleCheckbox(TreeView,sonNode,true); sonNode := sonNode.GetNextSibling; end; end; end; end; end;
//4.点击连选处理 procedure TForm1.TreeView1Click(Sender: TObject); var P:TPoint; treenode :TTreeNode; begin GetCursorPos(P); P := TreeView1.ScreenToClient(P); if (htOnStateIcon in TreeView1.GetHitTestInfoAt(P.X,P.Y)) then begin treenode := TreeView1.GetNodeAt(P.X,P.Y); tvToggleCheckbox(TreeView1,treenode ,true); end; end;
//5.生成节点 procedure TForm1.FormCreate(Sender: TObject); begin //仅仅这一句话就能让treeview 显示复选框 SetWindowLong(TreeView1.Handle, GWL_STYLE, GetWindowLong(TreeView1.Handle, GWL_STYLE) or $00000100); // SetWindowLong(H, GWL_STYLE, GetWindowLong(H, GWL_STYLE) or TVS_CHECKBOXES); //这名同上一个意思 {下面的代码只是给 TreeView 添加内容} with TreeView1 do begin Align := alLeft; Items.Add(nil, 'AAA'); Items.Add(nil, 'BBB'); Items.Add(nil, 'CCC'); Items.AddChild(Items[2], '111'); Items.AddChild(Items[2], '222'); Items.AddChild(Items[2], '333'); end; end;
//6.查看是否选中 procedure TForm1.Button1Click(Sender: TObject); var Node: TTreeNode; TVI: TTVItem; begin for Node in TreeView1.Items do begin TVI.mask := TVIF_STATE; TVI.hItem := Node.ItemId; TreeView_GetItem(TreeView1.Handle, TVI); if TVI.state and $2000 = $2000 then ShowMessage(Node.Text); end; end;
在Delphi10.3运行成功
1.引用单元
2.定义私有过程
3.过程体代码
4.点击连选处理
5.生成节点
6.查看是否选中