5,392
社区成员
发帖
与我相关
我的任务
分享
unit TVDemo;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, CommCtrl, StdCtrls;
type
TfrmtvDemo = class(TForm)
tvDemo: TTreeView;
Memo1: TMemo;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure tvDemoKeyPress(Sender: TObject; var Key: Char);
procedure tvDemoClick(Sender: TObject);
procedure Button1Click(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);
var
Node1A, NodeB:TTreeNode;
begin
SetWindowLong(tvDemo.Handle, GWL_STYLE, GetWindowLong(tvDemo.Handle,
GWL_STYLE) or $0000100); //使树形控件具有复选框功能
self.tvDemo.Items.Clear;
Node1A := self.tvDemo.Items.AddFirst(nil, '一级分类1A');
NodeB := self.tvDemo.Items.AddChildFirst(Node1A,'二级分类1A_2A');
self.tvDemo.Items.AddChildFirst(NodeB,'方案一');
self.tvDemo.Items.AddChild(NodeB,'方案二');
self.tvDemo.Items.AddChild(NodeB,'方案三');
NodeB := self.tvDemo.Items.AddChild(Node1A,'二级分类1A_2B');
self.tvDemo.Items.AddChildFirst(NodeB,'方案一');
self.tvDemo.Items.AddChild(NodeB,'方案二');
self.tvDemo.Items.AddChild(NodeB,'方案三');
Node1A := self.tvDemo.Items.Add(nil, '一级分类1B');
NodeB := self.tvDemo.Items.AddChildFirst(Node1A,'二级分类1B_2A');
self.tvDemo.Items.AddChildFirst(NodeB,'方案一');
self.tvDemo.Items.AddChild(NodeB,'方案二');
self.tvDemo.Items.AddChild(NodeB,'方案三');
NodeB := self.tvDemo.Items.AddChild(Node1A,'二级分类1B_2B');
self.tvDemo.Items.AddChildFirst(NodeB,'方案一');
self.tvDemo.Items.AddChild(NodeB,'方案二');
self.tvDemo.Items.AddChild(NodeB,'方案三');
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;
procedure TfrmtvDemo.Button1Click(Sender: TObject);
var
i:integer;
node:TTreeNode;
s:String;
begin
for i:=0 to tvDemo.Items.Count -1 do
begin
node := tvDemo.Items[i];
if IsChecked(node) and (self.tvDemo.Items[i].Level = 2) then
begin
s := s + tvDemo.Items[i].Text + #13 +#10;
end;
end;
self.memo1.text := s;
end;
end.
判断节点有没有子节点