Tree Control : Adding Check Box Support

Submitted by date of submission user level 

Mahesh Chand Feb 02, 2001 Beginner 

You can provide check box support to a Tree Control. It kind of cheating though :). It happens with the help of two different images. First image look like a checked check box while other looks like unchecked check box. This all is possible with the help of CImageList. 

Create Check and UnCheck Box Icons

First step is to create two icons looks like check and uncheck boxes. See resource of my project.

Load and attach the ImageList to the TreeControl

On OnInitDialog,  I have created an ImageList and added both icons to it. After adding icons I attach this list to the TreeControl by using SetImageList.

// Load Images to the Image List

m_ImgList.Create(16, 16, TRUE, 2, 10);

HICON hIcon;

hIcon = ::LoadIcon(AfxGetResourceHandle(),

MAKEINTRESOURCE(IDI_UNCHECK));

m_ImgList.Add(hIcon);

hIcon = ::LoadIcon(AfxGetResourceHandle(),

MAKEINTRESOURCE(IDI_CHECK));

m_ImgList.Add(hIcon);

// Attach the Image List with the Tree Control 

m_TreeCtrl.SetImageList( &m_ImgList, TVSIL_NORMAL);

 

Add some items to the TreeControl

Now next step is to add some items to the TreeControl. This all done on OnInitDialog too.

// Add Items to the Tree Control

hRoot = m_TreeCtrl.InsertItem ("Root Item", 0, 0, TVI_ROOT, TVI_SORT);

m_TreeCtrl.SetItemImage(hRoot, 1, 1);

hItem = m_TreeCtrl.InsertItem( "First Child", 0, 0, hRoot, TVI_SORT );

m_TreeCtrl.SetItemImage(hItem, 1, 1);

hItem = m_TreeCtrl.InsertItem( "Second Child", 0, 0, hRoot, TVI_SORT );

m_TreeCtrl.SetItemImage(hItem, 1, 1);

HTREEITEM ghItem = m_TreeCtrl.InsertItem( "First Grand Child", 0, 0, hItem, TVI_SORT );

m_TreeCtrl.SetItemImage(hItem, 0, 0);

ghItem = m_TreeCtrl.InsertItem( "Second Grand Child", 0, 0, hItem, TVI_SORT );

m_TreeCtrl.SetItemImage(hItem, 0, 0);

ghItem = m_TreeCtrl.InsertItem( "Third Grand Child", 0, 0, hItem, TVI_SORT );

m_TreeCtrl.SetItemImage(hItem, 0, 0);

ghItem = m_TreeCtrl.InsertItem( "Fourth Grand Child", 0, 0, hItem, TVI_SORT );

m_TreeCtrl.SetItemImage(hItem, 0, 0);

hItem = m_TreeCtrl.InsertItem( "Third Child", 0, 0, hRoot, TVI_SORT );

m_TreeCtrl.SetItemImage(hItem, 1, 1);

 

Change the Image On On LButtonDown of the TreeControl

Now last step is to change the image of tree item OnLButtonDown message. I have used PreTranslateMessage to do so.

BOOL CTreeDlgDlg::PreTranslateMessage(MSG* pMsg) 

{

UINT pflags;

CTreeCtrl * pTreeCtrl = (CTreeCtrl*)GetDlgItem(IDC_TREE1);

if(pMsg->message==WM_LBUTTONDOWN && pMsg->hwnd == ((CWnd*)pTreeCtrl)->m_hWnd)

{

CPoint point;

point=pMsg->pt;

CString temp;

pTreeCtrl->ScreenToClient(&point);

HTREEITEM hitItem = pTreeCtrl->HitTest(point , &pflags);

if ( pflags & (TVHT_ONITEMICON))

if ( hitItem )

{

int nImage,nSelectedImage;

pTreeCtrl->GetItemImage(hitItem, nImage, nSelectedImage);

if(nImage==0)

pTreeCtrl->SetItemImage(hitItem, 1, 1);

else

pTreeCtrl->SetItemImage(hitItem, 0, 0);

return FALSE;

}

return CDialog::PreTranslateMessage(pMsg);

Here is the output:

 

Looking for all checked leaves in the tree

Now let's say you need to look for all checked leaves. How would you do that? Here is how I would do that.

BOOL bThisLeafIsChecked = FALSE;

CTreeCtrl * pTreeCtrl = (CTreeCtrl*)GetDlgItem(IDC_TREE1);

HTREEITEM hItem = pTreeCtrl->GetRootItem() ;

while (hItem)

{

   int nImage,nSelectedImage;

   pTreeCtrl->GetItemImage(hItem, nImage, nSelectedImage);

   if ( nImage == 1 )

       bThisLeafIsChecked = TRUE;

    hItem = pTreeCtrl->GetNextVisibleItem(hItem);

}

 

 

Attachments:

About the Author:

Mahesh is Admin and the founder of this site. He has been programming in VC++, Visual Basic, COM, ATL, Database Programming for 4 years. He can be reached at Mahesh. His  background includes Master's in Computer Science and Applications and BS in Mathematics and Physics.