微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用Delphi保存/加载到virtualtree组件中的文件?

我已经下载了virtualtree组件和手册“Virtual TreeView教程”.我一步一步地按照教程和编码.教程中的大部分功能都很好,除了savetofile和loadfromfile不起作用.

我的节点数据是

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

问题是当从文件加载时,column0,column1 / 2中的字符串丢失.

代码如下

创建新节点和数据:

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.Button4Click(Sender: TObject);
begin
    VST.SavetoFile('C:\vst.at1');
end;

procedure TForm3.Button5Click(Sender: TObject);
begin
    VST.LoadFromFile('C:\vst.at1');
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;

加载表格文件

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)^,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;

解决方法

在Unicode Delphi,2009及更高版本中,Char是16位类型的WideChar.你只写了一半的字符串,因为你没有考虑到这一点.在每次调用Write和Read的字符串内容时,必须写入两倍的字节.

例如,每条线都是这样的

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

应该

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

其他一些评论

>您复制代码以读取和写入每个字符串.将这些重复的代码提取到重用方法中会更好.>您应该使用WriteBuffer而不是Write. WriteBuffer调用Write来完成工作,但也会检查返回值并执行错误检查.同样调用ReadBuffer而不是Read.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐