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