How To Save A TreeView To A File

my question is for C++Builder

i have a TreeView with multiple nodes.. each node has the .data property set to point to some structure with additional info about that node

now i need to know how to save that TTreeView to a file of some kind and then load it again...

and i need the .data to be saved as well so when im done loading it.. it will be there too!

please dont tell me to use the .SaveToFile property as that wont save the .data part  (unless im doing something wrong)


just incase no one know what im talking about the .data thing i will give some code

here is the code i use to add an item to the tree

//The Structure
struct TreeLeaf {
    char Name[40];
    char Description[100];
    char Pin[2];
    char Light[8];
};

//The Add Code
    TreeLeaf *data;
    TTreeNode *node;

    data = (TreeLeaf *)malloc(sizeof(TreeLeaf));

    strcpy(data->Pin, "00");
    strcpy(data->Light, "00000000");
    strcpy(data->Description, "New Item");

    node = spSkinTreeView1->Items->Add(NULL,"New Item");
    node->Data = data;
    node->Selected = true;

    Current = node;




so as you can see each node has some additional data attached to it.. which is critical to be saved along with the tree..
SOBKingAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

kretzschmarCommented:
go to q

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_10120892.html

you may find there some solutions, how this could be done

meikl ;-)
0
SOBKingAuthor Commented:
ok thanks i will look into that!

one thing i was thinking of is..

1st.. just saving the tree with the .save to file...

then after thats saved.. run thru the tree.. and for each node write the .data to a file

then when opening it...

open the ree with the loadfromfile...

then after its loaded.. run thru the tree backwards and set the .data property from that file..


the only problem with that is i dont know how to traverse a complicated tree... i know how to do a birnar tree with recursion..
0
BAlexandrovCommented:
If you traverse it root - left node - right node, save to file and restore in same manner then it will remain same.
For complex tree - if there is one root with 3 childs - process root, first child, second child, third child...
That is the way.

Bojidar Alexandrov
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

SOBKingAuthor Commented:
ya i understand the theory kinda.. thats what we doing in classes right now.. its the code i have no idea..

i dont understand enough about to do that...

if someone could give me some code to lets say traverse a tree and add the node->text property to a memo that would be awsome! and would get the points..  :)

oh please try to give in c++ builder. but if all u know is delphi.. i may be able to figure it out

thanks
0
SOBKingAuthor Commented:
ya i understand the theory kinda.. thats what we doing in classes right now.. its the code i have no idea..

i dont understand enough about to do that...

if someone could give me some code to lets say traverse a tree and add the node->text property to a memo that would be awsome! and would get the points..  :)

oh please try to give in c++ builder. but if all u know is delphi.. i may be able to figure it out

thanks
0
SOBKingAuthor Commented:
ya i understand the theory kinda.. thats what we doing in classes right now.. its the code i have no idea..

i dont understand enough about to do that...

if someone could give me some code to lets say traverse a tree and add the node->text property to a memo that would be awsome! and would get the points..  :)

oh please try to give in c++ builder. but if all u know is delphi.. i may be able to figure it out

thanks
0
SOBKingAuthor Commented:
ya i understand the theory kinda.. thats what we doing in classes right now.. its the code i have no idea..

i dont understand enough about to do that...

if someone could give me some code to lets say traverse a tree and add the node->text property to a memo that would be awsome! and would get the points..  :)

oh please try to give in c++ builder. but if all u know is delphi.. i may be able to figure it out

thanks
0
kretzschmarCommented:
please release the submit button :-))

i advice you to read the link i gave first

meikl ;-)
0
SOBKingAuthor Commented:
i thinkt he stuf in the other post is wayyyyy over my head...

lol i guess i pressed it one too many times  hah
0
mocartsCommented:
exactly. you must start with TreeView's SaveToFile method :) to be precise with it's implementation.
i wrote small treeview saver class for you :)
you must assign OnReadData and OnWriteData event to r/w data associated with node - something like:
Stream.Write(Node.Data^, SizeOf(TreeLeaf));
and
Stream.Read(PNewLeaf^, SizeOf(TreeLeaf));
Node.Data := PNewLeaf;

type
  TTreeDataEvent = procedure(Stream: TStream; Node: TTreeNode) of object;

  TTreeViewSaver = class
  private
    FOnWriteData: TTreeDataEvent;
    FOnReadData: TTreeDataEvent;
    FNodes: TTreeNodes;
  public
    constructor Create(Nodes: TTreeNodes);
    procedure LoadFromStream(Stream: TStream);
    procedure SaveToStream(Stream: TStream);
    procedure LoadFromFile(const FileName: string);
    procedure SaveToFile(const FileName: string);

    property OnWriteData: TTreeDataEvent read FOnWriteData write FOnWriteData;
    property OnReadData: TTreeDataEvent read FOnReadData write FOnReadData;
  end;

implementation

constructor TTreeViewSaver.Create(Nodes: TTreeNodes);
begin
  inherited Create;
  FNodes := Nodes;
end;

procedure TTreeViewSaver.LoadFromFile(const FileName: string);
var
  Stream: TStream;
begin
  Stream := TFileStream.Create(FileName, fmOpenRead);
  try
    LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
end;

procedure TTreeViewSaver.LoadFromStream(Stream: TStream);
var
  ALevel, ASize: Word;
  AText: string;
  ANode, NextNode: TTreeNode;
begin
  FNodes.BeginUpdate;
  try
    if FNodes.Count > 0 then FNodes.Clear;
    ANode := nil;
    while Stream.Position < Stream.Size do begin
      Stream.Read(ALevel, sizeOf(ALevel));
      Stream.Read(ASize, sizeOf(ASize));
      SetLength(AText, ASize);
      Stream.Read(AText[1], ASize);
      if ANode = nil then
        ANode := FNodes.AddChild(nil, AText)
      else if ANode.Level = ALevel then
        ANode := FNodes.AddChild(ANode.Parent, AText)
      else if ANode.Level = (ALevel - 1) then
        ANode := FNodes.AddChild(ANode, AText)
      else if ANode.Level > ALevel then
      begin
        NextNode := ANode.Parent;
        while NextNode.Level > ALevel do
          NextNode := NextNode.Parent;
        ANode := FNodes.AddChild(NextNode.Parent, AText);
      end
      else
        raise Exception.Create('Invalid TreeViewSaver stream format.');
      if assigned(FOnReadData) then
        FOnReadData(Stream, ANode);
    end;
  finally
    FNodes.EndUpdate;
  end;
end;

procedure TTreeViewSaver.SaveToFile(const FileName: string);
var
  Stream: TStream;
begin
  Stream := TFileStream.Create(FileName, fmCreate);
  try
    SaveToStream(Stream);
  finally
    Stream.Free;
  end;
end;

procedure TTreeViewSaver.SaveToStream(Stream: TStream);
var
  ALevel: Word; // should be enough
  ANode: TTreeNode;
begin
  if FNodes.Count > 0 then
  begin
    ANode := FNodes[0];
    while ANode <> nil do
    begin
      ALevel := ANode.Level;
      Stream.Write(ALevel, sizeOf(ALevel));
      ALevel := Length(ANode.Text);
      Stream.Write(ALevel, sizeOf(ALevel));
      Stream.Write(ANode.Text[1], ALevel);
      if assigned(FOnWriteData) then
        FOnWriteData(Stream, ANode);
      ANode := ANode.GetNext;
    end;
  end;
end;

end.

wbr, mo.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.