Class with full row highlighting, dragable headers, sorting

Information above the divider pertains to the update of 6/13/98. I have redone the sorting. It should be much improved now. I have tested this sorting, and it will work much more reliably than the old stuff. Also I added support for sorting by float. There is now no need to check the Owner Draw Fixed box in the dialog editor. ListCtrlEx will automatically set LVS_OWNERDRAWFIXED if row hilighting is enabled.


I needed to add some functionality to my list controls, so of course, I came to the Code Guru for help. I found several very good articles on extending the CListCtrl class, but none that included all of the features I needed. By combining the code from three of these articles and adding some features of my own, I have created an easy to use extended list control class. CListCtrlEx extends CListCtrl by adding full row highlighting, column header drag and drop, and column sorting. Columns can be sorted by string(case or no case), number, or date/time. All, none or any combination of these features can be enabled.

I would like to thank the authors of the following articles:
Selection highlighting of entire row
Dragging columns to rearrange column sequence

Download Source (CListCtrlEx.h, and CListCtrlEx.cpp) 8Kb

To use CListCtrlEx:

1. Add the header to your dialog box header file or StdAfx.h:
#include "CListCtrlEx.h" 

2. Add a CListCtrlEx to your dialog box class where you would add CListCtrl:
CListCtrlEx m_List; 

3. Initialize the list control in the dialog box OnInitDialog function to enable the features you want:

BOOL CListDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
		
	//set the column types and enable sorting
	if(m_List.SetColumnTypes(_gnLogColTypes, NUM_LOGCOLUMNS))
		m_List.EnableSort();	
	//set the type of row highlighting
	m_List.SetHighlightType(HIGHLIGHT_ROW);
	//enable drag and drop headers
	m_List.EnableHeaderDrag();
	//set the base time for sorting on a 24 hour clock
	m_List.SetBaseTime("21:04:00");
	return TRUE;  
}

Notes:

_gnLogColTypes and NUM_LOGCOLUMNS are globally defined as follows:

#define NUM_LOGCOLUMNS	4
static unsigned char _gnLogColTypes[NUM_LOGCOLUMNS] = 
{
	LVEX_NUM, LVEX_CASE, LVEX_TIME, LVEX_NOCASE
};

If you do not call SetColumnTypes() but you enable sorting, all columns will be sorted as case sensitive strings. The sorting types are defined as:

LVEX_NUM: Sort as an integer number
LVEX_CASE: Sort as a string (case sensitive)
LVEX_NOCASE: Sort as a string (not case sensitive)
LVEX_TIME: Sort as a date/time
LVEX_NOSORT: Do not sort this column
LVEX_NUM_FLOAT: Sort by floating point number
LVEX_TIME_BASE: Sort as 24 hour time with a starting time (see below, will probably never use)

The row highlighting types are defined as:

HIGHLIGHT_NORMAL: Highlight the first column only (default CListCtrl behavior)
HIGHLIGHT_ALLCOLUMNS: Highlight all columns but not unused space
HIGHLIGHT_ROW: Highlight the entire row including unused space

I added the base clock time feature to fit a very specific need I had. Most people will probably not have to use it. The records I display commonly have 24 hour clock times (no date) beginning in early evening and running to morning (ie: 23:00:00 to 05:00:00) and I needed to sort the time from the starting time (23:00:00) not by the lowest time. If you do not call SetBaseTime(), the date/time will be sorted by absolute time.