桌面开发
现在阅读
Simple Tree Control
0

Simple Tree Control

由 ultracpy2018年1月20日

Why a new tree control

First of all, there are lots of custom tree controls available so what’s the need for this?
In one of my projects I happened to use several tree controls to show data objects at different levels
and I had to deal with user actions. Each time, my tree control has to respond
in different way depending on the selected item. Here I present what I have (I re-wrote some of my code to
use this custom control and I believe that it is more readeble and easy to understand now)

How it works

CSimpleTreeCtrl “simply” overrides the MFC CTreeCtrl class and provides some access
functions to deal with it. CSimpleTreeCtrl::TreeCtrlItem is used to add new items in the
tree control. You should write your own class (to use it in a better way) and override virtual functions
to be notified by windows messages such as item selection, right click etc.

CSimpleTreeCtrl provides the following virtual functions:

virtual void          selChanged ( TreeCtrlItem *item ) {} ;
virtual void          lClick ( TreeCtrlItem *item ) {} ;
virtual void          lDblClick ( TreeCtrlItem *item ) {} ;
virtual void          rClick ( TreeCtrlItem *item ) {} ;
// will be called after three control is created
virtual void          postCreate ( void ) {} ;

As you noticed base class has nothing to do with these functions. It simply handles windows messages and calls
the virtual function (I just got bored having to register my message handling functions). The base class also will
let CTreeCtrl do its own stuff, so whenever you receive a lClick() you will also get a
selChanged() if this click causes the current selection to change. The only difference is with
rClick(): since in most cases I want right click to change the selected item, I handled this case in
my message handler, so it will also send a selChanged() as well (if a selection exists). You may change this
behaviour if you want.

For me the most useful part is CSimpleTreeCtrl::TreeCtrlItem. This class provides the following virtual
functions:

// will be called on selection
virtual void          onSelected   ( void ) {} ;
// will be called for old selected item when there is a new selection (before
// onSelected() for new item)
virtual void          onUnSelected ( void ) {} ;
// will be called with position in screen coordinates if user right clicks on item
virtual void          onRClick    ( CPoint pos ) {} ;
// will be called if user left double clicks on item
virtual void          onLDblClick ( void ) {} ;
// will be called after item inserted in tree
virtual void          postInsert  ( void ) {} ;

It also provides two additional functions which you may find necessary. Thanks to Michael Dunn and his article
“Neat Stuff to do in List Controls Using Custom Draw”

void          setTextColor   ( COLORREF color ) ;
void          setBkColor     ( COLORREF color ) ;

The default color for item text is black ( RGB(0, 0, 0) ) and item background is white ( RGB(255, 255, 255) ).

You can write your own class handling only required virtual functions as shown below.

class BaseCtrlItem : public CSimpleTreeCtrl::TreeCtrlItem
{
public:
     BaseCtrlItem ( CString name, CMyDataClass *myData )
          : CSimpleTreeCtrl::TreeCtrlItem ( name )
     {
          m_myData = myData ;
     } ;

     virtual ~BaseCtrlItem () {} ;

     virtual void     postInsert ( void )
     {
          //You can insert sub items to the tree control if necessary
     } ;

     virtual void     onRClick ( CPoint pos )
     {
          //Show popup menu according to your data pointer
     } ;

protected:
     CMyDataClass *m_myData ;
};

If an item is removed from the tree (using CSimpleTreeCtrl or CTreeCtrl functions) related
the CSimpleTreeCtrl::TreeCtrlItem pointer will be removed as well, so you do not need to worry
about deleting the item pointers.

There is some more to add to this class but I prefer to keep it as simple as possible. Also, it handles most of
the requirements in my project. I would, however, like to hear if there is any usefull features to add while keeping
it simple.

The demo application creates a new tree control and adds some items in different colors. It also handles
the onRClick() function in items. You can just add SimpleTreeCtrl.h and SimpleTreeCtrl.cpp to your
project and enjoy it. The header file should be clear enough for documentation, if it is not, just let me know 🙂

Known Problems:

  1. CSimpleTreeCtrl does not hide the base implementation of CTreeCtrl so users may use
    the base class functionality as well. However this may cause some problems. Whenever a CSimpleTreeCtrl::TreeCtrlItem
    item is added to the tree, it’s pointer is added as item data in CTreeCtrl. If you use HTREEITEM to add
    new items and set item data by yourself, CSimpleTreeCtrl will assume that user data is a
    CSimpleTreeCtrl::TreeCtrlItem or derived pointer. If there is no user data, there should not be any problem

  2. CSimpleTreeCtrl::postCreate() will be called when tree control receives an OnCreate()
    message. I noticed that in some cases (according to how you use the tree) that control does not get this message. But I did
    not check it in detail. If you’ve got any problem send me the details.

出处:https://www.codeproject.com/Articles/3115/Simple-Tree-Control

关于作者
ultracpy
评论

你必须 登录 提交评论