Einzelnen Beitrag anzeigen

nuclearping

Registriert seit: 7. Jun 2008
708 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Baumstruktur in Stream speichern

  Alt 21. Jan 2014, 11:40
Worin wird der Baum denn momentan abgebildet? TTreeView?

Im Grunde musst du dich hier genauso rekursiv durch die Nodes hangeln und TNode.Parent mit dem entsprechenden Knoten belegen, bzw. zB mit einer ID, da es ja keinen Sinn macht, den Pointer zu speichern (bzw die Speicheradresse des Knotens zu der Zeit).
Weiterhin musst du beachten, dass du Strings mit dynamischer Länge (var DynStr: String ) nicht direkt mit dem Record zusammen speichern kannst, sondern hier erst die Länge des Strings und dann den String mit Länge * 2 (wegen Unicode) speichern musst. Oder du gibst den Strings eine feste Länge (var FixedStr: String[20] ).

Du kannst dir ja auch mal den TVirtualStringTree anschauen. Der nimmt dir das Speichern und Laden solcher Strukturen recht bequem ab, indem er dir Events wie OnSaveNode / OnLoadNode zur Verfügung stellt, wo du deine Datenstruktur Knoten für Knoten in einen Stream speichern kannst, ohne dich beim Speichern und Laden um die Iteration bzw. Rekursion kümmern zu müssen.

Edit:

Ich arbeite für Baum- und Listenstrukturen ausschließlich nur noch mit dem TVirtualStringTree. Daher würde ein Beispiel zum Speichern / Laden mit dem VST mit deinen Daten zB so aussehen:

Delphi-Quellcode:
// **** Speichern

procedure TForm1.Button_SpeichernClick(Sender: TObject);
begin
  VirtualStringTree1.SaveToFile('tree.dat');
end;

procedure TForm1.VirtualStringTree1SaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode; Stream: TStream);
var
  Data: PNode; // Deine Datenstruktur
  strLength: Integer;
begin
  Data := Sender.GetNodeData(Node);
  with Data^ do
    begin
      Stream.Write(IsPersion, SizeOf(Boolean));
      strLength := Length(Name);
      Stream.Write(strLength, SizeOf(Integer));
      Stream.Write(Name[1], strLength * 2);
      // ... usw.
    end;
end;

// **** Laden

procedure TForm1.Button_LadenClick(Sender: TObject);
begin
  VirtualStringTree1.LoadFromFile('tree.dat');
end;

procedure TForm1.VirtualStringTree1LoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode; Stream: TStream);
var
  Data: PNode; // Deine Datenstruktur
  strLength: Integer;
begin
  Data := Sender.GetNodeData(Node);
  with Data^ do
    begin
      Stream.Read(IsPerson, SizeOf(Boolean));
      Stream.Read(strLength, SizeOf(Integer));
      SetLength(Name, strLength);
      Stream.Read(Name[1], strLength * 2);
      // ... usw.
    end;
end;

Geändert von nuclearping (21. Jan 2014 um 11:47 Uhr)
  Mit Zitat antworten Zitat