A Multi-Level CCheckListbox
Posted
by Brett R. Mitchell
on January 21st, 2000

The interface's supplied to use this class is as follows (examples to use them are below
Each item added to the control is represented by the following structure..
struct LISTITEM
{
LISTITEM* pParentItem; // Points to its parent
int nCheckedState; // It check state
// Total width of this item (includes bitmap & indents)
int nTotalWidth;
int nTextLength; // Length of the text in bytes
int nLevel; // How many tabs it is over
// Is this item selected (multiple selection eventually)
bool bSelected;
DWORD dwID; // Id accociated with the item
CString csText; // Text of the item
// Appearence
COLORREF crTextColor; // Text color
COLORREF crTextHighColor; // Text selection color
COLORREF crBgHighlightColor; // Background highlight color
// List to other child list items
CPtrList m_ItemList; // List of all this items children
};
You can obtain this structure for every item in the control to get and set its
attributes. Be careful not to change certian items though, such as nLevel and
nTextLength. (these are for internal use only!)
User Functions
BOOL Create( CRect Rect, CWnd* pParent, UINT uID, UINT nCheckBitmap, UINT nUnCheckBitmap, UINT nMiddleCheckBitmap, COLORREF crBkColor = GetSysColor(COLOR_WINDOW), CFont* pCustomFont = NULL); LISTITEM* AddString( CString csText, LISTITEM* pParentItem = NULL, int nCheckState = UNCHECKED, DWORD dwID = -1, COLORREF crTextColor = GetSysColor(COLOR_INFOTEXT), COLORREF crTextHighColor = GetSysColor(COLOR_HIGHLIGHTTEXT), COLORREF crBgHighlightColor = GetSysColor(COLOR_HIGHLIGHT)); int DeleteString(int nItem); int GetCount(LISTITEM* pParentItem = NULL); int GetTopIndex(); int SetTopIndex(int nTop); DWORD GetItemData(int nItem); int SetItemData(int nItem, DWORD dwID); LISTITEM* GetItem(int nItem); LISTITEM* GetItem(DWORD dwID); int GetText(int nItem, CString* pString ); int GetTextLen(int nItem ); int GetCurSel(); int SetCurSel(int nItem); int SetCheck(int nItem, int nCheckState ); int GetCheck(int nItem); void ResetContent();Most of the above functions work identical to the standard CListBox functions so I will spare you the verbiage in how to use them. I will however, elaborate on some specific ones that are new to this class or work a little differently then the norm.
BOOL Create( CRect Rect, CWnd* pParent, UINT uID, ...)In the create call you must specify the three bitmaps you want to be used to display the states of each item. These imaged must be the same exact size! You can also see that the background color can be set along with the font to use.
LISTITEM* AddString( CString csText, ...)In the AddString call, you can set the items parent (by using the item that is returned in a previous AddString call) You can also set a lot of custom features such as: State, ID, and lots of colors!
int DeleteString(int nItem);Removes the item sent, PLUS all of the items children, and their children, etc.
int GetCount(LISTITEM* pParentItem = NULL);Returns the total items in the control if NULL is sent in or the number of children for a specific item.
LISTITEM* GetItem(int nItem); LISTITEM* GetItem(DWORD dwID);Both of these functions find an item based on either their positions in the control or the ID set for the them. As you can see, it returns the entire structure that represents the item.
There are other inline functions that are also available. These are (hopefully) self-explanatory.
inline int GetWidestItem() { return m_nWidestItem; };
inline int GetLineHeight() { return m_nLineHeight; };
inline CPen* GetBkPen() { return m_pBkPen; };
inline CBrush* GetBkBrush() { return m_pBkBrush; };
inline CFont* GetTextFont() { return m_pTextFont; };
inline int GetImageWidth() { return m_cBitmapDimen.cx; };
inline int GetImageHeight() { return m_cBitmapDimen.cy; };
inline CBitmap* GetCheckImage() { return m_pCheck; };
inline CBitmap* GetUnCheckImage() { return m_pUnCheck; };
inline CBitmap* GetMiddleImage() { return m_pMiddleCheck; };
Here's some sample code in how to fill and manipulate items in the control...
// Create the Control
LISTITEM* pParentItem = NULL;
m_pCheckList = new CCheckList();
if( !m_pCheckList->Create( CRect(50,50,300,300), this, 10001,
IDB_CHECK, IDB_UNCHECK, IDB_MIDDLECHECK ))
{
return;
}
// Add some items
// Root Item
pParentItem = m_pCheckListStandard->AddString("Exotics");
// Sub Item
m_ pCheckList ->AddString("Lamborghini", pParentItem );
// Sub Item
m_ pCheckList ->AddString("Corvette", pParentItem );
// Sub Item
m_ pCheckList ->AddString("Vector", pParentItem );
// Sub Item
m_ pCheckList ->AddString("Hummer", pParentItem );
// Sub-Sub Item
pParentItem = m_ pCheckList ->AddString("Porsche", pParentItem );
// Sub-Sub Item
m_ pCheckList ->AddString("Boxster", pParentItem );
// Sub-Sub Item
m_ pCheckList ->AddString("928 S4", pParentItem);
// Sub-Sub Item
m_ pCheckList ->AddString("959", pParentItem );
// Root Item
m_ pCheckList ->AddString("Luxury");
// Root Item
m_ pCheckList ->AddString("Trucks");
// Root Item
m_ pCheckList ->AddString("Sport Utility Vehicles");
// Root Item
m_ pCheckList ->AddString("Classics");
// Function uses
// Get Total Count
CString csMessage;
csMessage.Format("There are a total of %d items",
m_pCheckListStandard->GetCount() );
AfxMessageBox(csMessage);
// Get and Set the top index
csMessage.Format("The top index is: %d",
m_pCheckListStandard->GetTopIndex() );
AfxMessageBox(csMessage);
m_pCheckListStandard->SetTopIndex(6);
// Different ways to get an item
LISTITEM* pItem =
m_pCheckListStandard->GetItem(
m_pCheckListStandard->GetTopIndex());
AfxMessageBox(pItem->csText);
pItem = m_pCheckList->GetItem((DWORD)5000);
AfxMessageBox(pItem->csText);
// Get and Set the Item data
DWORD dwID =
m_pCheckListStandard->GetItemData(
m_pCheckListStandard->GetTopIndex());
csMessage.Format("The Data for this item is: %ld", dwID );
AfxMessageBox(csMessage);
m_pCheckListStandard->SetItemData(6, 2000);
// Get the text and text length
CString csText;
m_pCheckListStandard->GetText( 6, &csText );
int nTemp = m_pCheckListStandard->GetTextLen( 7 );
// Get and set the current selection
m_pCheckListStandard->SetCurSel(6);
nTemp = m_pCheckListStandard->GetCurSel();
// Get and Set Checks
m_pCheckListStandard->SetCheck(6, CHECKED);
nTemp = m_pCheckListStandard->GetCheck(6);
// Remove one item and all its subitems (if it has them)
m_pCheckListStandard->DeleteString(6);
// Delete eveything
m_pCheckListStandard->ResetContent();
I have included the standard looking three states for checkboxes..but feel free to think outside the box and create your own!

Comments