Category Listbox
![]() |
![]() |
Without checkboxes. (Default) | With checkboxes. |
|---|---|
Environment: Visual C++ 6
Description
This control mimics the behavior of Microsoft Outlook's categorized listbox. It displays a list of categories and each category has its own list of items. Categories can be opened to reveal their items or closed to hide them. The idea is to help improve list organization and to make it easier for users to find what they are looking for.
Categories have the following attributes:
- Are indicated in the list with a grey background.
- Category name must be unique. (They are case sensitive.)
- Can have 0 to N items under them.
- Have open/close buttons to show/hide their items.
- Can be opened/closed by double-clicking them or by pressing the space bar.
Category items have the following attributes:
- Must be assigned to a category.
- Item name does not have to be unique.
- Can have a checkbox displayed next to it. (Microsoft Outlook does not have this feature.)
- Checkboxes can be checked/unchecked by clicking them or by pressing the space bar.
- Items can store DWORD data with them. (CListBox has this feature.)
Other supported features include:
- Sorts categories and their items if the LBS_SORT style has been set.
- Supports selection modes Single, Multiple, Extended, and None.
- SHOULD support unicode. (I haven't verified this.)
Implementation
The category listbox class is derived from the MFC CListBox class. Most of CListBoxs functions can still be used; however, some functions have been protected, thereby forcing you to use this class's functions instead. You cannot use the following CListBox functions with this class:
AddString( LPCTSTR pString ); InsertString( int iIndex, LPCTSTR pString ); DeleteString( int iIndex ); GetItemData( int iIndex ); SetItemData( int iIndex, DWORD dwValue );
The category listbox class has been made as simple as possible to make it easy for you to add this control to your project. You only need to add the files "CatListBox.cpp" and "CatListBox.h" to your project. That's it! You do not have to add any images to your resource file because this class draws its buttons and checkboxes itself.
To add this control to your dialog, do the following:
- Add a listbox to your dialog's resource.
- Set up your listbox's resource for "Owner Draw: Fixed" and check "Has Strings".

- Create a CCatListBox member variable in your dialog's code. For example...
#include "CatListBox.h" class MyDialog : public CDialog { public: // Dialog Data //{{AFX_DATA( MyDialog ) enum { IDD = IDD_MY_DIALOG }; CCatListBox m_lstCategories; // Create your variable here. //}}AFX_DATA } // Subclass the listbox here. // Make sure to replace IDC_LISTBOX_ID with the // one you're using. void MyDialog::DoDataExchange( CDataExchange* pDX ) { CDialog::DoDataExchange( pDX ); //{{AFX_DATA_MAP( MyDialog ) DDX_Control( pDX, IDC_LISTBOX_ID, m_lstCategories ); // Subclass it! //}}AFX_DATA_MAP }
Downloads
Download demo project - 20 KbDownload source - 2 Kb



Comments
Killer Implementation. Great design.
Posted by Legacy on 06/27/2003 12:00amOriginally posted by: Digital Sunrise
Gave me lots of ideas on what to do with an owner drawn list box, even from WIN32.
ReplyCan we add drag and drop function in this nice class?
Posted by Legacy on 06/18/2003 12:00amOriginally posted by: Yihong Yang
Hi, buddy:
I just use this class in my application. Really nice job! But I'm considering if we can add drag and drop function in this class that make it more powerful. Any suggestion or new work would be highly appreciated.
David Yang
ReplyA bug (not the checkbox issue)???
Posted by Legacy on 05/16/2003 12:00amOriginally posted by: Nigel Johnson
ReplyGREATAAAAaaaa !!!
Posted by Legacy on 04/22/2003 12:00amOriginally posted by: Zvika F.
i realy like the idea and the implementation !!
Suggesion:
make the structure "internal classes" (you'll have to make some modifications but it's more elegant)
ReplyVery nice implementation
Posted by Legacy on 04/17/2003 12:00amOriginally posted by: Santanu Lahiri
Joshua's Category List class was just what I needed. Pretty much drop in the class, include the header files, create the proper control in the dialog, and off you go. Hard to believe it was that simple. Documentation is also very good indeed. Was easy to change the behaviour just slightly to get the exact look I needed. Of course, I did not go about it the true C++ way by deriving from his class, but what the heck! Hope he forgives me!
ReplyGreat!
Posted by Legacy on 03/19/2003 12:00amOriginally posted by: Rahman
Thanks man. I was just looking for this kind cool stuff
ReplyExcellent work!
Posted by Legacy on 11/14/2002 12:00amOriginally posted by: Dean Jones
Must comment on the quality job Joshua did on the category listbox! It's seldom that I've found something this well written, this well documented (comments are copious and helpful), and this helpful (saved me QUITE a bit of work on one of my projects). Note that his comments in "Checkbox issue found is not a bug" are important (I made sure that all calls to AddCategoryItem() set an item's state to either zero or one, not the default of two).
Kudos!
DJ
ReplyCheckbox issue found is not a bug
Posted by Legacy on 11/13/2002 12:00amOriginally posted by: Joshua Quick
Hello all,
Some people are having trouble displaying checkboxes in my category listbox class. Here are some things you should know.
Checkboxes are referred to as item states in the code. Checkboxes are shown for all items by calling the following function:
myList.ShowCategoryItemStates( true );
Each item's checkbox has 3 states:
0 - Unchecked
1 - Checked
2 - No checkbox (The default!)
MFC and VB's checkboxes have similar tri-state behavior.
The item's checkbox state is set by calling the following function. (Set state to either 0, 1, or 2.)
myList.SetCategoryItemState( category, item, state );
The item's checkbox state can also be set when adding the item to the listbox.
myList.AddCategoryItem( category, item, state );
For example, to show an unchecked checkbox for the 2nd item under category "Foo", do the following...
myList.SetCategoryItemState( "Foo", 1, 0 );
To check it, do this...
myList.SetCategoryItemState( "Foo", 1, 1 );
I suppose the real bug is that the item's default checkbox state should not be 2 (no checkbox). Perhaps I should change it to 0 (unchecked)?
I apologize for the confusion caused by this. I have commented all of my functions in the CPP file if you haven't seen them already. However, due to the responses I've received, this shows that I have not documented my work well enough.
Thank you for your feedback!
Reply- Josh
Neat item
Posted by Legacy on 06/22/2002 12:00amOriginally posted by: Garry Birch
Sure as hell looks good Josh. Don't understand a damn thing written but nice to know that your good enough for publishing.
Garry
Reply