Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS General Discussion » ReportGrid: manual tree traversal necessary to get all children? Collapse All
Subject Author Date
Martin Baumgaertner Jun 18, 2007 - 2:47 PM

Hello,

is there an elegant solution integrated in class CExtReportGridWnd that allows extracting ALL deepest children of a branch (i.e. tree items without children of their own) relative to a selected but collapsed HTREEITEM parent node? Or do I have to traverse all of its children and siblings manually?

Thanks in advance,

Martin

Martin Baumgaertner Jun 21, 2007 - 3:22 AM

Thank you for your kind answer!

[SOLVED]
I wrote the following recursive function (and it seems to work fine so far):

// --------------
void CProjectBrowser::TraverseSubtree ( HTREEITEM htiFocus,
                                        BOOL b_Initialized ) // = FALSE
                                            
{
    const bool b_ExpandedOnly = false; // traverse item only if expanded?
    const bool b_WalkDeeper = true; // internal, has to be TRUE
    bool b_SiblingsOnly = false; // traverse only siblings?

    if ( htiFocus == NULL )
    {
        return;
    }

    static HTREEITEM htiRoot = NULL;

    if ( !b_Initialized )
    {
        htiRoot = htiFocus;
        b_Initialized = TRUE;
    }

    ASSERT( htiRoot );

    if ( ItemGetChildCount( htiFocus ) != 0L ) // is any parent level
    {
        // DESCENDING
        htiFocus = ItemGetNext( htiFocus,
                                b_SiblingsOnly,    // FALSE
                                b_ExpandedOnly,    // FALSE
                                b_WalkDeeper );    // TRUE

        TraverseSubtree( htiFocus,
                         b_Initialized ); // = TRUE
    }
    else                        // is leaf node
    {
        // ATTENTION:
        // htiParent == htiRoot IS POSSIBLE
        // if leaf’s direct parent is selected node
        // --> needs to be proved (termiation condition)
        HTREEITEM htiParent = ItemGetParent( htiFocus );

        // iterate lowermost parent’s children
        for ( LONG i=0; i<ItemGetChildCount( htiParent ); ++i )
        {
            ExtractAndAddItemToSelection( ItemGetChildAt( htiParent, i ) ); // e.g. using vector in extraction function
        }

        // termination condition
        if ( (htiFocus = htiParent) == htiRoot )
        {
            return;
        }

        b_SiblingsOnly = TRUE;

        while ( (htiParent = ItemGetNext( htiFocus,
                                         b_SiblingsOnly, // TRUE
                                         b_ExpandedOnly, // FALSE
                                         b_WalkDeeper )) // TRUE
                == NULL )            // no next sibling available
        {
            // ASCENDING
            htiFocus = ItemGetParent( htiFocus );

            // termination condition
            if ( (htiParent = htiFocus) == htiRoot )
            {
                return;
            }
        }
    
        TraverseSubtree( htiParent,
                         b_Initialized ); // TRUE
    }
}
// --------------

This function can be called easily with the selection’s node as a parameter (e.g.):
    .......
    if ( ItemGetChildCount( hTreeItem ) != 0 && !ItemIsExpanded( hTreeItem ) )
    {
        TraverseSubtree( hTreeItem );
    }
    else
    {
    .......
    }
    .......


Martin

Technical Support Jun 19, 2007 - 11:21 AM

Yes, you should code a small recursive function which traverses all the tree items and analyzes if an item has any child items and its expanded state. We do not think it is complicated and anything more elegant is needed. But we could implement some GetFirst()/GetNext()/GetLast()/GetPrev() APIs for you or some FillList()/FillArray() API which would fetch CExtReportGridItem* pointers for you.