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.