Click here to Skip to main content
Click here to Skip to main content

Speeding up the tree control

, 22 Aug 2000
Rate this:
Please Sign up or sign in to vote.
Some notes on speed issues with the MS Tree control
<!-- Main HTML starts here -->

Introduction

I was in a situation where my application became slower than I expected. The reason, I found, was the tree control's speed.

First problem was in drawing. I used my own OnPaint, and used a trick you can find in many examples:

void CMyTreeCtrl::OnPaint()
{
    CPaintDC paintDc(this);

    CDC dc;
    dc.CreateCompatibleDC(&paintDc);

    CRect clientRect;
    GetClientRect(&clientRect);

    CBitmap bitmap;
    bitmap.CreateCompatibleBitmap(&paintDc, clientRect.right, clientRect.bottom);

    CBitmap *pOldBitmap = dc.SelectObject(& bitmap);

    CWnd::DefWindowProc(WM_PAINT, (WPARAM)dc.m_hDC, 0);

    dc.SetBkMode(TRANSPARENT);

    HTREEITEM hItem = GetFirstVisibleItem();

    while(hItem != NULL)
    {
        //do here what you want

        hItem = GetNextVisibleItem(hItem);
    }

    paintDc.BitBlt(0, 0, clientRect.right, clientRect.bottom, 
                   &dc, 0, 0, SRCCOPY);

    dc.SelectObject(pOldBitmap);

    // Do not call CTreeCtrl::OnPaint() for painting messages
}

If you plan to use many items then change the "//do here what you want" part to this

        CRect rItemRect;
        GetItemRect(hItem, &rItemRect, FALSE);
        if(dc.RectVisible(rItemRect))
        {
            //do here what you want
        }
        else
        {
            break; //from while
        }

This way drawing speed improved.

Multiple fonts

Maybe you will not believe it but there can be situations where the tree control can use two fonts. This happened (in non-Unicode case) when some items contained not-english characters.

This items were drawn with another font so my own drawing in client's rectangle was sometimes clipped. Both fonts sometimes displayed the problematic characters the same way, or sometimes the second font displayed them wrong way.

It only happened on some machines, and than this problem was in another system too. It helped to set the windows default language to that what uses all the problematic characters.

Back to the speed case.

I found there are actions what are slow because of tree control's nature (or better their author's). All of the following speed problems will grow with item count, meaning a time dependency on item count is not linear but quadratic.

One of the slow operations was, as you can expect, InsertItem. To do something with this is difficult. When you have application where you will from time to time insert some items then this will not be a problem.

What was worse, and for me surprising, was that a slower operation than InsertItem was DeleteItem. For me was interesting was the case of deleting all items from the tree.

Possibly you will say: Stupid man, I will have not this problem because

  • I will use (optimized) DeleteAllItems, possibly with SetRedraw combination, or
  • I will never call any Delete because I have a tree in dialog so it will be automaticaly detroyed at its end, or
  • I will call DestoyWindow and than Create.

No one of this solutions will help you - they will all take similar time.

Hopefully you will never have 65536 items in a MS tree control. Of course this depends on machine speed but for full tree it can take more than half hour to remove all items. If you think you will jump over it by using list-control solution (I know from message boards reading only) you will not win.

Trying to set the parent to NULL to eliminate possible DeleteItem notifications did not work either.

I started to experiment with own all items deleting. The funny thing is I never found a slower solution than DeleteAllItems. The best solution I found was this:

SetRedraw(FALSE) 
//find last first-level item
HTREEITEM i1 = GetRootItem();
HTREEITEM i2 = i1;
while(i2 != NULL)
{
  i1 = i2;
  i2 = GetNextItem(i1, TVGN_NEXT);
}
//remove from end
while( i1 != NULL)
{
  i2 = GetNextItem(i1, TVGN_PREVIOUS);
  DeleteItem(i1);
  i1 = i2;
}
SetRedraw(TRUE) 

Note that calling SetRedraw(..) before and after the repeated operations stops the control from redrawing the control each time it's contents are changed. This is a standard trick and works with most of the Windows common controls (thanks to Steve Driessens for this).

Overall it was little bit quicker but similar to DeleteAllItems - minutes are still minutes. Plus it is possible that at your machine, with your OS version, your commctrl.dll version will be slower (or faster) than this. In newer windows versions (W2K experience) the situation is better. Adding SetRedraw()s and with Expand(hItem, TVE_COLLAPSE)s before your deletions you can get a more usable state (you can do this in W9x/NT, but it won't result in any further speedup).

Maybe you will not agree with my methods, or have or know something better - please let know.

As an aside, try to using the spy tool on the workspace window in Developer Studio. From the class name you will see that it does not use the system tree control.

There are some quicker non-MS tree controls but most are not free. Using them without source ownership cound possibly bring problems with new OS versions.

License

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

Share

About the Author

Tibor Blazko
Software Developer (Senior)
Slovakia Slovakia
No Biography provided

Comments and Discussions

 
GeneralInitial painting problem in CTreeCtrl PinmemberAbhi Lahare8-May-06 21:14 
GeneralRe: Initial painting problem in CTreeCtrl PinmemberTibor Blazko8-May-06 21:44 
GeneralSolutions and strange behaviour PinmemberArccos6-Sep-05 3:09 
GeneralObvious but often forgot!! Pinmembereneam4-Feb-04 21:32 
GeneralIME Issue in CTreeCtrl Pinmemberboonshajayan25-Aug-03 22:33 
GeneralAnother optimization... well sort of... PinmemberTim Smith19-Jul-02 5:17 
GeneralProblem with Tree contol PinmemberMuddassir25-Apr-02 23:18 
Generala sample of a fast file system browsing CTreeCtrl PinmemberMarat Bedretdinov2-Jun-01 16:18 
GeneralThe final solution to the speed problem PinmemberMarcos Lima21-May-01 15:25 
GeneralRe: The final solution to the speed problem PinmemberAnonymous21-May-01 15:46 
GeneralRe: The final solution to the speed problem PinmemberRené Greiner5-Jul-01 21:04 
GeneralRe: The final solution to the speed problem PinmemberTibor Blazko5-Jul-01 21:07 
GeneralMy own tree control ( need help with UI ) PinsussRené Greiner30-Aug-00 21:48 
GeneralRe: My own tree control ( need help with UI ) PinsussPeter17-Sep-00 22:05 
GeneralOWN TREE CONTROL PinmemberTibor Blazko5-Jul-01 20:52 
GeneralRe: My own tree control ( need help with UI ) Pinmemberroger_long17-Dec-07 21:01 
GeneralInsert an item PinsussRené Greiner28-Aug-00 1:25 
GeneralSpeed up PinsussMartin Bohring25-Aug-00 8:48 
GeneralSpeed up PinsussMartin Bohring25-Aug-00 8:48 
GeneralVirtual ListCtrl is much much faster PinsussTim Finer24-Aug-00 20:01 
GeneralSpeed PinsussSimon Brown24-Aug-00 10:05 
GeneralAnother spped improvement PinsussSteve Driessens23-Aug-00 17:38 
GeneralRe: Another spped improvement Pinsusstibor blazko23-Aug-00 23:42 

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
Web02 | 2.8.141015.1 | Last Updated 23 Aug 2000
Article Copyright 2000 by Tibor Blazko
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid