保存VirtualStringTree节点数据

Max*_*ams 2 delphi unicode virtualtreeview tvirtualstringtree delphi-xe3

我正在尝试将项目从D6移动到D-XE3.使用VirtualStringTree版本5.10在OnSaveNode和OnLoadEvents中保存和加载树数据时,我得到了垃圾.我可能没有正确处理Unicode,但我可能还有其他一些无知:

procedure TfMain.vstGridSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Stream: TStream);
var
  Data: PStkData;
begin
  Data := Sender.GetNodeData(Node);

  //  Owned: boolean;
  Stream.Write(Data.Owned, SizeOf(boolean) );

  //  Symbol: string;
  Stream.Write(PChar(Data.Symbol)^, Length(Data.Symbol) * SizeOf(Char));

  //  AvgTarget: currency;
  //Stream.Write(Data.AvgTarget, SizeOf(currency));

  //  PE: double;
  Stream.Write(Data.PE, SizeOf(double));
end;

procedure TfMain.vstGridLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Stream: TStream);
var
  Data: PStkData;
begin
  Data := Sender.GetNodeData(Node);

  //Owned: boolean;
  Stream.Read(Data.Owned, SizeOf(boolean));

  //Symbol: string;
  Stream.Read(PChar(Data.Symbol)^, Length(Data.Symbol) * SizeOf(Char));

  //AvgTarget: currency;
  Stream.Read(Data.AvgTarget, SizeOf(currency));

  //PE: double;
  Stream.Read(Data.PE, SizeOf(double));
end;
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助.

Rob*_*edy 8

当您编写字符数据时,您需要确保以这样的方式编写它,以便您知道在加载时再读取多少内容.你目前正在写只是字符数据,所以你不知道你需要多少稍后再阅读.相反,你假设Symbol已经是正确的长度,现在我已经指出了,你可能意识到这是一个无效的假设.

当你编写字符串时,首先写下它的长度,以便在加载时可以读取:

var
  SymbolLen: Integer;

SymbolLen := Length(Data.Symbol);
Stream.Write(SymbolLen, SizeOf(SymbolLen));
Stream.Write(PChar(Data.Symbol)^, Length(Data.Symbol) * SizeOf(Data.Symbol[1]));
Run Code Online (Sandbox Code Playgroud)

然后你可以阅读它:

Stream.Read(SymbolLen, SizeOf(SymbolLen));
SetLength(Data.Symbol, SymbolLen);
Stream.Read(PChar(Data.Symbol)^, SymbolLen * SizeOf(Data.Symbol[1]));
Run Code Online (Sandbox Code Playgroud)