https://www.cnblogs.com/FKdelphi/p/5843135.html
也可参考 ExpressDBTreeView学习(06) uniGUI前添加checkBox
在Delphi10.3运行成功Win7-32位,示例代码下载。只适合Windows平台
//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;
//7.取消所有选中、全选 procedure TForm1.Button2Click(Sender: TObject); var Node: TTreeNode; TVI: TTVItem; begin for Node in TreeView1.Items do begin TVI.mask := TVIF_STATE; TVI.hItem := Node.ItemId; TVI.stateMask := TVIS_STATEIMAGEMASK; TVI.state := $2000 shr 1;// TVI.state := $2000 ;//为全选 TreeView_SetItem(TreeView1.Handle, TVI); end; end;
procedure TForm9.Button1Click(Sender: TObject); var //8只选择叶结点 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) and (not Node.HasChildren) then LISTBOX1.Items.Add(Node.Text); end; end;
procedure TForm9.Button1Click(Sender: TObject); var Node: TTreeNode; TVI: TTVItem; aStr:string; tempNode: TTreeNode; 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 begin aStr:=node.Text; tempNode :=Node; while (tempNode.Parent<>nil ) do begin aStr:= tempNode.Parent.Text+' \ '+ aStr; tempNode:=tempNode.Parent; end; ShowMessage( aStr); end; end; end;
9把多层次的 XML 文档解析为 TreeView 显示
https://blog.csdn.net/pcplayer/article/details/129164849
procedure TForm1.Button1Click(Sender: TObject); var Rootnode,node : IXMLNode; nodelist:IXMLNodeList; b,c,str, S: string; i, j:Integer; StartItemNode: IXMLNode; ANode: IXMLNode; TotalAmount, StartDate, EndDate, DepositDate: string; DT: Cardinal; begin if OpenDialog1.Execute() then begin DT := GetTickCount; Screen.Cursor := crHourGlass; try XMLDocument1.LoadFromFile(OpenDialog1.FileName); XMLDocument1.Active := True; Rootnode := XMLDocument1.DocumentElement; TreeView1.Items.BeginUpdate; try CreateTreeView(RootNode, Treeview1.Items.GetFirstNode); finally TreeView1.Items.EndUpdate; end; finally Screen.Cursor := crDefault; end; DT := GetTickCount -DT; S := '执行时间 = ' + FloatToStr(DT/1000) + ' 秒'; ShowMessage(S); end; end; procedure TForm1.CreateTreeView(ANode: IXMLNode; TreeNode: TTreeNode); var ParentTreeNode, CurrentTreeNode: TTreeNode; i: Integer; begin //采用递归,把一个多层次的 XML 变成 TreeView 显示。测试通过。 if ANode.HasChildNodes then begin CurrentTreeNode := TreeView1.Items.AddChild(TreeNode, ANode.NodeName); ParentTreeNode := CurrentTreeNode; for i:=0 to ANode.ChildNodes.Count-1 do begin CreateTreeview(ANode.ChildNodes[i], ParentTreeNode); end; end else begin TreeView1.Items.AddChild(TreeNode, VarToStr(ANode.NodeValue)); end; end;