Introduction
Sometimes, we need a tree control that allows the user to select multiple items at a time, but this feature is not provided by the standard common controls. Thanks to Richard Hazlewood's great article, this feature has been implemented nicely. However, Richard's implementation only supports the simple style rubber band selection. What I want to have is a tree control that implements an alpha-blended selection rectangle (just like explorer does).
Eugen Podsypalnikov did give us an approach to that with his CCoverWnd class, but the focus issue and CWnd
derived implementation makes me think that maybe implementing the selection drawing by the tree control itself would be a better idea, so here comes the CMultiSelTriCheckTreeCtrl
class in MFC.
The demo project actually belongs to my another humble article CVComboBox, so the download URLs are shared here.
As the snapshot shown, the tree control can have tri-states checkboxes display for each item, and all the selected items will be checked/unchecked when you click the checkbox of one of them. If you want to only check/uncheck the very item which is being selected, you can click the checkbox while holding the control key down.
Interfaces of CMultiSelTriCheckTreeCtrl
CMultiSelTriCheckTreeCtrl
is an MFC wrapper class that encapsulates the multi-select tree control, it derives from another MFC wrapper class called CTriCheckStateTreeCtrl
, which implements a tri-check state tree control.
The interfaces of CMultiSelTriCheckTreeCtrl
are quite similar to those of CMultiTree
by Richard Hazlewood since I just simply changed the selection drawing code after all, here are the public
interfaces:
inline BOOL IsMultiSelectable() const ;
void SetMultiSelectable(BOOL bMultiSel = TRUE);
inline BOOL IsSelected(HTREEITEM hItem) const;
size_t GetSelectedCount() const;
HTREEITEM GetFirstSelectedItem() const;
HTREEITEM GetNextSelectedItem(HTREEITEM hItem) const;
HTREEITEM GetPrevSelectedItem(HTREEITEM hItem) const;
void SelectAll(BOOL bSelect = TRUE);
void SelectRange(HTREEITEM hFirst, HTREEITEM hLast, BOOL bOnly = TRUE);
BOOL SetItemState(HTREEITEM hItem, UINT nState, UINT nStateMask);
UINT GetItemState(HTREEITEM hItem, UINT nStateMask) const;
virtual void ToggleCheckSelectedItem();
virtual void DeleteSelectedItem();
void GetSelectedList(TreeItemList& selectedList) const;
The Basic Steps to Use CMultiSelTriCheckTreeCtrl in a Dialog Based Application
Here are the basic steps to show how to use the class CMultiSelTriCheckTreeCtrl
:
- Create a dialog based MFC project called
CMultiSelTreeDemo
. - Add the following source files (under the folder code_base) into your workspace:
- CustomDrawCommon.cpp
- CustomDrawCommon.h
- CustomDrawControl.cpp
- CustomDrawControl.h
- CustomDrawUtils.cpp
- CustomDrawUtils.h
- Open the precompiled header file, which is normally StdAfx.h, append this line to it:
#include "..\code_base\CustomDrawCommon.h"
- If you are using Visual Studio 6.0, you also need to put these at the beginning of StdAfx.h:
#pragma warning(disable: 4786) // try to disable the annoying warning in VC6
#ifndef WINVER
#define WINVER 0x0501
#endif // WINVER
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif // _WIN32_WINNT
- Open the dialog with resource editor, drag and drop a tree control from the control toolbar to the dialog.
- Add a corresponding control member variable to that tree control, name it like
m_myTreeCtrl
, the IDE will add the necessary code for you, it would look like:
CTreeCtrl m_myTreeCtrl;
- Open the header file of the dialog class, put the
#include
directive to the beginning of it like this:
#include "..\code_base\CustomDrawControl.h"
- Rename the type of
m_myTreeCtrl
from CTreeCtrl
to CMultiSelTriCheckTreeCtrl
.
History
- 2010-12-29: Initial release