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 Tech Support » need help using CExtTreeCtrl Collapse All
Subject Author Date
Dave Calkins Dec 11, 2009 - 8:58 AM

We have been using CExtWFF<CTreeCtrl> in our app.  We use this with an image list to provide icons for individual items in the tree.  We’ve noticed that under Windows 7, the dashed lines drawn to the nodes in the tree do not render correctly.  If we comment out the set image list call, removing the images, then the lines draw correctly.


Prof-UIS support suggested we use CExtTreeCtrl instead and use the TreeIconInsert method there instead of image lists.


Is there a sample anywhere which illustrates this?  We’ve tried this but cannot get images to show in the tree using this approach.


We’re initializing the tree images with the below code using the same image we used to use with the image list (so we have to manually chop it up into the individual icons).


<tt> CImage treeIconSet;

    treeIconSet.LoadFromResource(AfxGetInstanceHandle(),IDB_TAB);

    const int iconWidth = 16;

    const int iconHeight = 16;

    CDC screenDC;

    screenDC.CreateDC(_T("DISPLAY"),NULL,NULL,NULL);

    CDC offscreenDC;

    offscreenDC.CreateCompatibleDC(&screenDC);

    HDC hOffscreenDC = offscreenDC.GetSafeHdc();

    INT iconPos = 0;

    for (int xUL = 0; (xUL+iconWidth-1) < treeIconSet.GetWidth(); xUL += iconWidth, iconPos++)

    {

        CImage iconImg;

        if (!iconImg.CreateEx(iconWidth,iconHeight,32,BI_RGB,NULL,CImage::createAlphaChannel))

            break;

        HBITMAP hBmp = iconImg.Detach();

        HGDIOBJ hPrevObj = ::SelectObject(hOffscreenDC,hBmp);

        treeIconSet.Draw(hOffscreenDC,0,0,iconWidth,iconHeight,xUL,0,iconWidth,iconHeight);

        ::SelectObject(hOffscreenDC,hPrevObj);

        CExtCmdIcon& cmdIcon = *new CExtCmdIcon;

        cmdIcon.AssignFromHBITMAP(hBmp);

        TreeIconInsert(cmdIcon,iconPos);

    }</tt>


 We then call CTreeCtrl::SetItemImage on individual items.  But no icons show up in the tree.  Is there something else we need to do?

Technical Support Dec 15, 2009 - 1:46 PM

Yes. The ProfUIS_Controls sample application contains the CPageTreeCtrl dialog page dedicated to the CExtTreeCtrl extended tree control. The tree control displays images there. Here is the part of the CPageTreeCtrl::OnInitDialog() method initializing a set of tree items displaying icons:

                                       HTREEITEM htiItemsWithIcons = m_wndTree.InsertItem( _T("Items with icons"), htiControls, NULL );
                                                m_wndTree.TreeItemInfoGet( htiItemsWithIcons ).m_nIconIndexCollapsed = 1;
                                                m_wndTree.TreeItemInfoGet( htiItemsWithIcons ).m_nIconIndexExpanded = 0;

                                                                                    hti = m_wndTree.InsertItem( _T("Item 0"), htiItemsWithIcons, NULL );
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexCollapsed = 2;
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexExpanded = 2;

                                                                                    hti = m_wndTree.InsertItem( _T("Item 1"), htiItemsWithIcons, NULL );
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexCollapsed = 3;
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexExpanded = 3;
                                                                                    
                                                                                    hti = m_wndTree.InsertItem( _T("Item 2"), htiItemsWithIcons, NULL );
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexCollapsed = 4;
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexExpanded = 4;
                                                                                    
                                                                                    hti = m_wndTree.InsertItem( _T("Item 3"), htiItemsWithIcons, NULL );
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexCollapsed = 5;
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexExpanded = 5;
                                                                                    
                                                                                    hti = m_wndTree.InsertItem( _T("Item 4"), htiItemsWithIcons, NULL );
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexCollapsed = 6;
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexExpanded = 6;
                                                                                    
                                                                                    hti = m_wndTree.InsertItem( _T("Item 5"), htiItemsWithIcons, NULL );
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexCollapsed = 7;
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexExpanded = 7;
                                                                                    
                                                                                    hti = m_wndTree.InsertItem( _T("Item 6 (disabled)"), htiItemsWithIcons, NULL );
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexCollapsed = 8;
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexExpanded = 8;
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_bDisabled = true;
                                                                                    
                                                                                    hti = m_wndTree.InsertItem( _T("Item 7"), htiItemsWithIcons, NULL );
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexCollapsed = 8;
                                                                                    m_wndTree.TreeItemInfoGet( hti ).m_nIconIndexExpanded = 8;

Dave Calkins Dec 17, 2009 - 12:27 PM

I noticed that if I set a breakpoint on CExtTreeCtrl::OnPaint that the breakpoint never gets called. If I set a breakpoint on CExtTreeCtrl::TreeIconAdd, it does get called (so the breakpoints are being properly set).

So now I suspect the rendering is just using the base CTreeCtrl which might be why we’re not getting images. We’re creating the tree control dynamically at runtime using the below code (as opposed to a dialog resource like in your example).

Is there something special we need to do to get the CExtTreeControl to take over and do its own rendering?


BOOL COurTree::CreateTreeCtrl(CExtTabPageContainerWnd& tabsContainer)
{
    m_pTabsContainer = &tabsContainer;

    if( !this->Create(
        WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|WS_TABSTOP
        |TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT
        |TVS_INFOTIP
        |TVS_SHOWSELALWAYS|TVS_TRACKSELECT,
        CRect(0,0,0,0),
        m_pTabsContainer,
        UINT(IDC_STATIC)
        )
        )
    {
        TRACE0("Failed to create TreeCtrl\n");
        return FALSE;        // fail to create
    }

Note that COurTree class is created as follows.

class COurTree : public CExtWFF<CExtTreeCtrl>, public OurTreeBase {}

Dave Calkins Dec 17, 2009 - 12:32 PM

I think I found the problem. If I remove the CExtWFF<> from the class derivation (just derive from CExtTreeCtrl) the images work.

I believe we added the CExtWFF<> in there to have flicker free scrolling through the tree. What alternative should we now use with CExtTreeCtrl?

Technical Support Dec 18, 2009 - 11:12 AM

The CExtWFF template class can remove flicker effects from standard common controls. It just implements double-buffered painting. Most of the Prof-UIS controls does not need assistance of this template class. Most of the Prof-UIS controls have their own flicker free painting code. I.e. you can make the MFC’s tree control non-flickering by using CExtWFF < CTreeCtrl > type. But the CExtTreeCtrl does not require the CExtWFF template class.

Technical Support Dec 18, 2009 - 11:12 AM

The CExtWFF template class can remove flicker effects from standard common controls. It just implements double-buffered painting. Most of the Prof-UIS controls does not need assistance of this template class. Most of the Prof-UIS controls have their own flicker free painting code. I.e. you can make the MFC’s tree control non-flickering by using CExtWFF < CTreeCtrl > type. But the CExtTreeCtrl does not require the CExtWFF template class.

Dave Calkins Dec 17, 2009 - 9:11 AM

Your sample ProfUIS_Controls project does not appear to call TreeIconInsert. I can’t find any sample code which calls TreeIconInsert. I can see in that sample where its setting up the icons for each item, but not where they’re being added to the tree.

Dave Calkins Dec 17, 2009 - 9:19 AM

I see you’re doing TreeIconAdd instead; I switched to that, but still no icons in the tree.

Dave Calkins Dec 17, 2009 - 7:30 AM

I’m adding tree items after the window is initialized.  I’m adding an item and then need to set its icon after the fact.  I also have cases where I need to change the icon of an existing tree item.


 


Your example code just involves setting a variable in the item info structure.  This doesn’t seem sufficient to get the tree control to re-draw that item with the new icon.   Is there some other call I need to tell the tree control to update that item and use the modified info structure?

Dave Calkins Dec 14, 2009 - 3:56 PM

I made the change you suggested, but I’m still not seeing any icons in the tree.  Is there some style I need to set or flag to enable use of the images?


Also, the code you provided just sets a member variable in the TREEITEMINFO structure.  Shouldn’t there be another call to cause the tree to take notice of the change and use the new value?


 

Technical Support Dec 14, 2009 - 9:28 AM

Please remove the CTreeCtrl::SetItemImage() method invocation and use the following code instead:

CExtTreeCtrl & wndTree = . . .
INT nImageIndex = . . .
HTREEITEM hti = . . .
CExtTreeCtrl::TREEITEMINFO_t & _TII =  wndTree.TreeItemInfoGet( hti );
            _TII.m_nIconIndexCollapsed = _TII.m_nIconIndexExpanded = nImageIndex;


Dave Calkins Dec 14, 2009 - 8:35 PM

There must be some missing information here.  Do you have a sample illustrating how to use CExtTreeCtrl with images for the items?  I can’t get images in my tree.

Dave Calkins Dec 14, 2009 - 3:57 PM

I made the change you suggested, but I’m still not seeing any icons in the tree.  Is there some style I need to set or flag to enable use of the images?


 


Also, the code you provided just sets a member variable in the TREEITEMINFO structure.  Shouldn’t there be another call to cause the tree to take notice of the change and use the new value?