首页 > delphi > delphi的treeview中增加checkbox复选框

delphi的treeview中增加checkbox复选框

2010年9月28日 亲亲宝宝 发表评论 阅读评论

    不知道delphi中为啥treeview中没有提供checkbox复选框的功能,也有一些第三方的控件可以做,这里不使用第三方控件,直接使用delphi中的TTreeview 做一些修改,看看效果.

unit wenhq;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,CommCtrl,
  Dialogs, ComCtrls, StdCtrls;
type
  Twenhqform = class(TForm)
    TreeView1: TTreeView;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure TreeView1Click(Sender: TObject);
  private
    { Private declarations }
   procedure tvToggleCheckbox(TreeView: TTreeView;Node: TTreeNode;isclick:boolean =false);
   procedure SetChecked(Node: TTreeNode; Checked: Boolean);
   function IsChecked(Node: TTreeNode): Boolean;
 public
    { Public declarations }
  end;

var
  wenhqform: Twenhqform;

implementation

{$R *.dfm}
 const
TVIS_CHECKED = $2000;
procedure Twenhqform.FormCreate(Sender: TObject);
begin
//仅仅这一句话就能让treeview 显示复选框
SetWindowLong(TreeView1.Handle, GWL_STYLE, GetWindowLong(TreeView1.Handle, GWL_STYLE) or $00000100);
end;
//检查某个节点是否被 选中
function Twenhqform.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 Twenhqform.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 Twenhqform.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;

procedure Twenhqform.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;
end.

分类: delphi 标签: 5,994 次阅读
原文链接:http://www.wenhq.com/article/view_659.html
欢迎转载,请注明出处:亲亲宝宝
  1. 2010年10月4日01:26 | #1

    delphi 压根不懂!!

    [回复]

  2. 2010年11月30日16:03 | #2

    踩踩

    [回复]

  3. 2011年1月18日16:55 | #3

    给楼主踩踩,人气大增!

    [回复]

  1. 本文目前尚无任何 trackbacks 和 pingbacks.