2017-08-10 2 views
4

Ich habe die virtualtree Komponente und das Handbuch "Virtual TreeView Tutorial" heruntergeladen. Ich folge dem Tutorial und der Codierung Schritt für Schritt. Die meisten Funktionen im Tutorial sind in Ordnung, außer das savetofile und loadfromfile funktionieren nicht.Wie zu/von Datei in/von Datei in virtualtree Komponente mit Delphi zu speichern/zu laden?

Meine Knotendaten sind

type 
    PMytreedata = ^TMYTreeData; 
    TMYTreeData = record 
    Column0: String; 
    Column1: String; 
    Column2: String; 
    end; 

Die Frage ist in column0 etwas Schnur verlieren, Spalte1/2, wenn die Last aus einer Datei.

Der Code ist unter

Erstellen neuer Knoten und Daten:

procedure TForm3.Button1Click(Sender: TObject); //CRETAE NEW NODE AND DATA 
begin 
    Randomize; 
    Rand := Random(99); 
    XNode := VST.AddChild(nil); 

    if VST.AbsoluteIndex(XNode) > -1 then 
    begin 
    Data := VST.GetNodeData(Xnode); 
    Data^.Column0 := IntToStr(Rand)+EDIT1.Text + 'One' ; 
    Data^.Column1 := EDIT1.Text+'Two' + IntToStr(Rand + 10); 
    Data^.Column2 := EDIT1.Text+'Three' + IntToStr(Rand - 10); 
    end; 
end; 

procedure TForm3.Button2Click(Sender: TObject);//ADDCHILD 
var 
    XNode: PVirtualNode; 
    Data: PMytreedata; 
begin 
    if not Assigned(VST.FocusedNode) then 
    Exit; 

    XNode := VST.AddChild(VST.FocusedNode); 
    Data := VST.GetNodeData(Xnode); 

    Data^.Column0 := EDIT1.Text ; 
    Data^.Column1 := EDIT2.Text ; 
    Data^.Column2 := EDIT3.Text ; 

    VST.Expanded[VST.FocusedNode] := True; 
end; 

Speichern und Laden von Datei ohne Codefehler

procedure TForm3.Button4Click(Sender: TObject); 
begin 
    VST.SaveToFile('C:\vst.at1'); 
end; 

procedure TForm3.Button5Click(Sender: TObject); 
begin 
    VST.LoadFromFile('C:\vst.at1'); 
end; 

Holen Sie sich den Knoten zur Dateigröße

procedure TForm3.VSTGetNodeDataSize(Sender: TBaseVirtualTree; 
    var NodeDataSize: Integer); 
begin 
    NodeDataSize := SizeOf(TMYTreeData);//WITHOUT THE CODE,ERROR COMING . 
end; 

Text anzeigen

procedure TForm3.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; 
    Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); 
var 
    Data: PMytreedata; 
begin 
    Data := VST.GetNodeData(Node); 
    case Column of 
    0: CellText := Data^.Column0; 
    1: CellText := Data^.Column1; 
    2: CellText := Data^.Column2; 
    end; 
end; 

LOAD FORM FILE

procedure TForm3.VSTLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode; 
    Stream: TStream);//LOAD FORM FILE 
var 
    Data: PMytreedata; 
    Len: Integer; 
begin 
     Data := VST.GetNodeData(Node); 

     Stream.read(Len, SizeOf(Len)); 
     SetLength(Data^.Column0, Len); 
     Stream.read(PChar(Data^.Column0)^, Len); 

     Stream.read(Len, SizeOf(Len)); 
     SetLength(Data^.Column1, Len); 
     Stream.read(PChar(Data^.Column1)^, Len); 

     Stream.read(Len, SizeOf(Len)); 
     SetLength(Data^.Column2, Len); 
     Stream.read(PChar(Data^.Column2)^, Len); 
end; 

SPAREN

procedure TForm3.VSTSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode; 
    Stream: TStream); //SAVE TO FILE 
var 
    Data: PMytreedata; 
    Len: Integer; 
begin 
    Data := VST.GetNodeData(Node); 

    Len := Length(Data^.Column0); 
    Stream.write(Len, SizeOf(Len)); 
    Stream.write(PChar(Data^.Column0)^, Len); 

    Len := Length(Data^.Column1); 
    Stream.write(Len, SizeOf(Len)); 
    Stream.write(PChar(Data^.Column1)^, Len); 

    Len := Length(Data^.Column2); 
    Stream.write(Len, SizeOf(Len)); 
    Stream.write(PChar(Data^.Column2)^, Len); 
end; 

Antwort

7

In Unicode Delphi TO FILE 2009 und später Char ist ein 16-Bit-Typ, WideChar. Sie schreiben nur die Hälfte der Zeichenfolge, weil Sie dies nicht berücksichtigen. Bei jedem Aufruf von Write und Read für den Inhalt der Zeichenfolge müssen Sie doppelt so viele Bytes schreiben.

Zum Beispiel kann jede Zeile wie diese

Stream.read(PChar(Data^.Column0)^, Len); 

sollte

Stream.read(PChar(Data^.Column0)^, Len*SizeOf(Char)); 

Einige andere Kommentare werden:

  • Sie Code zu replizieren lesen und jede Zeichenfolge zu schreiben. Es wäre besser, diese wiederholten Abschnitte des Codes in Methoden zur Wiederverwendung zu extrahieren.
  • Sie sollten statt Write verwenden. ruft Write auf, um die Arbeit zu erledigen, überprüft aber auch den Rückgabewert und führt eine Fehlerprüfung durch. Ebenso rufen Sie ReadBuffer statt Read.
+0

Ich habe nicht die Erfahrung der Verwendung von Writepuffer. Ich teste es und es funktioniert gut. Dank für Ihre für schnelle und genaue Lösung. Vielen Dank – u950321