加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Treeview中增加Checkbox复选框

(2011-02-12 14:17:43)
标签:

treeview控件

复选框

分类: Delphi

Delphi7中默认的Treeview控件中没有复选框按钮,为了方便使用贴出Delphi7中的Treeview控件中复选框的一种实现方法如下:

  1. 在窗体上增加Treeview控件取名字为tvDemo;
  2. 在FormCreate过程中增加代码,使树形控件具有复选框功能;
  3. 定义状态常量,增加方法和过程:
    • 定义节点选择状态常量TVIS_CHECKED;
    • IsChecked:用于判断节点是否被选中;
    • SetChecked:用于设置节点的选中状态;
  4. 附加功能(状态联动转换)
    1. 定义状态转换过程:Checkbox;
    2. 在鼠标和键盘事件中调用Checkbox;

注:TTVItem出现未定义时,需要引用CommCtrl。
代码如下:

 

 unit TVDemo;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, CommCtrl;

type
  TfrmtvDemo = class(TForm)
    tvDemo: TTreeView;
    procedure FormCreate(Sender: TObject);
    procedure tvDemoKeyPress(Sender: TObject; var Key: Char);
    procedure tvDemoClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    function IsChecked(Node: TTreeNode): Boolean;
    procedure SetChecked(Node: TTreeNode; Checked: Boolean);
    procedure Checkbox(TreeView: TTreeView; Node: TTreeNode; isclick:
      boolean = false);
  end;
var
  frmtvDemo: TfrmtvDemo;
implementation
{$R *.dfm}
const
  TVIS_CHECKED = $2000; //节点是否被选中

procedure TfrmtvDemo.FormCreate(Sender: TObject);
begin
  SetWindowLong(tvDemo.Handle, GWL_STYLE, GetWindowLong(tvDemo.Handle,
    GWL_STYLE) or $00000100); //使树形控件具有复选框功能
end;

function TfrmtvDemo.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 TfrmtvDemo.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 TfrmtvDemo.Checkbox(TreeView: TTreeView;
  Node: TTreeNode; isclick: boolean = false); //节点选择后子节点状态处理
var
  CurNode, ParentNode, GrandSonNode, sonNode: TTreeNode;
  flag: boolean;
begin
  CurNode := node;
  with TreeView do
  begin
    if IsChecked(CurNode) then
    begin
      sonNode := CurNode.GetFirstChild;
      while sonNode <> nil do
      begin
        SetChecked(sonNode, true);
        Checkbox(TreeView, sonNode, true);
        sonNode := sonNode.GetNextSibling;
      end;
      ParentNode := CurNode.Parent;
      if ParentNode <> nil then
      begin
        if not isChecked(parentNode) then
        begin
          GrandSonNode := ParentNode.GetFirstChild;
          flag := false;
          while GrandSonNode <> nil do
          begin
            if (not IsChecked(GrandSonNode)) then
              flag := true;
            if flag then
              GrandSonNode := nil
            else
              GrandSonNode := GrandSonNode.GetNextSibling;
          end;
          SetChecked(ParentNode, not flag);
          Checkbox(TreeView, ParentNode, false);
        end;
      end;
    end
    else if not IsChecked(CurNode) then
    begin
      ParentNode := CurNode.Parent;
      if ParentNode <> nil then
      begin
        if isChecked(parentNode) then
        begin
          SetChecked(ParentNode, false);
          Checkbox(TreeView, ParentNode);
        end;
      end;
      if (isclick) then
      begin
        sonNode := CurNode.GetFirstChild;
        while sonNode <> nil do
        begin
          SetChecked(sonNode, false);
          Checkbox(TreeView, sonNode, true);
          sonNode := sonNode.GetNextSibling;
        end;
      end;
    end;
  end;
end;

procedure TfrmtvDemo.tvDemoClick(Sender: TObject); //鼠标单击时选择
var
  P: TPoint;
  treenode: TTreeNode;
begin
  GetCursorPos(P);
  P := tvDemo.ScreenToClient(P);
  if (htOnStateIcon in tvDemo.GetHitTestInfoAt(P.X, P.Y)) then
  begin
    treenode := tvDemo.GetNodeAt(P.X, P.Y);
    Checkbox(tvDemo, treenode, true);
  end;
end;

procedure TfrmtvDemo.tvDemoKeyPress(Sender: TObject; var Key: Char);
//键盘空格时选择
begin
  if (Key = #32) and Assigned(tvDemo.Selected) then
    Checkbox(tvDemo, tvDemo.Selected, true);
end;

end.

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有