delphi的treeview中增加checkbox复选框

来源:互联网 发布:淘宝logo设计生成器 编辑:程序博客网 时间:2024/04/28 03:16

不知道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.

原创粉丝点击