EX. ONE
this first example
ITERATE THROUGH ALL OF THE NODES IN A TREE VIEW
note that we MIGHT have looped through TreeView.Items
where n is 0 to (TreeView.Items.Count - 1) but we
don't: doing it this way is more akin to the way we
are forced to loop through an XML DOM tree and the
method is more generic...
procedure TMainForm.FormCreate(Sender: TObject);
const
menusTextFileName = 'menus.txt';
var
TVrootNode: TTreeNode;
begin
TreeView.LoadFromFile(menusTextFileName);
TVrootNode := TreeView.Items.GetFirstNode;
TreeViewWalker(TVrootNode);
end;
////////////////////////////////////////////////////////////
procedure TMainForm.TreeViewWalker(currTVnodePtr: TTreeNode);
//Recursive procedure to iterate through all of the nodes in
//a TreeView tree. Note that this code DOES NOTHING as yet:
//it merely forms the basis for some potential useful thing
var
TVnodePtr: TTreeNode;
nodeNameText: String;
begin
if (currTVnodePtr.hasChildren) then
begin
TVnodePtr := currTVnodePtr.GetFirstChild;
repeat
if (assigned(TVnodePtr)) then
begin
nodeNameText := TVnodePtr.Text;
GetPathStringsFromTreeView(TVnodePtr, paths);
end;
TVnodePtr := TVnodePtr.GetNextSibling;
until (TVnodePtr = nil);
end;
end;
////////////////////////////////////////////////////////////
************************************************************
EX. TWO
this next example appends node text strings to a string list
procedure TMainForm.FormCreate(Sender: TObject);
var
pathStrings: TStringList;
TVrootNode: TTreeNode;
begin
pathStrings := TStringList.Create;
TreeView.LoadFromFile(menusTextFileName);
TVrootNode := TreeView.Items.GetFirstNode;
GetPathStringsFromTreeView(TVrootNode, pathStrings);
pathStrings.SaveToFile(pathsTextFileName);
pathStrings.Free;
end;
////////////////////////////////////////////////
procedure TMainForm.GetPathStringsFromTreeView(currTVnodePtr: TTreeNode;
var paths: TStringList);
//Recursive procedure to iterate through all of the nodes in a TreeView
//tree, appending each node's text string to a string list
var
TVnodePtr: TTreeNode;
nodeNameText: String;
begin
if (currTVnodePtr.hasChildren) then
begin
TVnodePtr := currTVnodePtr.GetFirstChild;
repeat
if (assigned(TVnodePtr)) then
begin
nodeNameText := TVnodePtr.Text;
paths.Add(nodeNameText);
GetPathStringsFromTreeView(TVnodePtr, paths);
end;
TVnodePtr := TVnodePtr.GetNextSibling;
until (TVnodePtr = nil);
end;
end;
***************************************************************************
EX. THREE
the last example here is similar to the example above, but it has the added
feature of building up full 'path' strings for the nodes by prefacing node
text with the text of it's parents, rather than just using the node text as
is -see comments in GetTreeNodeFullPathName below-
////////////////////////////////////////////////
procedure TMainForm.FormCreate(Sender: TObject);
var
pathStrings: TStringList;
TVrootNode: TTreeNode;
begin
pathStrings := TStringList.Create;
//use a simple tabbed text file as input
TreeView.LoadFromFile(menusTextFileName);
TVrootNode := TreeView.Items.GetFirstNode;
GetPathStringsFromTreeView(TVrootNode, pathStrings);
pathStrings.SaveToFile(pathsTextFileName);
pathStrings.Free;
end;
////////////////////////////////////////////////
procedure TMainForm.GetPathStringsFromTreeView(currTVnodePtr: TTreeNode;
var paths: TStringList);
//Recursive procedure to iterate through all of the nodes in a TreeView
//tree, appending each node's text string to a string list. The procedure
//does yet more though: rather than just using the node string as is, the
//node's node string is prefaced with the text of it's parent nodes, so
//that we have proper 'path' names for the nodes: eg where a node with
//the text 'File' has a child node whose text is 'Open', then the string
//we build up for the child node becomes 'File\Open' (and not just 'Open').
//There is mileage in handling node text or node 'names' as 'path names'
//that fully describe the node's place in the tree heirarchy... see
//elsewhere for ways that we might take advantage of this however...
var
TVnodePtr: TTreeNode;
nodeNameText: String;
begin
if (currTVnodePtr.hasChildren) then
begin
TVnodePtr := currTVnodePtr.GetFirstChild;
repeat
if (assigned(TVnodePtr)) then
begin
nodeNameText := TVnodePtr.Text;
nodeNameText := GetTreeNodeFullPathName(TVnodePtr, nodeNameText);
paths.Add(nodeNameText);
GetPathStringsFromTreeView(TVnodePtr, paths);
end;
TVnodePtr := TVnodePtr.GetNextSibling;
until (TVnodePtr = nil);
end;
end;
///////////////////////////////////////////////////////////////////////
function TMainForm.GetTreeNodeFullPathName(tempTVnodePtr: TTreeNode;
nodeText: String): String;
//go up through the parents of the node passed in, building up a 'full
//path name' string such that if we have nodes where the text is 'File',
//'Open' (and this node is a child of the 'File' node), 'OpenDoc' (and
//where this node is a child of the 'Open' node) then the 'full path'
//string built up for OpenDoc becomes 'File\Open\OpenDoc'...
var
TVrootNode: TTreeNode;
begin
while (Assigned(tempTVnodePtr.Parent) and
(tempTVnodePtr.Parent <> TreeView.Items[0])) do
begin
tempTVnodePtr := tempTVnodePtr.Parent;
//build up the string...
nodeText := tempTVnodePtr.Text + '\' + nodeText;
end;
//make sure that we preface the path string with
//the root node's text... [nb in some contexts, the root node's
//text will be synonymous with the tree's 'namespace'...]
TVrootNode := TreeView.Items.GetFirstNode;
//if speed is an issue, there will be a way of coding
//the line above such that it executes faster...
Result := TVrootNode.Text + '\' + nodeText;
end;