A Multi Column Sort listview

 Download Source Code and Example

This class handles sorting of multiple columns in a listctrl
at the same time. The way it works is simple. When you click
on a column, the column number is stored in an array, the array
is cleared each time you click on a column without holding control.
Telling the sort routine that only 1 column needs to be sorted.
If you press control while clicking another column that second column
is appended to the array and the columns are sorted in reverse order.
Accomplishing a “subsort”.

One other thing it does is save column widths for each instance of
the listctrl. To acheive this though you must call SetUniqueName.
Each instance needs a unique name to know where to save and retreive
column widths.

Usage:

You generally should not use this class directly, though it
is possible. You need to do two things to use it directly.
Set m_strUniqueName to someting, and set m_strColumnWidthSection
to where you want the column widths to be saved. m_strColumnWidthSection by
default is set to “ColumnWidths”.

The purpose of m_strUniqueName is to allow for saving of
multiple instances of listview objects. So obviously you would
need to set this differently for each instance. SetUniqueName must be called
before calling InsertColumn() or LoadColumnWidths().

If you are deriving from this class, you need to do the following:
Add a class to your project derived from CListView, then go into the
header file and include MultiColumnSortListView.h and change all
references to CListView to CMultiColumnSortListView. Then in the .cpp
file of your class, change all the message maps to CMultiColumnSortListView
instead of CListView. That should do it.

Functions you must call:

A sample CreateView:


< CMyListView is derived from CMultiColumnSortListView >

m_wndSplitter.CreateView( 0, 0, RUNTIME_CLASS( CMyListView ), CSize( 0, 200 ), pContext );
CMyListView *pView = (CMyListView *) m_wndSplitter.GetPane( 0, 0 );
pView->SetUniqueName( “MYVIEW1” );

Functions you dont need to call but may find useful:

  • SetColumnNumeric:

    This function tells the sorting routine that
    this column will contain only numeric data. It will not crash
    if there are string inside the column, it just wont sort them correctly.


    CMyListView *pView = GetTheListView();
    pView->SetColumnNumeric(2);
    pView->SetColumnNumeric(3);

  • IsSorting:

    This function will tell you if the listctrl
    is in the middle of being sorted.


    if( pView->IsSorting() )
    MessageBox(“Cannot sort, i am already sorting”);

Miscellaneous utility functions are also provided:

  • void CMultiColumnSortListView::DeleteAllColumns()

    Utility function to get rid of all the columns

  • void CMultiColumnSortListView::DeleteAllItems()

    Utility function to get rid of all items.

  • UINT CMultiColumnSortListView::GetColumnCount()

    Utility function to get the number of columns written by Zafir Anjum

  • const int CMultiColumnSortListView::IsControlPressed() const

    Utility function to tell you if the control key is being pressed

  • const SORT_STATE CMultiColumnSortListView::GetItemSortState( int iItem ) const

    Utility function to get you the sort state of a column

  • void CMultiColumnSortListView::SetItemSortState(int iItem, SORT_STATE bSortState)

    Utility function to set the sort state of a column

  • const int CMultiColumnSortListView::GetRegColumnWidth( int iColumn ) const

    Utility function to look up a columns width in the registry.

  • void CMultiColumnSortListView::AutoSizeAllColumns()

    Utility function to Autosize all columns in the case there is no registry entry.

  • void CMultiColumnSortListView::SetColumnWidth( int nCol )

    Utility function to set the width on the column based on the registry
    value and a set minimum column width.

Most of the functions have very descriptive names.

Compiling:

One problem you will have is finding IDB_ARROWUP and IDB_ARROWDOWN.
Those bitmaps will be included with this set of classes, You should
add them to your project or add your own bitmaps named correctly.
These are the bitmaps that show the sort order on the header control.

I hope this is simple enough, kind of a pain to get started but after
that it should be cake and hopefully it will be useful.

Things to be aware of:

Multithreading:
If you delete all the items from another thread
in the middle of a sort, it will crash. This is the only
bug i have found.

Column Widths:

MINCOLWIDTH – Minimum width a column can be.
MAXCOLWIDTH – Maximum width a column can be.

These are hard coded in the header file. Be aware.

MAXCOLUMNS – The most columns you can have right
now is 64, that is only because im using __int64 to
hold the column sort states. Who needs more than
64 columns anyway? If you do, you can change it to
CUIntArray, i just didnt see the need for a whole int
when all i needed was a bit.

Credits:

  • Iuri Apollonio — Sorting Class ( great class )
  • Zafir Anjum — CMultiColumnSortListView::GetColumnCount
  • Roger Onslow — CMultiColumnSortListView::AutoSizeColumns
  • Zafir Anjum — CSortableHeaderCtrl::SetSortImage
  • Me — The Rest, I think.

Last updated: 12 July 1998

More by Author

Must Read