Set the State of Check Boxes in a ListView Control

 

Microsoft Corporation

June 2002

Summary: The Pocket PC ListView control provides a user interface feature that is very useful but unfortunately not completely exposed through API calls. However, it is possible to add a check box to ListView items so the user can easily select multiple items. The Pocket PC Software Development Kit (SDK) contains the function call to get the current check box state but unfortunately not to set its state. Here's how to add this functionality. (3 printed pages)

Applies to:
   Microsoft® Windows® Powered Pocket PC 2002
   Microsoft eMbedded Visual Tools version 3.0
   Microsoft® eMbedded Visual C++®

Languages supported

English (and others if applicable)

Contents

Background
Adding the Missing Pieces
Using the Checkboxes
Conclusion

Background

When designing a user interface, you often need to present a list of items with some visual feedback about the selection state. This can be done with different icons or, in the case of exclusive yes or no choices, a check box control. The Pocket PC ListView control comes with built-in support for check boxes (see Figure 1).


Figure 1. Check boxes allow intuitive selection of ListView items.

In the Pocket PC SDK, you'll find the ListView macro ListView_GetCheckState, which allows a list item's check box state to be queried. Unfortunately, the corresponding ListView_SetCheckState macro is not defined in the header files shipping with Microsoft Visual C++ to date, as well as the Pocket PC 2000 SDK and the current beta release of the Pocket PC 2002 SDK. The macro is shipping in the Platform SDK and documented in the MSDN library. It will be added for the final version of the Pocket PC 2002 SDK and future compiler releases.

If you take a look at the definition for ListView_GetCheckState in commctrl.h, you can see that the check box state is stored in bit 12 of the item data:

#define ListView_GetCheckState(hwndLV, i) \
   ((((UINT)(SNDMSG((hwndLV), LVM_GETITEMSTATE, (WPARAM)i, 
LVIS_STATEIMAGEMASK))) >> 12) -1)

Adding the Missing Pieces

By reversing the logic of ListView_GetCheckState, setting or clearing this bit will directly affect the check box state by setting or removing the check mark. Therefore, the ListView_SetCheckState command can be implemented as follows. Just copy and paste this macro definition into your own code to make it work.

#ifndef ListView_SetCheckState 
#define ListView_SetCheckState(h, i, f) \
        ListView_SetItemState(h, i, INDEXTOSTATEIMAGEMASK((f) + 1), 
LVIS_STATEIMAGEMASK) 
#endif

Note that INDEXTOSTATEIMAGEMASK shifts the value by 12 bits:

#define INDEXTOSTATEIMAGEMASK(i) ((i) << 12)

Using the Checkboxes

In order to use check boxes in a ListView, you need to set the LVS_EX_CHECKBOXES style:

ListView_SetExtendedListViewStyle(hWndList, LVS_EX_CHECKBOXES);

This style attribute reserves the required space in the list's first column and draws the check boxes in front of the text. When you want to set the check box, you just need to call ListView_SetCheckState with the control handle, the item index, and the desired state:

ListView_SetCheckState(hWndList, dwIndex, (bState ? 1 : 0));

Likewise, you can retrieve the check box state by simply calling ListView_GetCheckState with the control handle and item index:

ListView_GetCheckState(hWndList, dwIndex);

Conclusion

The full implementation of this feature will be available in the final Pocket PC SDK, so take advantage of this very simple way to fill the void and use check boxes to make your applications even more intuitive.