Спасибо огромное!
Может кому-нибудь пригодиться... Немного переписанное событие OnMouseDown и рекурсивная процедура (позволяет проставить галочки во всех дочерних нодах):
Код:
procedure TMainForm.CTVMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
Node: TTreeNode;
begin
if (Sender as TCustomTreeView).AutoCheck=True then
begin
Node:=(Sender as TCustomTreeView).GetNodeAt(X, Y);
if (Node <> nil) and
((Sender as TCustomTreeView).GetHitTestInfoAt(X, Y) = [htOnItem, htOnStateIcon]) then
CheckSubNode(Sender, Node);
end;
end;
procedure TMainForm.CheckSubNode(Sender: TObject; Node: TTreeNode);
var
flag: boolean;
begin
if not Node.HasChildren then Exit;
flag:=(Sender as TCustomTreeView).GetChecked(Node);
Node:=Node.getFirstChild;
while Assigned(Node) do
begin
(Sender as TCustomTreeView).SetChecked(Node, flag);
CheckSubNode(Sender, Node);
Node:=Node.GetNextChild(Node);
end;
end;
Еще раз переписанное событие (позволяет снимать родительский чекбокс при снятии последнего дочернего и ставить родительский чекбокс при включении первого дочернего):
Код:
procedure TMainForm.CTVMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
NodeParent, Node: TTreeNode;
begin
if (Sender as TCustomTreeView).AutoCheck=True then
begin
Node:=(Sender as TCustomTreeView).GetNodeAt(X, Y);
if (Node <> nil) and
((Sender as TCustomTreeView).GetHitTestInfoAt(X, Y) = [htOnItem, htOnStateIcon]) then
CheckSubNode(Sender, Node);
if Node.Parent<>nil then
begin
NodeParent:=Node.Parent;
Node:=NodeParent.getFirstChild;
while Assigned(Node) do
begin
if (Sender as TCustomTreeView).GetChecked(Node) then
Checked:=True;
Node:=NodeParent.GetNextChild(Node);
end;
if not Checked then
(Sender as TCustomTreeView).SetChecked(NodeParent, false)
else
(Sender as TCustomTreeView).SetChecked(NodeParent, true);
end;
end;
end;
Рекурсивная процедура остается той же.
Таким образом, имеем полностью рабочее дерево с чекбоксами.