Adding Simple Checkbox for each Item


You can check items in a treeview control by using either an overlay image or a couple of state images. Both the techniques are fairly simple, but using a state image allows us to show a checkbox and makes it obvious to the user.

In this section we allow an item to have only two states. Either it is checked or it is not. For a tree this is not always the best choice. We may also want imformation as to whether any of the child or descendant items are checked or not. We will cover that in the next topic.

Step 1: Create bitmap with checkbox images

Create a bitmap with an image of an unchecked checkbox and an image with a checked checkbox. Since we will be using this bitmap for the state image list, the first image will not be used. So the sequence of images in the bitmap is - blank image, empty checkbox and checked checkbox.


Step 2: Initialize the state image list

Setting up state images has been covered in a previous topic. If the tree control class has a member variable m_imageState then here's how to set the image list.
	m_tree.m_imageState.Create( IDB_STATE, 13, 1, RGB(255,255,255) );
	m_tree.SetImageList( &(m_tree.m_imageState), TVSIL_STATE );

Step 3: Insert items with the checkbox as a state image

If you are using TV_INSERTSTRUCT to insert an item into the tree control, then specify the state and the stateMask in the TV_ITEM member. The index of the state image is specified by using the macro INDEXTOSTATEIMAGEMASK. You can also use the SetItemState() function.

SetItemState( hItem, INDEXTOSTATEIMAGEMASK(1), TVIS_STATEIMAGEMASK );

Step 4: Add code to OnLButtonDown to toggle checkbox

When the user clicks on the checkbox, then the checkbox state has to be toggled. We use the HitTest() function to determine if the click was on the checkbox. When we get the state image index to determine whether the item is checked or not, the GetItemState() function returns the value in the form used internally by the tree control. Shifting the value by 12 bit places to the right gives us the proper index value. We then toggle the state of the item.
void CTreeCtrlX::OnLButtonDown(UINT nFlags, CPoint point) 
{
	UINT uFlags=0;
	HTREEITEM hti = HitTest(point,&uFlags);

	if( uFlags & TVHT_ONITEMSTATEICON )
	{
		int iImage = GetItemState( hti, TVIS_STATEIMAGEMASK )>>12;
		SetItemState( hti, INDEXTOSTATEIMAGEMASK(iImage == 1 ? 2 : 1), 
					TVIS_STATEIMAGEMASK );
		return;
	}
}

Step 5: Add code to OnKeyDown to toggle checkbox

This step provides the keyboard interface for checking and unchecking an item. The key used is usually the space key, so we will use the space key. The code is nearly the same as in the previous step. Instead of using HitTest() to determine the item handle, we use the function GetSelectedItem().
void CTreeCtrlX::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if( nChar == VK_SPACE )
	{
		HTREEITEM hti = GetSelectedItem();
		int iImage = GetItemState( hti, TVIS_STATEIMAGEMASK )>>12;
		SetItemState( hti, INDEXTOSTATEIMAGEMASK(iImage == 1 ? 2 : 1),
					TVIS_STATEIMAGEMASK );
		return;
	}
}

Step 6: Define helper functions

Define helper functions to determine whether an item is checked or not and to iterate through the checked items. The purpose of the functions is very clear from the function names.
BOOL CTreeCtrlX::IsItemChecked(HTREEITEM hItem)
{
	return GetItemState( hItem, TVIS_STATEIMAGEMASK )>>12 == 2;
}

HTREEITEM CTreeCtrlX::GetFirstCheckedItem()
{
	for ( HTREEITEM hItem = GetRootItem(); hItem!=NULL; hItem = GetNextItem( hItem ) )
		if ( IsItemChecked(hItem) )
			return hItem;

	return NULL;
}

HTREEITEM CTreeCtrlX::GetNextCheckedItem( HTREEITEM hItem )
{
	for ( hItem = GetNextItem( hItem ); hItem!=NULL; hItem = GetNextItem( hItem ) )
		if ( IsItemChecked(hItem) )
			return hItem;

	return NULL;
}

HTREEITEM CTreeCtrlX::GetPrevCheckedItem( HTREEITEM hItem )
{
	for ( hItem = GetPrevItem( hItem ); hItem!=NULL; hItem = GetPrevItem( hItem ) )
		if ( IsItemChecked(hItem) )
			return hItem;

	return NULL;
}



Comments

  • good control

    Posted by jiqiubo on 03/18/2008 03:59am

    good . thank you.

    Reply
  • IS it possible to add check to fet tree items instead of all.

    Posted by Legacy on 11/18/2003 12:00am

    Originally posted by: Shiv Kumar

    This article shows how to add check box to each tree item. IS it possible to add check to fet tree items instead of all.If yes please let me know.
    Thanks
    Shiv

    Reply
  • Adding check boxes to a CTreeCtrl

    Posted by Legacy on 04/22/2002 12:00am

    Originally posted by: David Orr

    Hi!

    Do you have any suggestions how I might add check boxes to
    a CTreeCtrl. It turns out that the LButtonDown message
    is not sent for the control and the message provided (NM_CLICK) does not have mouse coordinates from which to
    perform the HitTest. I've tried GetMessagePos(), but its coordindates are not something HitTest likes. This is true even after converting to client coordinates with ScreenToClient().

    Any hint would be greatly appreciated.

    David

    Reply
  • initializing Tree Control checkboxes

    Posted by Legacy on 12/31/2000 12:00am

    Originally posted by: Oren

    While opening a dialog with CTreeCtrl using check boxes,
    I have initalized the CTreeCtrl object in the OnInitDailog
    virtual function.
    Unfotunately somewhere in the middle of the DoModal on the
    DialogBox the state of the check boxes was changed to unchecked ...
    While trying to change the checkbox in other places in the program - it works ...

    If you know what could cause such a problem - i'wd be most thankfull.

    Reply
  • Check Tree Control

    Posted by Legacy on 10/03/2000 12:00am

    Originally posted by: Ashley Frieze

    On my copy of Visual C++ (6), there are functions SetCheck and GetCheck of CTreeCtrl. In addition, there is a Checkboxes style of a tree control.

    I'm not sure if these are new features, but they certainly render this article obsolete.

    Reply
  • Using State Images

    Posted by Legacy on 08/18/1999 12:00am

    Originally posted by: Emendeep Singh

    How to use State Images

    Reply
  • Passing Control to parent class

    Posted by Legacy on 03/10/1999 12:00am

    Originally posted by: George kalash

    CTreeCtrlX::OnLButtonDown is not passing control to its parent class
    
    

    if a tree node do not have TVHT_ONITEMSTATEICON the method is not passing control to its parent method

    I think that the method should be as follows

    if( uFlags & TVHT_ONITEMSTATEICON )
    {
    .....
    .....
    return;
    }

    CTreeCtrl::OnLButtonDown(nFlags, point);

    the same thing applies for OnKeyDown

    thanks
    George Kalash

    Reply
  • Compilation error

    Posted by Legacy on 03/10/1999 12:00am

    Originally posted by: George kalash

    GetNextItem method takes 2 parameters and not one
    
    HTREEITEM GetNextItem( HTREEITEM hItem, UINT nCode );

    GetPrevItem() does not exist under CTreeCtrl we have instead
    HTREEITEM GetPrevSiblingItem( HTREEITEM hItem );

    are these methods specific for CTreeCtrlX?

    thanks
    George Kalash

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • You probably have several goals for your patient portal of choice. Is "community" one of them? With a bevy of vendors offering portal solutions, it can be challenging for a hospital to know where to start. Fortunately, YourCareCommunity helps ease the decision-making process. Read this white paper to learn more. "3 Ways Clinicians can Leverage a Patient Portal to Craft a Healthcare Community" is a published document owned by www.medhost.com

  • Instead of only managing projects organizations do need to manage value! "Doing the right things" and "doing things right" are the essential ingredients for successful software and systems delivery. Unfortunately, with distributed delivery spanning multiple disciplines, geographies and time zones, many organizations struggle with teams working in silos, broken lines of communication, lack of collaboration, inadequate traceability, and poor project visibility. This often results in organizations "doing the …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds