Click here to Skip to main content
15,867,686 members
Articles / Desktop Programming / MFC
Article

XListCtrl - A custom-draw list control with subitem formatting

Rate me:
Please Sign up or sign in to vote.
4.92/5 (261 votes)
6 Sep 2006CPOL9 min read 3.4M   34.2K   665   932
A custom-draw list control with support for subitem colors, bold font, progress bars, and checkboxes.

Introduction

The use of list controls is becoming very common now, and is used by many apps with the need for some sort of list display. I have used list controls in many projects, and naturally have developed my own classes to display different colors, fonts, and progress bars in list control.

Recently I needed a list control with a checkbox like Hotmail. With a list like Hotmail you have checkbox in column header, and checkboxes in each subitem in that column. To set a check in every subitem, you check the checkbox in the column header. Similarly, if you uncheck one of the subitems, then the checkbox in the column header also gets unchecked.

What's New in 1.4

  • Subitem editing - thanks to Oleg Matcovsky for providing code that I based this implementation on.
  • New combo box implementation - thanks to Mathias Tunared's excellent AdvComboBox.
  • Skip disabled items - fixed this bug, that allowed disabled item to be selected.
  • Set header alignment, text color, and divider lines.
  • Set cell padding.
  • Reduced flickering.
  • Header checkboxes do not require resource bitmap - the file checkboxes.bmp, is still included in download, but it is no longer really necessary.
  • Enable ellipsis for text display.
  • Get modified flag for subitems.
  • More demo build configurations - 1.4 includes both DLL and static link build configurations, with 3 types of demo apps — dialogs, MDI, and property sheet — and 12 versions of the XListCtrl libraries, including both Unicode and ANSI.
  • DLL and static library versions - beginning with this version, all XListCtrl code has been organized as libraries that you link with. Table below shows library versions available.
  • Many bug fixes!

XListCtrl Features

The new CXListCtrl list control class supports these features:

  • Text and background colors may be specified for each subitem.
  • One or more subitem text may be displayed as normal or bold font.
  • One or more subitems may be switched from displaying text to displaying a progress bar, and then back again to text.
  • Custom text may be specified for progress bar, instead of just displaying usual 10%, 20%, etc. Also, there is option to display no text for progress bar, just the bar itself.
  • One or more subitems may contain checkbox, with or without text.
  • One or more subitems may contain combobox control.
  • One or more subitems may contain edit control.
  • A row may be disabled, so that checkboxes are unclickable.
  • The header is displayed flat like Outlook.

XListCtrl Demo

The demo project provides a sample app that shows what the various features look like. Press the Start button and the list control is filled with data.

screenshot

  1. First column is specified with checkboxes
  2. The second column shows subitem with bold text
  3. The second column shows subitem with different background color
  4. The third column contains progress bar in row 2
  5. The fourth column also contains checkboxes
  6. The fifth column shows subitem with different background color
  7. The sixth column shows subitem with different text and background colors
  8. The second column shows combobox
  9. The sixth row is disabled
  10. The fifth column shows edit control

How To Use

To integrate XListCtrl into your own app, you first need to decide if you want to include XListCtrl code into your own exe (using XListCtrl static link library), or if you want to link to XListCtrl DLL. Using DLL version of XListCtrl makes sense if you plan to use XListCtrl in several apps. The XListCtrl DLL is an MFC extension DLL, so your app must also be MFC-based.

If you plan to use and distribute DLL version of XListCtrl, do not put DLL in Windows directory. This could cause conflicts with other apps that use XListCtrl, and some future version of XListCtrl may not be compatible with the one that you distribute.

To use static XListCtrl library, define symbol XLISTCTRLLIB_STATIC before including header file XListCtrl.h. Otherwise, DLL version of XListCtrl will be linked to your app. Regardless of which version you link with, you must change your app's build environment as follows:

  1. Go to Project | Settings | C/C++ | Preprocessor and add the XListCtrl source directory to Additional include directories. Also, on the left side of the Settings dialog, choose All Configurations. Click OK to save this setting.

    screenshot

  2. Go to Project | Settings | Link | Input and add the XListCtrl library directory to Additional library path. Again, on the left side of the Settings dialog, choose All Configurations. Click OK to save this setting.

    screenshot

Automatic Library Selection

Using symbols _AFXDLL, XLISTCTRLLIB_STATIC, _DEBUG, and _UNICODE, the following code in XListCtrl.h automatically determines which XListCtrl library to link to your app:

#ifndef XLISTCTRLLIB_NOAUTOLIB
    #if defined _AFXDLL && !defined XLISTCTRLLIB_STATIC
        // MFC shared DLL with XListCtrl shared DLL
        #ifdef _UNICODE    
            #ifdef _DEBUG
                #pragma comment(lib,"XListCtrlDDDU.lib")
                #pragma message("Automatically linking with XListCtrlDDDU.lib")
            #else
                #pragma comment(lib,"XListCtrlDDRU.lib")
                #pragma message("Automatically linking with XListCtrlDDRU.lib")
            #endif
        #else
            #ifdef _DEBUG
                #pragma comment(lib,"XListCtrlDDDA.lib")
                #pragma message("Automatically linking with XListCtrlDDDA.lib")
            #else
                #pragma comment(lib,"XListCtrlDDRA.lib")
                #pragma message("Automatically linking with XListCtrlDDRA.lib")
            #endif
        #endif
    #elif defined _AFXDLL && defined XLISTCTRLLIB_STATIC
        // MFC shared DLL with XListCtrl static lib
        #ifdef _UNICODE
            #ifdef _DEBUG
                #pragma comment(lib,"XListCtrlDSDU.lib")
                #pragma message("Automatically linking with XListCtrlDSDU.lib")
            #else
                #pragma comment(lib,"XListCtrlDSRU.lib")
                #pragma message("Automatically linking with XListCtrlDSRU.lib")
            #endif
        #else
            #ifdef _DEBUG
                #pragma comment(lib,"XListCtrlDSDA.lib")
                #pragma message("Automatically linking with XListCtrlDSDA.lib")
            #else
                #pragma comment(lib,"XListCtrlDSRA.lib")
                #pragma message("Automatically linking with XListCtrlDSRA.lib")
            #endif
        #endif
    #elif !defined _AFXDLL && defined XLISTCTRLLIB_STATIC
        // MFC static lib with XListCtrl static lib
        #ifdef _UNICODE
            #ifdef _DEBUG
                #pragma comment(lib,"XListCtrlSSDU.lib")
                #pragma message("Automatically linking with XListCtrlSSDU.lib")
            #else
                #pragma comment(lib,"XListCtrlSSRU.lib")
                #pragma message("Automatically linking with XListCtrlSSRU.lib")
            #endif
        #else
            #ifdef _DEBUG
                #pragma comment(lib,"XListCtrlSSDA.lib")
                #pragma message("Automatically linking with XListCtrlSSDA.lib")
            #else
                #pragma comment(lib,"XListCtrlSSRA.lib")
                #pragma message("Automatically linking with XListCtrlSSRA.lib")
            #endif
        #endif
    #else
        #pragma message(" ")
        #pragma message("-------------------------------------" + 
                        "-------------------------------------")
        #pragma message(" The SD build configuration (MFC static," + 
                        " XListCtrl DLL) is not available. ")
        #pragma message("-------------------------------------" + 
                        "-------------------------------------")
        #pragma message(" ")
        #error This build configuration is not available.
    #endif
#endif

XListCtrl Library Naming Conventions

XListCtrl Library Naming Conventions
Library NameMFCXListCtrlBuildCharset
DLLStaticDLLStaticDebugReleaseANSIUNICODE
XListCtrlDDDA

Image 4

 

Image 5

 

Image 6

 

Image 7

 
XListCtrlDDDU

Image 8

 

Image 9

 

Image 10

  

Image 11

XListCtrlDDRA

Image 12

 

Image 13

  

Image 14

Image 15

 
XListCtrlDDRU

Image 16

 

Image 17

  

Image 18

 

Image 19

XListCtrlDSDA

Image 20

  

Image 21

Image 22

 

Image 23

 
XListCtrlDSDU

Image 24

  

Image 25

Image 26

  

Image 27

XListCtrlDSRA

Image 28

  

Image 29

 

Image 30

Image 31

 
XListCtrlDSRU

Image 32

  

Image 33

 

Image 34

 

Image 35

XListCtrlSSDA 

Image 36

 

Image 37

Image 38

 

Image 39

 
XListCtrlSSDU 

Image 40

 

Image 41

Image 42

  

Image 43

XListCtrlSSRA 

Image 44

 

Image 45

 

Image 46

Image 47

 
XListCtrlSSRU 

Image 48

 

Image 49

 

Image 50

 

Image 51

XListCtrlSDxx——— not built ———

Building XListCtrl Libraries

To build the XListCtrl libraries, go to Build | Batch Build and select the libraries you wish to build:

screenshot

Then click on Rebuild All and the libraries will be built. By default, the .lib and .dll files are copied to the bin directory.

Tips and Tricks

  • Rebuilding dialog demos - If you rebuild any of the dialog demos, be sure to use Rebuild All command. Reason: the dialog demos all share the same output file directories, and you will get linker errors if you compile only one module, and try to link with modules that were compiled with different set of build options.
  • Eliminate flickering - When updating or filling the list control, there is sometimes flickering of list control and/or other controls on dialog. To eliminate this flickering, you may try one of the following methods:
    1. Use CListCtrl::LockWindowUpdate()/CListCtrl::UnlockWindowUpdate() to bracket the updating code.
    2. Use CListCtrl::SetRedraw(FALSE)/CListCtrl::SetRedraw(TRUE) to bracket the updating code.

    After using one of these methods, you probably should call list.UpdateWindow() to make sure control is updated. If one method doesn't completely eliminate flickering in your application, try other method to determine which works best.

  • Using tooltips - You must first call CListCtrl::EnableToolTips(TRUE).
  • Using combobox and edit controls - You must set LVS_EX_FULLROWSELECT style.

Revision History

Version 1.4 Changes

  • Subitem editing
  • New combo box implementation
  • Skip disabled items
  • APIs to set header alignment, text color, and divider lines
  • Set cell padding
  • Reduced flickering
  • Header checkboxes do not require resource bitmap
  • Enable ellipsis for text display
  • API to get modified flag for subitems
  • More demo build configurations
  • DLL and static library versions
  • Many bug fixes!

Version 1.3 Changes

This version includes many bug fixes that have been accumulating. My thanks for all who have reported bugs. Please try this new version and let me know if you find any bugs, or have suggestions for future enhancements.

  • Added hot-tracking to combo's listbox.
  • Added compile-time option to remove support for comboboxes. (This reduce exe size by about 8 Kb). To remove combobox support, put this line in stdafx.h:
    #define DO_NOT_INCLUDE_XCOMBOLIST

    If you insert this define, you do not need to include XComboList.cpp or XComboList.h in your project.

  • Changed CXComboList::SetActive to accept scroll bar width as input parameter.
  • Fixed bug that caused string to not be displayed when clicking outside item string (reported by James Moore). This also caused problems in property pages and other places.
  • Fixed bug that caused some strings not to be selected, when drag-selecting several items quickly (reported by James Moore).
  • Fixed several problems with displaying images in header and list control (reported by Scot Brennecke).
  • Changed message map macros for NM_CLICK and LVN_COLUMNCLICK to use ON_NOTIFY_REFLECT_EX(), to allow parent to handle message also (suggested by bkupcins).
  • Fixed problem in XHeaderCtrl caused when XP theming is enabled. The GetHeaderCheckedState()/SetHeaderCheckedState() functions now use 0 = no check box, 1 = unchecked check box, 2 = checked check box. Note: The checkboxes.bmp file has also been updated, and must be replaced in all project that use 1.3 XListCtrl. The new defines XHEADERCTRL_NO_IMAGE, XHEADERCTRL_UNCHECKED_IMAGE, and XHEADERCTRL_CHECKED_IMAGE should be used when setting the image in the header control (see XListCtrlTestDlg.cpp for example).
  • Replaced calls to GetSysColor() with class variables that are set in ctor. Class variables are reloaded in response to WM_SYSCOLORCHANGE message (suggested by KarstenK).
  • Added ASSERT if combo boxes are used without LVS_EX_FULLROWSELECT style.
  • Added two registered messages that XListCtrl will send to its parent when combo box selection is changed (WM_XLISTCTRL_COMBO_SELECTION) and when check box is clicked (WM_XLISTCTRL_CHECKBOX_CLICKED). The sample app shows how to handle these new messages.
  • Added support for tooltips. To enable tooltips, you must call CListCtrl::EnableToolTips(TRUE). If you #define constant NO_XLISTCTRL_TOOL_TIPS, the tooltip support will not be included. New API's for tooltips:
    BOOL SetItemToolTipText(int nItem, int nSubItem, LPCTSTR lpszToolTipText);
    CString GetItemToolTipText(int nItem, int nSubItem);
    void DeleteAllToolTips();

Version 1.2.1 Changes

  • Added build configurations for Unicode.
  • Minor code modifications to support Unicode strings.

Version 1.2 Changes

  • Comboboxes!!! Now you can specify drop-list combobox for one or more subitem.
  • Combobox will be drawn when item is highlighted. Demo now has item hot-tracking.
  • Incorporated David Patrick's suggestion on how to subclass header control if CXListCtrl is created dynamically via Create() instead of via dialog template. See XListCtrlTestDlg.cpp for details on how to convert the demo project to create CXListCtrl dynamically.
  • Tweaked drawing of subitems to make cleaner visually.
  • Added API's for GetCurSel and SetCurSel to make coding easier.

Acknowledgments

The CXListCtrl code is based on:

The city population figures are taken from Th. Brinkhoff: The Principal Agglomerations of the World.

Usage

This software is released into the public domain. You are free to use it in any way you like, except that you may not sell this source code. If you modify it or extend it, please to consider posting new code here for everyone to share. This software is provided "as is" with no expressed or implied warranty. I accept no liability for any damage or loss of business that this software may cause.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Hans Dietrich Software
United States United States
I attended St. Michael's College of the University of Toronto, with the intention of becoming a priest. A friend in the University's Computer Science Department got me interested in programming, and I have been hooked ever since.

Recently, I have moved to Los Angeles where I am doing consulting and development work.

For consulting and custom software development, please see www.hdsoft.org.






Comments and Discussions

 
GeneralMy vote of 5 Pin
Jackem_Govpan4-Oct-17 0:47
Jackem_Govpan4-Oct-17 0:47 
Questionmoving OnLButtonDown code to OnClick will better Pin
may20th21-Jun-17 2:35
may20th21-Jun-17 2:35 
Questiongot error when i tried to integrate XListCtrlSSDU.lib into my app Pin
yixuan1782-Nov-14 4:55
yixuan1782-Nov-14 4:55 
Questionmy mfc app is used "Use MFC in a Static Library", does it mean only to use XListCtrlSS.lib Pin
yixuan1782-Nov-14 4:41
yixuan1782-Nov-14 4:41 
Questionbuild failed under vs2013 Pin
yixuan1782-Nov-14 1:56
yixuan1782-Nov-14 1:56 
AnswerRe: build failed under vs2013 Pin
yixuan1782-Nov-14 2:38
yixuan1782-Nov-14 2:38 
GeneralMy vote of 5 Pin
Xjkstar23-Jul-14 22:25
Xjkstar23-Jul-14 22:25 
GeneralRe: My vote of 5 Pin
yixuan1782-Nov-14 1:07
yixuan1782-Nov-14 1:07 
QuestionVisual Studio 2012 Pin
Member 104081419-Jun-14 22:25
Member 104081419-Jun-14 22:25 
AnswerRe: Visual Studio 2012 Pin
Xjkstar23-Jul-14 22:17
Xjkstar23-Jul-14 22:17 
QuestionWhere to get the Latest Version Pin
LeslieM14-Mar-14 5:17
LeslieM14-Mar-14 5:17 
QuestionVisual Studio 2012 Pin
Member 100311734-Jul-13 8:02
Member 100311734-Jul-13 8:02 
AnswerRe: Visual Studio 2012 Pin
gbjbaanb13-Sep-13 4:33
gbjbaanb13-Sep-13 4:33 
Questionpurchase latest version from hans website Pin
garyt14-Apr-13 8:58
garyt14-Apr-13 8:58 
Bugbug of xlistctrl(combo box) Pin
sharkka16-Jan-13 23:23
sharkka16-Jan-13 23:23 
QuestionSuggested Enhancements Pin
Sharon F28-Sep-12 10:17
Sharon F28-Sep-12 10:17 
QuestionClick the check box of the first column is not responding! Pin
zemelaoshi1-Aug-12 20:50
zemelaoshi1-Aug-12 20:50 
QuestionAlignment of heading text Pin
David Crow28-Feb-12 8:00
David Crow28-Feb-12 8:00 
QuestionTest app won't run Pin
David Crow27-Feb-12 5:28
David Crow27-Feb-12 5:28 
QuestionThe demo project build error... Pin
cyfage19-Feb-12 21:25
cyfage19-Feb-12 21:25 
AnswerRe: The demo project build error... Pin
David Crow27-Feb-12 4:24
David Crow27-Feb-12 4:24 
GeneralRe: The demo project build error... Pin
gindar19-Apr-12 4:04
gindar19-Apr-12 4:04 
AnswerRe: The demo project build error... Pin
gindar19-Apr-12 4:02
gindar19-Apr-12 4:02 
AnswerRe: The demo project build error... Pin
Xjkstar23-Jul-14 22:03
Xjkstar23-Jul-14 22:03 
Questionabout XListCtrl 1.5 license Pin
hugeval27-Dec-11 0:26
hugeval27-Dec-11 0:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.