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 » Question and bug in Tree View page in Prof-UIS Controls 2.89 Collapse All
Subject Author Date
Therese P May 26, 2010 - 7:53 AM

Good morning,



this is a 2-part post on tree view.



PART 1

I am looking to use the tree view to allow users to navigate throught the application.

Specifications are:

- tree boxes buttons to be displayed (that one is covered)

- one click on the label expands/collapses the tree (not double click)

- only sub levels can have icons: main root does not have icons and if possible, the text is right next to the tree boxe button

- if more than one sub level is expanded, the previous sub levels stay expanded (not collapse the previous and expand the current)





PART 2

So I went to see my options in the sample Prof-UIS Controls 2.89. In the tree view page, I checked the "Single expand" box. I single-click on the label in the tree to expand it: the sub level opens but closes as soon as the click button is released. Should that be the correct behaviour?



Thank you


 

Therese P May 26, 2010 - 1:16 PM

Hi,


thanks for the quick reply and fix. However, there is still a little glitch. When I open the tree view page in the Pro-UIS Cotrols, the tree is complitely extended. If I click "Single expand" and go and single-click on the label, the original problem happens. But if you click again on the same label, the correct behaviour happens. This happens for any label that has not been clicked on yet.


As for part 3, sorry I was not clear. I meant to change the text size of the label (not the label size). I want the text in my tree to be bigger than the default used in the rest of the application.


Thanks again!

Technical Support May 26, 2010 - 12:14 PM

PART 1: The CExtTreeCtrl control is close to what you need:

- tree boxes buttons to be displayed (that one is covered)
The TVS_HASBUTTONS style displays the tree boxes. You can also use the CExtTreeCtrl::HasButtonsSet() method.

- one click on the label expands/collapses the tree (not double click)
The TVS_SINGLEEXPAND style provides the single expanded behavior. You can also use the CExtTreeCtrl::SingleExpandSet() method.

- only sub levels can have icons: main root does not have icons and if possible, the text is right next to the tree box button
The CExtTreeCtrl control supports per-item independent features: icons, check boxes, radio buttons, disabled state, selected state, attached controls.
You can see this in the ProfUIS_Controls sample application.

- if more than one sub level is expanded, the previous sub levels stay expanded (not collapse the previous and expand the current)
This is non-standard behavior. But you can implement it without TVS_SINGLEEXPAND style. Just override the CExtTreeCtrl::OnTreeMouseClick() virtual method and expand non-expanded items on single click.

PART 2:The single expanding behavior of the CExtTreeCtrl control in the ProfUIS_Controls sample application is an issue. Thank you for reporting it. To fix it please update the source code for the following two methods:

 void CExtTreeCtrl::FocusItem(
            HTREEITEM hti,
            bool bSelect, // = false
            bool bUnselectOtherItems, // = false
            bool bMouseClickEvent // = false
            )
{
            ASSERT_VALID( this );
            bMouseClickEvent;
HTREEITEM htiOldFocus = GetNextItem( NULL, TVGN_CARET );
bool bActuallyFocusChanged = ( htiOldFocus == hti ) ? false : true;
            if( hti == NULL )
                        return;
bool bAnyUnSelected = false;
            if( bUnselectOtherItems )
            {
                        HTREEITEM htiWalk = NULL;
                        POSITION pos = m_mapItemInfo.GetStartPosition();
                        for( ; pos != NULL; )
                        {
                                    TREEITEMINFO_t * pTII = NULL;
                                    m_mapItemInfo.GetNextAssoc( pos, htiWalk, pTII );
                                    if( htiWalk == hti || pTII == NULL )
                                                continue;
                                    pTII->m_bSelected = false;
                                    bAnyUnSelected = true;
                        }
            }
            if( bSelect )
                        SelectItem( hti, true );
            if( bActuallyFocusChanged )
            {
                        CTreeCtrl::SelectItem( hti );
                        if( bSelect)
                                    SelectItem( hti, true, false );
            }
            if( bActuallyFocusChanged || bSelect || bAnyUnSelected )
                        CExtTreeCtrl::Invalidate();
            if( bActuallyFocusChanged )
                        OnTreeItemDelayedFocus( hti, true, bMouseClickEvent );
            if(                     bMouseClickEvent
                        &&        htiOldFocus != hti
                        &&        ( GetStyle() & TVS_SINGLEEXPAND ) != 0
                        &&        (! TreeItemIsExpanded( hti ) )
                        )
                        Expand( hti, TVE_EXPAND );
}

bool CExtTreeCtrl::OnTreeMouseClick(
            HTREEITEM hti,
            DWORD dwHitTestFlags,
            int nMouseButton,
            int nClick,
            UINT nMouseEventFlags,
            CPoint point
            )
{
            ASSERT_VALID( this );
            if( hti == NULL )
                        return false;

            if(                     ( nMouseButton == VK_LBUTTON || nMouseButton == VK_RBUTTON )
                        &&        ( nClick == 0 || nClick == 2 )
                        )
            {
                        HWND hWndParent = ::GetParent( m_hWnd );
                        UINT nOwnID = UINT( GetDlgCtrlID() );
                        NM_TREEVIEW _data;
                        ::memset( &_data, 0, sizeof(NM_TREEVIEW) );
                        _data.hdr.hwndFrom = m_hWnd;
                        _data.hdr.idFrom = nOwnID;
                        _data.hdr.code =
                                    ( nMouseButton == VK_LBUTTON )
                                                ? ( nClick == 0 ? NM_CLICK : NM_DBLCLK )
                                                : ( nClick == 0 ? NM_RCLICK : NM_RDBLCLK )
                                                ;
                        _data.action = 0;
                        _data.itemOld.mask = TVIF_CHILDREN|TVIF_HANDLE|TVIF_PARAM|TVIF_STATE;
                        _data.itemOld.hItem = hti;
                        GetItem( &_data.itemOld );
                        CExtSafeString strItemText = GetItemText( hti );
                        _data.itemOld.cchTextMax = INT(strItemText.GetLength());
                        _data.itemOld.pszText = strItemText.IsEmpty() ? _T("") : LPTSTR(LPCTSTR(strItemText));
                        _data.itemOld.mask |= TVIF_TEXT;
                        ::memcpy( &_data.itemNew, &_data.itemOld, sizeof(TVITEM) );
                        _data.ptDrag.x = point.x;
                        _data.ptDrag.y = point.y;
                        if( ::SendMessage( hWndParent, WM_NOTIFY, WPARAM(nOwnID), LPARAM(&_data) ) != 0 )
                                    return true;
            }

DWORD dwTreeStyle = TreeGetStyle();
bool bMultiSelection       = ( ( dwTreeStyle & __EXT_TREE_MULTIPLE_SELECTION ) != 0 ) ? true : false;
bool bSelectDisabledItems  = ( ( dwTreeStyle & __EXT_TREE_SELECT_DISABLE_ITEMS ) != 0 ) ? true : false;
bool bFocusDisabledItems   = ( ( dwTreeStyle & __EXT_TREE_FOCUS_DISABLE_ITEMS ) != 0 ) ? true : false;
bool bSelectCollapsedItems = ( ( dwTreeStyle & __EXT_TREE_SELECT_COLLAPSED_ITEMS ) != 0 ) ? true : false;
bool bSubtractSelection    = ( ( dwTreeStyle & __EXT_TREE_SUBTRACT_SELECTION ) != 0 ) ? true : false;
bool bSingleExpand         = ( ( GetStyle() & TVS_SINGLEEXPAND ) != 0 ) ? true : false;
bool bEditLabels                          = ( ( GetStyle() & TVS_EDITLABELS ) != 0 ) ? true : false;
bool bItemIsEnabled        = OnQueryItemEnabledState( hti );
            switch( nMouseButton )
            {
            case VK_LBUTTON:
            {
                        static HTREEITEM g_htiLastLButtonDownItem = NULL;
                        switch( nClick )
                        {
                        case 0:
                                    g_htiLastLButtonDownItem = hti;
                                    // continue falling after drag detection ...
                        case 1:
                        {
                                    if( ::GetFocus() != m_hWnd )
                                                SetFocus();
                                    if( g_htiLastLButtonDownItem != hti )
                                                return true;
                                    if( ( dwHitTestFlags & __EXT_TVHT_ONCONTROL ) != 0 )
                                    {
                                                CRect rcControl;
                                                VERIFY( TreeItemRectGet( hti, rcControl, e_tirt_control ) );
                                                ASSERT( ! rcControl.IsRectEmpty() );
                                                if( m_hWndChildControl != NULL )
                                                {
                                                            CRect rc;
                                                            ::GetWindowRect( m_hWndChildControl, &rc );
                                                            if( rc == rcControl )
                                                                        return true;
                                                            SendMessage( WM_CANCELMODE );
                                                }
                                                m_hWndChildControl = OnInplaceControlCreate( hti, rcControl );
                                                if( m_hWndChildControl != NULL )
                                                            m_htiInplaceEdited = hti;
                                                return true;
                                    }
                                    if( ( dwHitTestFlags & __EXT_TVHT_ONITEMBUTTON ) != 0 )
                                    {
                                                if( nClick != 0 )
                                                            return true;
                                                HTREEITEM htiFocus = GetFocusedItem();
                                                if( htiFocus != NULL )
                                                {
                                                            if(                     TreeItemIsExpanded( hti )
                                                                        &&        HasAncestor( hti, htiFocus )
                                                                        )
                                                            {
                                                                        if(                     ( ! bFocusDisabledItems )
                                                                                    &&        ( ! bItemIsEnabled )
                                                                                    )
                                                                                    FocusItem( NULL, false, false );
                                                                        else
                                                                                    FocusItem( hti, bSelectDisabledItems || bItemIsEnabled, true );
                                                            }
                                                }
                                                SendMessage( WM_CANCELMODE );
                                                Expand( hti, TVE_TOGGLE );
                                                Invalidate();
                                                return true;
                                    }
                                    DWORD dwSelectionAreaFlags =
                                                __EXT_TVHT_ONITEMICON|__EXT_TVHT_ONITEMLABEL
                                                |__EXT_TVHT_ONCONTROL|__EXT_TVHT_ONCHECKBOX;
                                    bool bFullRowSelection = ( ( GetStyle() & TVS_FULLROWSELECT ) != 0 ) ? true : false;
                                    if( bFullRowSelection )
                                                dwSelectionAreaFlags |= __EXT_TVHT_ONITEMINDENT|__EXT_TVHT_ONITEMRIGHT;
                                    static HTREEITEM stat_htiLastZeroFocusItem = NULL;
                                    if(                     ( dwHitTestFlags & dwSelectionAreaFlags ) != 0
                                                &&        ( bFocusDisabledItems || bItemIsEnabled )
                                                )
                                    {
                                                TREEITEMINFO_t & _TII = TreeItemInfoGet( hti );
                                                
                                                if(                     bEditLabels
                                                            &&        ( hti != stat_htiLastZeroFocusItem && hti == GetFocusedItem() )
                                                            &&        (           bFullRowSelection
                                                                        ||           ( dwHitTestFlags & __EXT_TVHT_ONITEMLABEL ) != 0
                                                                        )
                                                            )
                                                {
                                                            if( nClick != 0 )
                                                                        stat_htiLastZeroFocusItem = NULL;
                                                            if( nClick != 1 )
                                                                        return true;
                                                            if(                     (           m_hWndChildControl == NULL
                                                                                    ||           ( ! ::IsWindow( m_hWndChildControl ) )
                                                                                    )
                                                                        &&        ::GetFocus() == m_hWnd
                                                                        &&        m_nLastMouseButtonEventType[0] == 0 // if WM_LBUTTONUP after WM_LBUTTONDOWN, i.e. if not after WM_LBUTTONDBLCLK
                                                                        )
                                                            {
                                                                        KillTimer( m_nDelayedEditingTimerID );
                                                                        m_wndContentExpand.Deactivate();
                                                                        SetTimer( m_nDelayedEditingTimerID, ::GetDoubleClickTime() + 1 , NULL );
                                                            }
                                                            return true;
                                                }
                                                if( ( dwHitTestFlags & m_dwCheckBoxAreaFlags ) != 0 && OnQueryItemEnabledState( hti ) )
                                                {
                                                            if( nClick == 1 )
                                                            {
                                                                        switch( _TII.m_eCheckBoxType )
                                                                        {
                                                                        case e_cbt_check_box:
                                                                                    switch( _TII.m_nCheckBoxState )
                                                                                    {
                                                                                    case 0:
                                                                                                _TII.m_nCheckBoxState = 1;
                                                                                                break;
                                                                                    case 1:
                                                                                                _TII.m_nCheckBoxState = 0;
                                                                                                break;
                                                                                    }
                                                                        break;
                                                                        case e_cbt_tri_state_check_box:
                                                                                    switch( _TII.m_nCheckBoxState )
                                                                                    {
                                                                                    case 0:
                                                                                                _TII.m_nCheckBoxState = 1;
                                                                                                break;
                                                                                    case 1:
                                                                                                _TII.m_nCheckBoxState = 2;
                                                                                                break;
                                                                                    case 2:
                                                                                                _TII.m_nCheckBoxState = 0;
                                                                                                break;
                                                                                    }
                                                                        break;
                                                                        case e_cbt_radio:
                                                                                    _CheckRadioBox( hti );
                                                                        break;
                                                                        } // switch( _TII.m_eCheckBoxType )
                                                            }
                                                } // if( ( dwHitTestFlags & m_dwCheckBoxAreaFlags ) != 0 && OnQueryItemEnabledState( hti ) )

                                                HTREEITEM htiFocus = GetFocusedItem();
                                                if(                     bSingleExpand
                                                            &&        nClick == 0
                                                            &&        htiFocus == hti
                                                            &&        ( nMouseEventFlags & (MK_CONTROL|MK_SHIFT) ) == 0
                                                            )
                                                {
                                                            SendMessage( WM_CANCELMODE );
                                                            Expand( hti, TVE_TOGGLE );
                                                            Invalidate();
                                                            if( nClick != 0 )
                                                                        stat_htiLastZeroFocusItem = NULL;
                                                            return true;
                                                }
                                                bool bSelectFocusedFinally = true;
                                                if(                     bSubtractSelection
                                                            &&        ( nMouseEventFlags & (MK_CONTROL|MK_SHIFT) ) == MK_CONTROL
                                                            )
                                                {
                                                            if( nClick == 1 )
                                                            {
                                                                        AnchorItemSet( hti );
                                                                        
                                                                        SendMessage( WM_CANCELMODE );
                                                                        bool bSelectThisItem = false, bUnselectOtherItems = false;
                                                                        if( ( TreeGetStyle() & __EXT_TREE_MULTIPLE_SELECTION ) != 0 )
                                                                        {
                                                                                    FocusItem( hti, bSelectThisItem, bUnselectOtherItems );
                                                                                    //if( bSelectDisabledItems || bItemIsEnabled )
                                                                                                SelectItem( hti, !IsItemSelected( hti ), IsItemSelected( hti ) );
                                                                        }
                                                                        else
                                                                        {
                                                                                    bSelectThisItem = bUnselectOtherItems = true;
                                                                                    FocusItem( hti, bSelectThisItem, bUnselectOtherItems );
                                                                        }
                                                                        
                                                                        Invalidate();
                                                                        if( m_wndContentExpand.GetSafeHwnd() != NULL )
                                                                                    m_wndContentExpand.Invalidate();
                                                            }
                                                            if( nClick != 0 )
                                                                        stat_htiLastZeroFocusItem = NULL;
                                                            return true;
                                                }

                                                HTREEITEM htiAnchor = AnchorItemGet();
                                                if( ( nMouseEventFlags & (MK_CONTROL|MK_SHIFT) ) != MK_SHIFT )
                                                            AnchorItemSet( hti );
                                                
                                                if( htiFocus != NULL )
                                                {
                                                            if(                     bMultiSelection
                                                                        &&        ( nMouseEventFlags & MK_SHIFT ) == MK_SHIFT
                                                                        )
                                                            {
                                                                        if( bSubtractSelection && htiAnchor != NULL )
                                                                                    SelectItemRange( htiAnchor, htiFocus, false, !bSelectCollapsedItems, bSelectDisabledItems );
                                                                        SelectItemRange( hti, htiAnchor, true, !bSelectCollapsedItems, bSelectDisabledItems );
                                                            }
                                                }
                                                bool bUnselectOtherItems =
                                                            (
                                                                        ( ! bMultiSelection )
                                                            ||           ( ( nMouseEventFlags & (MK_CONTROL|MK_SHIFT) ) == 0 )
                                                            )
                                                            ? true : false;
                                                SendMessage( WM_CANCELMODE );
                                                if( ( ! bSelectDisabledItems ) && ( ! bItemIsEnabled ) )
                                                            bSelectFocusedFinally = false;
                                                if( ! bSelectFocusedFinally )
                                                            SelectItem( hti, false );
                                                if( nClick == 0 )
                                                            stat_htiLastZeroFocusItem = hti;
                                                else
                                                            stat_htiLastZeroFocusItem = NULL;
                                                FocusItem( hti, bSelectFocusedFinally, bUnselectOtherItems, true );
                                                Invalidate();
                                                if( m_wndContentExpand.GetSafeHwnd() != NULL )
                                                            m_wndContentExpand.Invalidate();
                                                if( nClick == 0 && OnTreeItemDoDragDetect( hti, dwHitTestFlags, nMouseButton, nClick, nMouseEventFlags, point ) )
                                                {
                                                            g_htiLastLButtonDownItem = NULL;
                                                            return true;
                                                }
                                                return true;
                                    }
                                    if( nClick != 0 )
                                                stat_htiLastZeroFocusItem = NULL;
                        }
                        break;
                        case 2:
                                    g_htiLastLButtonDownItem = NULL;
                                    if(                     ( dwHitTestFlags & (__EXT_TVHT_ONITEMICON|__EXT_TVHT_ONITEMLABEL) ) != 0
                                                &&        ( bFocusDisabledItems || bItemIsEnabled )
                                                &&        ! bSingleExpand
                                                )
                                    {
                                                if( ::GetFocus() != m_hWnd )
                                                            SetFocus();
                                                SendMessage( WM_CANCELMODE );
                                                if( ItemHasChildren( hti ) )
                                                            Expand( hti, TVE_TOGGLE );

                                                Invalidate();
                                                return true;
                                    }
                        break;
                        } // switch( nClick )
            }
            return true; // case VK_LBUTTON
            case VK_RBUTTON:
            {
                        if( ::GetFocus() != m_hWnd )
                                    SetFocus();
                        switch( nClick )
                        {
                        case 0:
                                    if( OnTreeItemDoDragDetect( hti, dwHitTestFlags, nMouseButton, nClick, nMouseEventFlags, point ) )
                                                return true;
                        //break;
                                    // continue falling after drag detection ...
                        case 1:
                        {
                                    CPoint ptScreen = point;
                                    ClientToScreen( &ptScreen );
                                    SendMessage( WM_CONTEXTMENU, WPARAM(m_hWnd), MAKELPARAM(ptScreen.x,ptScreen.y) );
                        }
                        return true;
                        } // switch( nClick )
            }
            break; // case VK_RBUTTON
            default:
                        switch( nClick )
                        {
                        case 0:
                                    if( OnTreeItemDoDragDetect( hti, dwHitTestFlags, nMouseButton, nClick, nMouseEventFlags, point ) )
                                                return true;
                        //break;
                                    // continue falling after drag detection ...
                        } // switch( nClick )
            break;
            } // switch( nMouseButton )
            return true;
}


PART 3: The size of the label text is controlled by the measured size of its text. You should add space characters to the end of the label text to make it wider.


Technical Support May 27, 2010 - 10:05 AM

The single expanding feature assumes all the tree branches are initially collapsed. Only some one branch can be initially expanded. If you collapse all the tree branches before turning on the single expanding feature, then you will see it works OK.

The CExtTreeCtrl control is the repainted and improved version of the CTreeCtrl control. But CExtTreeCtrl control uses layout and HTREEITEM handle based tree data structure of the CTreeCtrl control. Very unfortunately, the CTreeCtrl control does not allow to re-measure its items. So, you can only insert a longer text and paint some smaller text over it.

Therese P May 26, 2010 - 8:01 AM

Also I would like to set the size of the label text.


Thank you