Click here to Skip to main content
Click here to Skip to main content
Go to top

TreeCtrl - A WTL tree control with Windows Vista style item selection

, 9 Apr 2006
Rate this:
Please Sign up or sign in to vote.
A WTL tree control that supports Windows Vista style selection and multiple selection.

Introduction

After quite a few requests, I thought I'd post this tree control that uses a similar selection drawing style to the list control I posted here: ListCtrl - A WTL list control with Windows Vista style item selection. For an added bonus, I've also included support for multiple-selection.

How to use CTreeCtrl

Simply use the tree control as you would the normal CTreeViewCtrl, however there are a couple of functions required to activate and retrieve multiple selections:

void ShowThemed( 
    BOOL bShowThemed = TRUE
)

Description

Draw item selection themed.

Parameters

  • bShowThemed - TRUE = Draw themed selection; FALSE = Classic mode.
void SetMultipleSelect( 
       BOOL bMultipleSelect
)

Description

Turns on/off multiple selection.

Parameters

  • bMultipleSelect - TRUE = Turn on multiple select.
void GetSelectedItems( 
    CSimpleArray < HTREEITEM >& aSelectedItems
)

Description

Retrieves a list of selected tree items.

Parameters

  • aSelectedItems - Reference to an array of HTREEITEM.

Finally

Any comments or suggestions are welcome.

History

  • 16th March, 2006: 1.0
    • First release.
  • 20th March, 2006: 1.1
    • Small bug fix for VS2005.
  • 5th April, 2006: 1.2
    • Corrected problems with multiple select and checkboxes - many thanks to Phil C.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

AlanW

United Kingdom United Kingdom
Alan has been developing applications for a very long time (~10 years), but he's not bitter about this at all. My main area of expertise is C++. He lives in Sweden with his beautiful wife, daughter and son and enjoys climbing mountains and kayaking in his spare time (which isn't much).

Comments and Discussions

 
GeneralFixes for keeping selection when clicking expand and collapse and setting background color PinmemberJ Chris Davies19-Apr-06 7:44 
Looks good and I like the approach -
 
Couple of fixes here -
Override SetBkColor to allow non-white background. Maybe a better way to handle background color (and text color) is by getting and setting the treeviews colors through TVM_GETBKCOLOR etc.
 
Fixed clicking on expand buttons so it doesn't affect the current selection.
 
Also just FYI - I got this working on 7.1 by copying out the relavent classes from ATL 7.5 (CDoubleBuffer, CMemoryDC and CLogFont)
 

COLORREF SetBkColor(COLORREF bk)
{
m_rgbBackground = bk;
return CWindowImpl< CTreeCtrl, CTreeViewCtrl >::SetBkColor(bk);
}
 
void OnLButtonDown( UINT nFlags, CPoint point )
{
if ( m_bMultipleSelect )
{
// reset selected item if click on a single item
UINT flags = 0;
HTREEITEM hNewItem = HitTest( point, &flags );
if (flags & TVHT_ONITEMBUTTON)
{
SetMsgHandled( FALSE );
return;
}
 
m_bCtrlKey = ( ( GetKeyState( VK_CONTROL ) & 0x8000 ) != 0 );
m_bShiftKey = ( ( GetKeyState( VK_SHIFT ) & 0x8000 ) != 0 );

if ( m_bCtrlKey || m_bShiftKey )
return;

if ( hNewItem != NULL )
{
UINT nNewSelectState = ( GetItemState( hNewItem, TVIS_SELECTED ) & TVIS_SELECTED );
ResetSelected( GetRootItem() );
SetItemState( hNewItem, nNewSelectState, TVIS_SELECTED );
m_hFirstSelected = hNewItem;
}
}

SetMsgHandled( FALSE );
}
 
void OnLButtonUp( UINT nFlags, CPoint point )
{
SetMsgHandled( FALSE );

if ( !m_bMultipleSelect )
return;
 
UINT flags = 0;
HTREEITEM hNewItem = HitTest( point, &flags );
if (flags & TVHT_ONITEMBUTTON)
return;
 
HTREEITEM hOldItem = GetSelectedItem();

if ( m_bCtrlKey )
{
if ( hNewItem != NULL )
{
UINT nNewSelectState = GetItemState( hNewItem, TVIS_SELECTED ) & TVIS_SELECTED ? 0 : TVIS_SELECTED;
UINT nOldSelectState = hOldItem == NULL ? 0 : GetItemState( hOldItem, TVIS_SELECTED );

// select new item (to get focus)
SelectItem( hNewItem );

// set highlight state for new item
if ( GetItemState( hNewItem, TVIS_SELECTED ) != nNewSelectState )
SetItemState( hNewItem, nNewSelectState, TVIS_SELECTED );

// restore state of old selected item
if ( hOldItem != NULL && hOldItem != hNewItem && GetItemState( hOldItem, TVIS_SELECTED ) != nOldSelectState )
SetItemState( hOldItem, nOldSelectState, TVIS_SELECTED );

m_hFirstSelected = NULL;
}
}
else if ( m_bShiftKey )
{
// initialise the reference item if this is the first shift selection
if ( m_hFirstSelected == NULL )
m_hFirstSelected = GetSelectedItem();

// select new item (to get focus)
if ( hOldItem == hNewItem )
SelectItem( NULL ); // to prevent edit
 
if ( m_hFirstSelected != NULL )
SelectItems( m_hFirstSelected, hNewItem );
}

m_bCtrlKey = FALSE;
m_bShiftKey = FALSE;
}

 

 
Chris Davies

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140916.1 | Last Updated 10 Apr 2006
Article Copyright 2006 by AlanW
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid