unit UnitMain;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls, ComCtrls, CommCtrl;
type
  TFormMain = class(TForm)
    tvTree: TTreeView;
    spl1: TSplitter;
    btnGetSelected: TBitBtn;
    btnSetSelected: TBitBtn;
    edtName: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure tvTreeClick(Sender: TObject);
    procedure btnGetSelectedClick(Sender: TObject);
    procedure btnSetSelectedClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }    // 检查某个树节点是否被勾选
    function IsChecked(TreeNode : TTreeNode) : Boolean;    // 设置某个树节点的勾选状态
    procedure SetChecked(TreeNode : TTreeNode; Checked : Boolean);    // 对选中节点的子节点进行全选或反全选
    procedure ToggleCheckbox(TreeView : TTreeView; TreeNode : TTreeNode);
  end;var
  FormMain: TFormMain;implementation{$R *.dfm}const
  TVIS_CHECKED = $2000;
  TVS_CHECKBOXS = $00000100;// 检查某个树节点是否被勾选
function TFormMain.IsChecked(TreeNode : TTreeNode) : Boolean;
var
  TVItem : TTVItem;
begin
  TVItem.Mask := TVIF_STATE;
  TVItem.hItem := TreeNode.ItemId;
  TreeView_GetItem(TreeNode.TreeView.Handle, TVItem);
  Result := (TVItem.State and TVIS_CHECKED) = TVIS_CHECKED;
end;// 设置某个树节点的勾选状态
procedure TFormMain.SetChecked(TreeNode : TTreeNode; Checked : Boolean);
var
  TVItem : TTVItem;
begin
  FillChar(TVItem, SizeOf(TVItem), 0);  with TVItem do
  begin
    hItem := TreeNode.ItemId;
    Mask := TVIF_STATE;
    StateMask := TVIS_STATEIMAGEMASK;    if Checked then
      TVItem.State := TVIS_CHECKED
    else
      TVItem.State := TVIS_CHECKED shr 1;    TreeView_SetItem(TreeNode.TreeView.Handle, TVItem);
  end;
end;// 对选中节点的子节点进行全选或反全选
procedure TFormMain.ToggleCheckbox(TreeView : TTreeView; TreeNode : TTreeNode);
var
  CurNode, ParentNode, GrandSonNode, SonNode : TTreeNode;
  Flag : boolean;
begin
  CurNode := TreeNode;  with TreeView do
  begin
    if IsChecked(CurNode) then
    begin
      //递归遍历处理其子节点
      SonNode := CurNode.GetFirstChild;
      while SonNode <> nil do
      begin
        SetChecked(SonNode, True);
        ToggleCheckbox(TreeView, SonNode);
        SonNode := SonNode.GetNextSibling;
      end;      ParentNode := CurNode.Parent;
      if ParentNode <> nil then
      begin
        SetChecked(ParentNode, True);
      end;
    end
    else if not IsChecked(CurNode) then
    begin
      SonNode := CurNode.GetFirstChild;
      while SonNode <> nil do
      begin
        SetChecked(SonNode, False);
        ToggleCheckbox(TreeView, SonNode);
        SonNode := SonNode.GetNextSibling;
      end;
    end;
  end;
end;
procedure TFormMain.FormCreate(Sender: TObject);
begin
  //仅仅这一句话就能让treeview 显示复选框
SetWindowLong(tvTree.Handle, GWL_STYLE,
  GetWindowLong(tvTree.Handle, GWL_STYLE) or TVS_CHECKBOXS);
end;procedure TFormMain.tvTreeClick(Sender: TObject);
var
  P : TPoint;
  TreeNode : TTreeNode;
begin
  GetCursorPos(P);
  P := tvTree.ScreenToClient(P);  if (htOnStateIcon in tvTree.GetHitTestInfoAt(P.X,P.Y)) then
  begin
     TreeNode := tvTree.GetNodeAt(P.X,P.Y);
     ToggleCheckbox(tvTree, TreeNode);
  end;
end;procedure TFormMain.btnGetSelectedClick(Sender: TObject);
var
  I : Integer;
begin
  for I := 0 to tvTree.Items.Count - 1 do
  begin
    if IsChecked(tvTree.Items[I]) then
    begin
      ShowMessage(tvTree.Items[I].Text);
    end;
  end;
end;procedure TFormMain.btnSetSelectedClick(Sender: TObject);
var
  I : Integer;
begin
  if Trim(edtName.Text) = '' then Exit;  for I := 0 to tvTree.Items.Count - 1 do
  begin
    if tvTree.Items[I].Text = Trim(edtName.Text) then
      SetChecked(tvTree.Items[I], True);
  end;
end;end.