A1
B1
B2
A2
B1
B2
B3
A3
A4
int num;
num = TreeView1->Items->Count;
now num is 9, cause it's the total number of TreeNode s in the TreeView
I want the number of immediate descendants of a TreeNode so
I can iterate trough them
TreeNode->Count is what I need.
But I want to get a TreeNode* from the TreeNodes property of the TreeView,
so I can use it's Count property. But
when I do
num = TreeView1->Items[0].Count;
I get all the children. i.e. 9
num = TreeView1->Items[1].Count;
I get 0, though I think this must be a pointer to A2
num = TreeView1->Items[2].Count;
is an access violation (?)
Here I don't understand if Items[int] is a TreeNode, why the code above
doesn't work as I expect.
When I try
num = TreeView1->Items->Item->Count;
I get
[C++ Error] Unit1.cpp(89): E2193 Too few parameters in call to '_fastcall
TTreeNodes::GetNodeFromIndex(int)'
(Why?)
When I try
num = TreeView1->Items->Item[0]->Count;
I get the number of direct children of A1. OK
With
num = TreeView1->Items->Item[1]->Count;
I don't get the number of direct children of A2.
Stupid problem but I think I'm not getting right how to use this property.
I'd be grateful if someone could explain this stuff and write a short sample
code. Thanks.
Personally, I wouldn't touch TTreeView any more. It uses the MS tree that
relies on passing messages all over the place and so is very slow.
Take a look at VirtualTreeView by Mike Lischke which is very fast (x100?).
It takes a bit of getting used to but if you have large trees it is well
worth while.
http://www.delphi-gems.com/VirtualTreeview/VT.php
HTH Pete
"Analian" <ana...@mail.bg> wrote in message
news:4215...@newsgroups.borland.com...
> I've got this tree view
> I want the number of immediate descendants of a TreeNode so
OK
I also thought so.
Can you write a sample code that iterates on the parents in the outer cycle
and on the direct children in the inner
Something like
int i, j;
for (i = 0; i < number_of_As; ++i)
for (j = 0; i < A[i].number_of_Bs; ++j) {
TreeView1->Items[i][j];
or
TreeView1->Items[i]->Item[j];
or
TreeView1->Items->Item[i][j];
or
TreeView1->Items->Item[i]->Item[j];
// what shoud I do here?
do_something ();
}
I'd REALLY appreciate help on this stupid question, 'cause I'm already
losing my nerves.
Thanks.
> when I do
>
> num = TreeView1->Items[0].Count;
That will not even compile to begin with. It needs to be this instead:
num = TreeView1->Items->Item[0]->Count;
> I get all the children. i.e. 9
No, you will get 2, not 9, since Item[0] is the A1 node.
> num = TreeView1->Items[1].Count;
Again, that will not even compile. IT needs to be this instead:
num = TreeView1->Items->Item[1]->Count;
> I get 0, though I think this must be a pointer to A2
It will be a pointer to B1, not A2
> num = TreeView1->Items[2].Count;
> is an access violation (?)
And again:
num = TreeView1->Items->Item[2]->Count;
> Here I don't understand if Items[int] is a TreeNode, why
> the code above doesn't work as I expect.
Because you are not using it correctly in the first place.
> When I try
> num = TreeView1->Items->Item->Count;
> I get
> [C++ Error] Unit1.cpp(89): E2193 Too few parameters in call
> to '_fastcall TTreeNodes::GetNodeFromIndex(int)'
> (Why?)
The Item property needs an index:
num = TreeView1->Items->Item[SomeIndexHere]->Count;
> num = TreeView1->Items->Item[0]->Count;
> I get the number of direct children of A1. OK
Correct.
> num = TreeView1->Items->Item[1]->Count;
> I don't get the number of direct children of A2.
You are not supposed to. Item[1] is B1, whereas A2 is Item[3] instead. The
Item[] property uses absolute indexing, starting from the top of the tree
and working downwards sequentially, regardless of the levels the nodes
belong to:
Item[0] = A1
Item[1] = B1
Item[2] = B2
Item[3] = A2
Item[4] = B1
Item[5] = B2
Item[6] = B3
Item[7] = A3
Item[8] = A4
If you want to iterate the nodes of just a particular level, then you do not
use the Item[] property for that. You get a pointer to the first node of
the level and then use the GetNextSibling() method instead:
TTreeNode *Node = TreeView1->Items->GetFirstNode();
while( Node )
{
num = Node->Count;
TTreeNode *Child = Node->getFirstChild();
while( Child )
{
num = Child->Count;
Child = Child->GetNextSibling();
}
Node = Node->GetNextSibling();
}
Gambit
void dfs (TreeNode *Node) {
static int i = -1;
TreeNode *t;
if (Node == 0)
return;
Node->Text = "Bla" + (AnsiString)i; // here we could do something useful
in the "absolute" order of these nodes
t = Node->getFirstChild ();
for (; t; ) {
dfs (t);
t = t -> getNextSibling();
}
}
I just couldn't think of other senseful usage of this indexing and I'm
curios for any other examle. Got any?
> but I still don't get it why do you need the TreeNodes to be
> in absolute coordinates
The Items collection is a container for ALL nodes. The main
TTreeNodes::Count property is supposed to reflect all nodes. There is no
way to retreive a node at a given level directly, so the Items[] property
uses absolute indexing. If you want to take levels into account, then you
are not supposed to be using the Items[] property. That is why
GetFirst/LastChild(), GetNext/PreviousSibling(), etc. exist for each
individual node.
> why the Count property should be equal to ALL the children of
> the node, not just the direct ones.
The TTreeNode::Count does not count all children and grandchildren. Only
immediate children, exactly as you want. You can prove that for yourself:
A1
B1
C1
B2
A2
B3
B4
B5
C2
C3
D1
A3
A4
Given a TTreeNode pointer to A1, its Count is 2, not 3. Given a pointer to
A2, its Count is 3, not 6. And so on.
> I only see sense if this absolute indexing of these nodes
> could be used to receive the order in which the nodes
> shoud appear in a... post script I think. Like you have a
> tree graph and you perform a depth first search
> something like this:
That code is not using absolute indexing at all. That is using recursion to
loop through the individual levels. Absolute indexing would be the
following instead:
void dfs(TreeNode *Node)
{
if( Node )
{
TTreeNodes *Nodes = Node->Owner;
int index = Node->AbsoluteIndex;
int last;
TTreeNode *t = Node->GetNextSibling();
if( t )
last = t->AbsoluteIndex;
else
last = Nodes->Count;
while( index < last )
{
t = Nodes->Item[index];
t->Text = "Bla" + (AnsiString)index;
++index;
}
}
}
Alternatively:
void dfs(TreeNode *Node)
{
if( Node )
{
TTreeNode *Last = Node->GetNextSibling();
while( Node != Last )
{
Node->Text = "Bla" + (AnsiString)Node->AbsoluteIndex;
Node = Node->GetNext();
}
}
}
Gambit
I understood that the previous time. OK. Just don't see the reason why this
TreeView class is implemented in such a way.
I find the other methods of accessing more convenient to use. That's all.
I mean it doesn't use absolute indexing, but generates an order of the
Nodes, so they can retrievie such consequent numbering.
void dfs (TreeNode *Node) {
static int i = -1;
TreeNode *t;
if (Node == 0)
return;
Node->Text = "Bla" + (AnsiString) (++i); // here we could do something
useful in the "absolute" order of these nodes
// I forgot the ++
here
// and I say that if this fuction is used it will generate this absolute
indexing, that's all. And I was wondering what benefit
// could one have from this indexing, when he can write a recursive function
to access any node he needs
> I understood that the previous time. OK. Just don't see the
> reason why this TreeView class is implemented in such a way.
Because that is the way Microsoft implements TreeView controls in general.
TTreeView is just a thin wrapper around the Win32 API TreeView control.
Most of TTreeView's functionality is controlled by Windows, not the VCL.
> I find the other methods of accessing more convenient to use. That's all.
Then use them. Nobody is forcing you to use the Items[] property. There
are situations where it can be useful, though.
> I mean it doesn't use absolute indexing, but generates an order
> of the Nodes, so they can retrievie such consequent numbering.
Nodes are already numbered in an orderly fashion. TTreeNode has both Index
and AbsoluteIndex properties. Index is the index relative to the Parent
node. AbsoluteIndex is the index relative to the entire TreeView as a
whole.
Gambit