Zwei Sachen sind mir aufgefallen:
1.
vstKunden.NodeDataSize := SizeOf(TRKundenDaten);
muss vor dem ersten AddChild stehen, sonst weiß der VST ja nicht, wie groß der Node sein soll und nachfolgende Speicheroperationen laufen ins (n)irgendwo.
2.
Wie schon gesagt, solltest du die Objekte in einer separaten Liste speichern und diese selbst wieder freigeben. Dann ist die Zuständigkeit sauber geregelt und du kannst auf das OnFreeNode komplett verzichten. Der VST arbeitet nur mit den Daten, der braucht sich nicht darum zu kümmern wo die herkommen und ob die freigegeben werden müssen.
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var
I : Integer;
CustomerNode, BuildingNode, SystemNode: PVirtualNode;
Daten: PRKundenDaten;
fk:TOCustomers;
fo:TOBuilding;
fs:TOSystems;
begin
vstKunden.NodeDataSize := SizeOf(TRKundenDaten);
KundenList:=TObjectList.create; // separate Liste
vstKunden.BeginUpdate;
try
vstKunden.Clear;
CustomerNode := vstKunden.AddChild(nil);
vstKunden.InvalidateNode(CustomerNode);
for I := 0 to 10 do
begin
BuildingNode := vstKunden.AddChild(nil);
Daten := vstKunden.GetNodeData(CustomerNode);
// das folgende geht anstandslos
fk := TOCustomers.Create;
fo := TOBuilding.Create;
fs := TOSystems.Create;
Daten^.FKundedaten := fk;
Daten^.FObjektdaten := fo;
Daten^.FSystemdaten := fs;
KundenList.Add(fk); // wahrscheinlich reicht hier aber auch ein Object pro Node
KundenList.Add(fo);
KundenList.Add(fs);
end;
vstKunden.SortTree(0, sdAscending, True);
finally
vstKunden.EndUpdate;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
KundenList.free;
end;