VirtualStringTreeのexport&importをテキスト形式でやられているか手折りますでしょうか。


りん  2026-09-26 09:46:39  No: 152306

おはようございます。
現在D7でVirtualStringTreeをいろいろ試しているんですが
export&importの際にバイナリーではなくテキスト形式で処理を行いたいと思いました。

多分ループで書き出しを行い、ループで読み込みを行うと思うのですが
レコード型とか代入のメソット等が複雑すぎて設計が思いつかない状態です。

もし、どなたか既にやられている方がおりましたら紹介していただけませんでしょうか。
よろしくお願いいたします。


りん  2026-09-26 09:52:32  No: 152307

×いるか手折り
↓
〇いるかたおり

でした(>_<)


AAAAA  2026-09-26 19:38:44  No: 152308

https://github.com/JAM-Software/Virtual-TreeView かな?

ソースあるので

procedure TBaseVirtualTree.SaveToStream(Stream: TStream; Node: PVirtualNode = nil);
procedure TBaseVirtualTree.WriteNode(Stream: TStream; Node: PVirtualNode);
procedure TBaseVirtualTree.WriteChunks(Stream: TStream; Node: PVirtualNode);
procedure TBaseVirtualTree.FinishChunkHeader(Stream: TStream; StartPos, EndPos: Integer);

の内容を Stream に書き込んでいるところを(他にもあるかも)  String に書き込むように変更する


procedure TBaseVirtualTree.SaveToStrings(String: TStrings; Node: PVirtualNode = nil);
procedure TBaseVirtualTree.WriteNode(Strings: TStrings; Node: PVirtualNode);                 //名前かえるか Overload
procedure TBaseVirtualTree.WriteChunks(Strings: TStrings; Node: PVirtualNode);               //名前かえるか Overload 
procedure TBaseVirtualTree.FinishChunkHeader(Strings: TStrings; StartPos, EndPos: Integer);  //名前かえるか Overload   

--- 例 ---

procedure TBaseVirtualTree.SaveToStream(Stream: TStream; Node: PVirtualNode = nil);
var
  Count: Cardinal;
begin
  Stream.Write(MagicID, SizeOf(MagicID));
  if Node = nil then
  begin
    // Keep number of top level nodes for easy restauration.
    Count := FRoot.ChildCount;
    Stream.WriteBuffer(Count, SizeOf(Count));

    // Save entire tree here.
    Node := FRoot.FirstChild;
    while Assigned(Node) do
    begin
      WriteNode(Stream, Node);
      Node := Node.NextSibling;
    end;


procedure TBaseVirtualTree.SaveToString(Strings; TStrings; Node: PVirtualNode = nil);
var
begin
  Strings.Add(MagicID)
  if Node = nil then
  begin
    Count := FRoot.ChildCount;
    Strings.Add(IntToStr(COUNT));

    Node := FRoot.FirstChild;
    while Assigned(Node) do
    begin
      WriteNode(Strings, Node);
      Node := Node.NextSibling;
    end;


りん  2026-09-26 22:46:07  No: 152309

AAAAA様、ありがとうございます。
ソースの書き換えはちょっと敷居が・・・・。

SaveToStreamでstreamにしたものを文字列に変えて、メモに文字列として保存し
そのメモを読み込んで復元なんてことはできないでしょうか?


AAAAA  2026-09-27 06:14:03  No: 152310

Stream の フォーマット通り読み込めばできるよ?

procedure Stream2Strings(Stream: TStream; Strings: TStrings);
var
    B: Byte;
    I: Integer;
    S: String;
    Buffer: array[0..255] of Char;
begin
    Stream.ReadData(B);
    Strings.Add(IntToStr(B));

    Stream.ReadData(I);
    Strings.Add(IntToStr(I));

    Stream.ReadData(Buffer);
    Strings.Add(Buffer);

    Stream.ReadData(B);
    Strings.Add(IntToStr(B));
    Stream.ReadData(S);
    Strings.Add(S);

    Stream.ReadData(B);
    Strings.Add(IntToStr(B));
end;


AAAAA  2026-09-27 06:14:45  No: 152311

書き込み側

procedure TForm2.Button1Click(Sender: TObject);
var
    B: Byte;
    MemoryStream: TMemoryStream;

    I: Integer;
    S: String;
    Buffer: array[0..255] of Char;
begin
    B := 5;
    I := 1024;
    S := 'ABC';

    StrPCopy(Buffer,'12345ZZZZ');
    MemoryStream := TMemoryStream.Create;
    MemoryStream.WriteData(B);
    MemoryStream.WriteData(I);
    MemoryStream.WriteData(Buffer);
    MemoryStream.WriteData(B);
    MemoryStream.WriteData(S);
    MemoryStream.WriteData(B);

    MemoryStream.Position := 0;

    Stream2Strings(MemoryStream,Memo1.Lines);

    MemoryStream.Free;


end;


AAAAA  2026-09-27 07:28:04  No: 152312

ソース自体書き換えなくても


uses
  VirtualTrees.BaseAncestorVCL,
  VirtualTrees.BaseTree,
  VirtualTrees.AncestorVCL,
  VirtualTrees,
  VirtualTrees.Types;

type
 
  TVirtualStringTree = class(VirtualTrees.TVirtualStringTree)
  private
    function GetCheckState(Node: PVirtualNode): TCheckState;
  public
    procedure DoSaveUserData(Node: PVirtualNode; Strings: TStrings); overload;
    procedure FinishChunkHeader(Strings: TStrings;  StartPos, EndPos: Integer); overload;  //StreamのSize書き込み Strings の場合不要
    procedure WriteChunks(Strings: TStrings;  Node: PVirtualNode); overload;
    procedure WriteNode(Strings: TStrings;  Node: PVirtualNode); overload;
    procedure SaveToStream(Strings: TStrings; Node: PVirtualNode = nil); overload;
  end;

 //VirtualTrees.BaseTree.pas  implementation 以下にあるので定義

  TMagicID = array[0..5] of WideChar;

  //VirtualTrees.BaseTree.pas
  TMagicID = array[0..5] of WideChar;

  //VirtualTrees.BaseTree.pas
  TBaseChunkBody = packed record
    ChildCount: Cardinal;
    NodeHeight: TDimension;
    States: TVirtualNodeStates;
    Align: Byte;
    CheckState: TCheckState;
    CheckType: TCheckType;
    Reserved: Cardinal;
  end;

  //VirtualTrees.BaseTree.pas
  TBaseChunk = packed record
    Header: TChunkHeader;      //VirtualTrees.Types
    Body: TBaseChunkBody;
  end;


const
    MagicID: TMagicID = (#$2045, 'V', 'T', WideChar(VTTreeStreamVersion), ' ', #$2046);

implementation

//private なので stream 使用していないけど copy
function TVirtualStringTree.GetCheckState(Node: PVirtualNode): TCheckState;
begin
    if Assigned(OnBeforeGetCheckState) then
       OnBeforeGetCheckState(Self, Node);
    Result := Node.CheckState;
end;

procedure TVirtualStringTree.DoSaveUserData(Node: PVirtualNode; Strings: TStrings);
begin
    //VirtualTrees.BaseTree.pas からコピーして Strings 用に変更する
end;

procedure TVirtualStringTree.FinishChunkHeader(Strings: TStrings;   StartPos, EndPos: Integer);
begin
   //StreamのSize書き込み Strings の場合不要
end;

procedure TVirtualStringTree.WriteChunks(Stream: TStream; Strings: TStrings;  Node: PVirtualNode);
begin
    //VirtualTrees.BaseTree.pas からコピーして Strings 用に変更する
end;

procedure TVirtualStringTree.WriteNode(Strings: TStrings;  Node: PVirtualNode);
begin
    //VirtualTrees.BaseTree.pas からコピーして Strings 用に変更する
end;

procedure TVirtualStringTree.SaveToStream(Strings: TStrings; Node: PVirtualNode = nil);
begin
    //VirtualTrees.BaseTree.pas からコピーして Strings 用に変更する
end;

でいけるよ?


※作成する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。







   このエントリーをはてなブックマークに追加