2017-08-10 52 views
4

我已经下载了virtualtree组件和手册“Virtual TreeView tutorial”。我遵循教程和编码一步一步。教程中的大部分功能都很好,除了savetofile和loadfromfile不起作用。如何使用Delphi在virtualtree组件中保存/加载/从文件加载?

我的节点数据

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

的问题是一些字符串column0输球,COLUMN1/2时从文件加载。

的代码如下

创建新的节点和数据:从文件

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

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

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; 

保存到文件和负载获取节点大小无码错误

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

显示文本

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表单文件

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; 

保存到文件

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; 

回答

7

在Unicode的德尔福,2009年以后,Char是16位的,WideChar。你只写了一半的字符串,因为你没有考虑到这一点。在每次调用WriteRead作为字符串的内容时,必须写入两倍的字节数。

例如,每行这样

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

应该

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

一些其他意见:

  • 您复制代码读取和写入每个字符串。将这些重复的代码段提取到重用方法中会更好。您可以使用WriteBuffer而不是WriteWriteBuffer调用Write来做这项工作,但也检查返回值并执行错误检查。同样请拨打ReadBuffer而不是Read
+0

我没有使用writebuffer的经验。我测试它,它工作得很好。感谢您的快速和准确的解决方案。谢谢 – u950321