Показать сообщение отдельно
  #6  
Старый 24.02.2014, 15:12
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Следуя вот этим рекомендациям вырисовывается лишь связка из сохранения структуры дерева в отдельном файле (см. код выше) и данных из нод, но так же в отдельном файле
Код:
...
type
 PNodeOptions = ^TNodeOptions;
 TNodeOptions = record
  Name:    string[255];
  Surname: string[255];
  Address: string[255];
  EMail:   string[255];
 end;

procedure NodeSaveDataProc(Writer: TWriter; Data: Pointer);
begin
 Writer.WriteListBegin;
 with TNodeOptions(Data^) do
 begin
  Writer.WriteString(Name);
  Writer.WriteString(Surname);
  Writer.WriteString(Address);
  Writer.WriteString(EMail);
 end;
 Writer.WriteListEnd;
end;

function NodeLoadDataProc(Reader: TReader): Pointer;
var
 P: PNodeOptions;
begin
 New(P);
 try
   Reader.ReadListBegin;
   with P^ do
   begin
    Name:=    Reader.ReadString;
    Surname:= Reader.ReadString;
    Address:= Reader.ReadString;
    EMail:=   Reader.ReadString;
   end;
   Reader.ReadListEnd;
 except
  Dispose(P);
  raise;
 end;
 Result:= P;
end;

type
TNodeSaveDataProc = procedure(Writer: TWriter; data: Pointer);
TNodeLoadDataProc = function(Reader: TReader): Pointer;

procedure SaveTreeviewToStream(tv: TTreeview; S: TStream;
saveProc: TNodeSaveDataProc);
var
  Writer: TWriter;
  Node:   TTreeNode;
begin
  Assert(Assigned(tv));
  Assert(Assigned(S));
  Assert(Assigned(saveProc));
  Writer:= TWriter.Create(S, 4096);
  try
    Node:= tv.Items[0];
    Writer.WriteListBegin;
    while Node <> nil do
    begin
     Writer.WriteInteger(Node.Level);
     Writer.WriteString(Node.Text);
     Writer.WriteInteger(Node.ImageIndex);
     saveProc(Writer, Node.Data);
     Node:= Node.GetNext;
    end; { While }
    Writer.WriteListEnd;
    Writer.FlushBuffer;
  finally
    Writer.Free;
  end;
end; { SaveTreeviewToStream }

procedure LoadTreeviewFromStream(tv: TTreeview; S: TStream;
                  loadProc: TNodeLoadDataProc);
var
  Reader: TReader;
  Node:   TTreeNode;
  Level:  integer;
begin
  Assert(Assigned(tv));
  Assert(Assigned(S));
  Assert(Assigned(loadProc));
  tv.Items.BeginUpdate;
  try
    tv.Items.Clear;
    Reader:= TReader.Create(S, 4096);
    try
      Node:= nil;
      Reader.ReadListBegin;
      while not Reader.EndOfList do begin
        Level := Reader.ReadInteger;
        if Node = nil then
        // create root node, ignore its level
          Node:= tv.Items.Add(nil, '')
        else
        begin
          if Level = Node.Level then
            Node:= tv.Items.Add(node, '')
          else if Level > Node.Level then
            Node:= tv.Items.AddChild(Node, '')
          else begin
            while Assigned(Node) and (Level < Node.Level) do
            Node:= Node.Parent;
            Node:= tv.Items.Add(node, '');
          end; { Else }
        end; { Else }
        Node.Text:= Reader.ReadString;
        Node.ImageIndex:= Reader.ReadInteger;
        Node.Data:= loadProc(Reader);
      end; { While }
      Reader.ReadListEnd;
    finally
      Reader.Free;
    end;
  finally
    tv.items.Endupdate;
  end;
end; { LoadTreeviewFromStream }

procedure TForm1.Button1Click(Sender: TObject);
var
 S: TFileStream;
begin
 S := TFileStream.Create('Data.sav', fmCreate or fmShareCompat);
 try
   SaveTreeViewToStream(TreeView1, S, NodeSaveDataProc);
 finally
   S.Free;
 end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 S: TFileStream;
begin
 S := TFileStream.Create('Data.sav', fmOpenRead);
 try
   LoadTreeViewFromStream(TreeView1, S, NodeLoadDataProc);
 finally
   S.Free;
 end;
end;
с последующей загрузкой. Если необходим один файл, то можно попробовать сливать их вместе, а затем резать в памяти на два куска, но есть ли в этом смысл, загадка
Ответить с цитированием