Why can't I create a pointer to a TTreeNode in a TTreeView

54 views Asked by At

Using C++ Builder in Rad Studio 10.4

Why can't I create a pointer to a TTreeNode?

I have a TTreeView called BookmarksTree, and I want to loop through all of its nodes. When I try and compile this:

TTreeNode *Node;
Node = BookmarksTree->Items[1];

I get a compiler error:

assigning to 'Vcl::Comctrls::TTreeNode *' from incompatible type 'Vcl::Comctrls::TTreeNodes'

According to Vcl.ComCtrls.TCustomTreeView.Items, I should be able to use MyTreeNode = TreeView1->Items[[1]];

Has anyone any idea what's wrong here?

1

There are 1 answers

0
Remy Lebeau On BEST ANSWER

BookmarksTree->Items is a pointer to a single TTreeNodes object. You are trying to perform pointer arithmetic to access a node as if the Items were an array of TTreeNode* pointers, which is simply not the case.

You need to use the TTreeNodes::Item[] sub-property instead, eg:

int count = BookmarksTree->Items->Count;
for(int i = 0; i < count; ++i)
{
    TTreeNode *Node = BookmarksTree->Items->Item[i];
    ...
}

Alternatively, you can use the TTreeNodes::operator[], but that requires you to dereference the TTreeNodes* pointer first, eg:

int count = BookmarksTree->Items->Count;
for(int i = 0; i < count; ++i)
{
    TTreeNode *Node = (*(BookmarksTree->Items))[i];
    ...
}

Alternatively, in the Clang-based compilers only, you can use C++ iterators, per C++ Iterator Support for Delphi Enumerable Types and Containers, eg:

auto iter = std::begin(BookmarksTree->Items);
auto end = std::end(BookmarksTree->Items);

while (iter != end)
{
    TTreeNode *Node = *iter++;
    ...
}

Or a range-for loop (which uses iterators internally):

for(TTreeNode *Node : BookmarksTree->Items)
{
    ...
}