普通に作るんであれば、
汎用的な再帰を実行する関数と、個別のノード移動時に実行される関数2つを作って、
個別関数で開くか閉じるかを実行するんじゃないかな。

//個別関数(の定義)
type TTVReflexiveFunction = procedure(Sender: TObject; Node: TTreeNode) of object;

//汎用関数
procedure TreeNodeReflexive(TreeView: TTreeView; TreeNode: TTreeNode; TVReflexiveFunction: TTVReflexiveFunction);
Var
ICount: Integer;
begin
TVReflexiveFunction(TreeView, TreeNode);

for ICount := 0 to TreeNode.Count -1 do
TreeNodeReflexive(TreeView, TreeNode[ICount], TVReflexiveFunction);

end;