Click here to Skip to main content
13,558,021 members
Click here to Skip to main content
Add your own
alternative version


89 bookmarked
Posted 20 Jul 2005

Full-Featured Tree Control

, 25 Jul 2005
Rate this:
Please Sign up or sign in to vote.
Implementation of a reusable tree control with many features.

Select multiple items by tracking a rubber band rectangle.

Drag and drop multiple items at once.

Customizable context menu.


As I was looking for a more advanced tree control, I came across the article Tree Editor by Yossi Patt. The tree control in this article seemed to have most of the features I had need for. Unfortunately this tree control was nearly unusable outside its demo application. I tried to adapt the tree control to suit my needs, but gave up after one day. It would take too much effort for me to get it to work. In lack of an alternative, I decided to create my own full featured tree control. This class should be as independent as possible to get it work in many projects.

The result, I'm reasonably satisfied with, I put here on CodeProject for all people who are interested. Strictly speaking, this article consists of a small class hierarchy. CEditTreeCtrl implements the base functionality and extents CTreeCtrl by the following capabilities:

  • insert items with a keystroke.
  • delete items with a keystroke.
  • edit items with a keystroke.
  • drag and drop (drop 'above', 'below' or 'as child').
  • drag and drop with right mouse button (drop context menu).
  • sort levels or entire subtrees.
  • context menu for most functions.

The class is highly customizable by inheritance. Nearly all methods are virtual. For instance, it is very simple to generally allow renaming of items, but forbid renaming of specific items. The same applies to insertion of new items, deletion and drag and drop operations.

The class CEditTreeCtrlEx extends the class CEditTreeCtrl by the ability of multiple selections of items as well as drag and drop of these selections. CEditTreeCtrlEx might also be used as an example of how to derive a class from CEditTreeCtrl to extend its capabilities by overriding some of its virtual methods.


I used code and ideas found in other articles at CodeProject. Many thanks go to:

Using the code


Usage is really simple: add all files from the source archive to your own project(s). After having done this, you may use CEditTreeCtrl and/or CEditTreeCtrlEx as a replacement of CTreeCtrl. For fine tuning, derive your own class and override methods to suit your needs.

In most cases it should be enough to override some of the 'permission'-methods to restrict the functionality to specific items. To prevent moving or copying specific items for instance, you override the method:

virtual bool    CanDragItem(TVITEM & item);

This might be implemented as follows:

// If derived from CEditTreeCtrl:
bool CMyOwnTreeCtrl::CanDragItem(TVITEM & item) {
    return (DWORD(item.lParam) == 666) ? false : true;

// If derived from CEditTreeCtrlEx:
// Have to take care about multiple selections.
// The one given as argument is the one item that has the focus.
bool CMyOwnTreeCtrl::CanDragItem(TVITEM &) {
    // iterate selected items
    for(HTREEITEM hItem = GetFirstSelectedItem(); hItem; 
                     hItem = GetNextSelectedItem(hItem))
        if(GetItemData(hItem) == 666)
            // At least one item that we must not drag
            return false;
    return true;

Multi Select

Generally you have to bear in mind, that CEditTreeCtrlEx will only take care of selected items that are currently visible or 'might be' visible. This means that selected items laying in collapsed subtrees will be ignored!

Multi select can be switched on or off by the method.

void CEditTreeCtrlEx::EnableMultiSelect(bool bEnable = true);

Whether or not multi select is enabled can be obtained by:

bool CEditTreeCtrlEx::IsMultiSelectEnabled() const;

Note that multi select is ON by default. If it is ON, every call to CTreeCtrl::SelectItem() will add an item to the list of currently selected items! Code of the form:

HTREEITEM hItem = GetRootItem();
hItem = GetNextSiblingItem(hItem);
    // 2 items should be selected
    ASSERT(GetSelectedCount() == 2);
    // only one item should be selected
    ASSERT(GetSelectedCount() == 1);

leads to two selected items if multi select is ON. The latest selected item has the focus. If multi select is switched off, only the user is unable to select more than one item, either by using the mouse or the keyboard. The programmer might use:

void CEditTreeCtrlEx::SelectItems(HTREEITEM hFrom, HTREEITEM hTo);
void CEditTreeCtrlEx::SelectAll();

to select more than one item, even if multi select is off.

You can use:

HTREEITEM CEditTreeCtrlEx::GetFirstSelectedItem() const;
HTREEITEM CEditTreeCtrlEx::GetNextSelectedItem(HTREEITEM hItem) const;
HTREEITEM CEditTreeCtrlEx::GetPrevSelectedItem(HTREEITEM hItem) const;

to iterate the selected items. The method:

HTREEITEM CTreeCtrl::GetSelectedItem() const;

works without a difference. It obtains the item with the focus as long as it is selected, too.

Selections might be reset with the use of these methods:

void CEditTreeCtrlEx::ClearSelection(HTREEITEM Except = 0);
void CEditTreeCtrlEx::DeselectItem(HTREEITEM hItem);

To remove all selections except the one that has currently the focus, you can use:


Points of Interest

To keep using the sources as simple as possible, the needed resources (cursors) are not included as resources. Instead, they are described in a separate header file CursorDef.h. If you don't like to use these cursors, feel free to define your own, put them to your project's resource and override the CreateCursorMap() method. Note that this method is only called once per session. All objects will use the same cursors.

There are two ways to customize the context menu. First you can override the method DisplayContextMenu() to provide a completely different menu. The other way is to override ExtendContextMenu(CMenu &) to add more functionality to the default menu. The class CEditTreeCtrlEx uses the second way to extend the menu by the items Select All and Select None.

The definition of the keyboard settings is stored in the member variable m_Keymap. This member appears as a three-dimensional array. The first index describes the key to act on, the second index is an indicator for the control-key, and the third index is an indicator for the shift-key. Assign a method of your derived class to the defined key. The method needs to have the following signature:

bool method(HTREEITEM);

Normally the method gets as a parameter the item on which the method should be used on. A function that erases the entire tree by a keystroke could be implemented as follows:

class CMyOwnTreeCtrl : public CEditTreeCtrl {
        virtual bool DoEraseTree(HTREEITEM);

CMyOwnTreeCtrl::CMyOwnTreeCtrl() {
    // Extend the keymap:
    // Ctrl+DEL shall erase the entire tree
    m_Keymap[VK_DELETE][true][false] = 

bool CMyOwnTreeCtrl::DoEraseTree(HTREEITEM) {
    return DeleteAllItems() != FALSE;


  • July, 18 2005 - first implementation.
  • July, 22 2005
    • Bug fixed in OnBegindrag() and OnBeginrdrag().
    • Bug fixed in HandleKeyDown() (don't handle keys while in label edit mode).


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

You may also be interested in...


Comments and Discussions

PraiseIt worked for what I needed Pin
Member 1261064329-Jun-16 10:10
memberMember 1261064329-Jun-16 10:10 
Generalwell done ! Pin
Koma Wang20-Oct-10 21:01
memberKoma Wang20-Oct-10 21:01 
GeneralRClick management Pin
Pancini Paolo13-Oct-10 22:33
memberPancini Paolo13-Oct-10 22:33 
GeneralMultiple selection of items does not work in windows7 Pin
redo8-Jun-10 22:45
memberredo8-Jun-10 22:45 
GeneralRe: Multiple selection of items does not work in windows7 Pin
stonexin13-Aug-12 17:30
memberstonexin13-Aug-12 17:30 
GeneralRe: Multiple selection of items does not work in windows7 Pin
stonexin14-Aug-12 0:03
memberstonexin14-Aug-12 0:03 
GeneralThank you! Pin
Cristina Cotoranu23-Oct-09 0:12
memberCristina Cotoranu23-Oct-09 0:12 
GeneralAdvice.. Pin
Gabor Bernat18-Feb-08 2:37
memberGabor Bernat18-Feb-08 2:37 
QuestionHow can I use this control in CTreeView? [modified] Pin
KFC12323-Mar-07 6:26
memberKFC12323-Mar-07 6:26 
GeneralWeb Tree Ctr Pin
Jian123456714-Nov-06 3:02
memberJian123456714-Nov-06 3:02 
Do you know how easily to use your tree ctr in web page?

GeneralOnInitDialog() - item selection Pin
Andy H20-Jul-06 6:55
memberAndy H20-Jul-06 6:55 
GeneralRootitem color?! Pin
break;17-May-06 5:06
memberbreak;17-May-06 5:06 
GeneralRe: Rootitem color?! Pin
Joerg Koenig17-May-06 22:21
memberJoerg Koenig17-May-06 22:21 
GeneralRe: Rootitem color?! Pin
break;18-May-06 23:18
memberbreak;18-May-06 23:18 
GeneralNice control,but... Pin
ucc8012-Feb-06 14:58
memberucc8012-Feb-06 14:58 
NewsFillSolidRect and Move Window Pin
linsi26-Oct-05 19:27
memberlinsi26-Oct-05 19:27 
QuestionHow to deal with LabelEditEnded msg? Pin
Fzz26-Oct-05 17:55
memberFzz26-Oct-05 17:55 
GeneralTips for saving and loading the tree... Pin
d00_ape24-Sep-05 22:47
memberd00_ape24-Sep-05 22:47 
GeneralRe: Tips for saving and loading the tree... Pin
Joerg Koenig27-Sep-05 21:58
memberJoerg Koenig27-Sep-05 21:58 
GeneralStrange behaviour when selecting items Pin
Announ16-Aug-05 23:44
memberAnnoun16-Aug-05 23:44 
GeneralRe: Strange behaviour when selecting items Pin
Anonymous28-Sep-05 7:14
sussAnonymous28-Sep-05 7:14 
Generalwarning C4503 Pin
hygreen6-Aug-05 18:26
memberhygreen6-Aug-05 18:26 
GeneralRe: warning C4503 Pin
hygreen6-Aug-05 18:42
memberhygreen6-Aug-05 18:42 
GeneralRe: warning C4503 Pin
FriendOfAsherah7-Jan-06 1:22
memberFriendOfAsherah7-Jan-06 1:22 
GeneralRe: warning C4503 Pin
safety_ruk28-Jun-06 0:00
membersafety_ruk28-Jun-06 0:00 

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

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

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02-2016 | 2.8.180515.1 | Last Updated 25 Jul 2005
Article Copyright 2005 by Jörg König
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid