Einzelnen Beitrag anzeigen

Benutzerbild von GuenterS
GuenterS

Registriert seit: 3. Mai 2004
Ort: Österreich > Bad Vöslau
760 Beiträge
 
Turbo Delphi für Win32
 
#1

VirtualStringTree und OnLoadNode

  Alt 18. Jun 2005, 23:44
Hallo,

jetzt kämpf ich schon eine ganze Weile mit dem VirtualStringTree. Ich möchte den Tree mit den dazu zur Verfügung gestellten Methoden "SaveToFile" und "LoadFromFile" speichern.

Jede Node enthält jedoch auch noch einen Record mit Daten, welche in den Ereignissen "OnSaveNode" und "OnLoadNode" in einen übergebenen Stream geschrieben bzw. von diesem gelesen werden müssen.

Wie es aussieht, klappt das Schreiben der Nodes.

Ich verwende folgenden Record, der mir die Daten hält welche ich im Node speichern möchte.
Delphi-Quellcode:
  PTreeData = ^TTreeData;
  TTreeData = record
    FileName: string;
    EntryType: TEntryType;
    Entry: TEntry;
  end;
TEntry ist die Basisklasse, verschiedener TEntryClassen, so gibt es CategoryEntry Klassen wie auch NoticeEntry Klassen.

Über EntryType kann unterschieden werden ob es sich um eine CategoryEntry Klasse oder eine NoticeEntry Klasse handelt.

Die TEntry Klasse:
Delphi-Quellcode:
  TEntryType = (etCATEGORY, etNOTICE);

  TEntry = class(TObject)
  private
    FCaption: string;
    FEntryType: TEntryType;
    FEntryFolder: string;
    FEntryFilename: string;
    function getEntryFullFileName: string;
    function getDataSize: integer;
  public

    procedure SaveMeToFile(aSourceComponent: TComponent); virtual;
    procedure LoadMeFromFile(aTargetComponent: TComponent; const aFilename: string); virtual;

    property EntryType: TEntryType read FEntryType write FEntryType;
    property Caption: string read FCaption write FCaption;
    property EntryFolder: string read FEntryFolder write FEntryFolder;
    property EntryFilename: string read FEntryFilename write FEntryFilename;
    property EntryFullFileName: string read getEntryFullFileName;
    property DataSize: integer read getDataSize;
  end;
Das Feld Caption ist das Feld, welches zur Beschriftung der Node hergenommen wird.

Die Eventroutine beim Speichern der Node schaut so aus:
Delphi-Quellcode:
procedure TfDataBox.vstSaveNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Stream: TStream);
var
  lTreeData: PTreeData;
  lIntegerData: integer;
begin
  lTreeData := PTreeData(Sender.GetNodeData(Node)^);
  lIntegerData := Ord(lTreeData.EntryType);
  Stream.WriteBuffer(lIntegerData, sizeOf(lIntegerData));
  lIntegerData := length(lTreeData.FileName);
  Stream.WriteBuffer(lIntegerData, sizeOf(lIntegerData));
  Stream.WriteBuffer(PChar(lTreeData.FileName)^, lIntegerData);
end;
Die Eventroutine zum Laden der Nodes schaut so aus:
Delphi-Quellcode:
procedure TfDataBox.vstLoadNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Stream: TStream);
var
  lTreeData: PTreeData;
  lEntryType: TEntryType;
  lIntegerData: integer;
  lFileName: string;
begin
  lTreeData := PTreeData(Sender.GetNodeData(Node)^);
  Stream.Read(lTreeData^.EntryType, sizeOf(integer));
  Stream.Read(lIntegerData, sizeOf(lIntegerData));
  setLength(lTreeData^.FileName, lIntegerData);
  Stream.Read(lTreeData^.FileName, lIntegerData);
  case lEntryType of
    etCATEGORY:
      begin
        lTreeData^.Entry := TCategoryEntry.Create;
        lTreeData^.Entry.LoadMeFromFile(nil, lFileName);
      end;
    etNOTICE:
      begin
        lTreeData^.Entry := TNoticeEntry.Create;
        lTreeData^.Entry.LoadMeFromFile(FNoticeEditor, lFileName);
      end;
  end;
end;

Jedoch bekomme ich beim Laden des Trees nur Access Violations, welche daher kommen, dass die Daten welche an den Nodes angehängt sein sollten, anscheinend nicht angehängt sind. Ich denke aber, dass ich genau das ja mit dieser Routine erreichen sollte.

Die NodeDataSize ist vorher schon auf die Größe von PTreeData festgelegt.

Weiß vielleicht jemand was ich falsch mache? Wieso mein Code nicht so funktioniert, wie ich mir das vorstelle?
Günter
Pünktlichkeit ist die Fähigkeit vorherzusagen um wieviel sich der Andere verspäten wird.
  Mit Zitat antworten Zitat