?
Solved

How To Save A TreeView To A File

Posted on 2003-03-20
10
Medium Priority
?
512 Views
Last Modified: 2010-04-04
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..
0
Comment
Question by:SOBKing
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
10 Comments
 
LVL 27

Expert Comment

by:kretzschmar
ID: 8179346
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
 

Author Comment

by:SOBKing
ID: 8179468
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
 
LVL 6

Expert Comment

by:BAlexandrov
ID: 8179552
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:SOBKing
ID: 8179677
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
 

Author Comment

by:SOBKing
ID: 8179712
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
 

Author Comment

by:SOBKing
ID: 8179834
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
 

Author Comment

by:SOBKing
ID: 8179837
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
 
LVL 27

Expert Comment

by:kretzschmar
ID: 8179858
please release the submit button :-))

i advice you to read the link i gave first

meikl ;-)
0
 

Author Comment

by:SOBKing
ID: 8181845
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
 
LVL 9

Accepted Solution

by:
mocarts earned 2000 total points
ID: 8184611
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

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
Suggested Courses

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question