Sorting the list when user clicks on column header
Posted
by Zafir Anjum
on August 6th, 1998
If you dont want to allow the users to sort the list by clicking on the header, you can use the style LVS_NOSORTHEADER. However, if you do want to allow sorting, you do not specify the LVS_NOSORTHEADER. The control, though, does not sort the items. You have to handle the HDN_ITEMCLICK notification from the header control and process it appropriately. In the code below, we have used the sorting function SortTextItems() developed in a previous section. You may choose to sort the items in a different manner.
Step 1: Add two member variables
Add two member variables to the CListCtrl. The first variable to track which column has been sorted on, if any. The second variable to track if the sort is ascending or descending.
int nSortedCol;
BOOL bSortAscending;
Step 2: Initialize them in the constructor.
Initialize nSortedCol to -1 to indicate that no column has been sorted on. If the list is initially sorted, then this variable should reflect that.nSortedCol = -1;
bSortAscending = TRUE;
Step 3: Add entry in message map to handle HDN_ITEMCLICK
Actually you need to add two entries. For HDN_ITEMCLICKA and HDN_ITEMCLICKW. Do not use the class wizard to add the entry. For one, you need to add two entries whereas the class wizard will allow you only one. Secondly, the class wizard uses the wrong macro in the entry. It uses ON_NOTIFY_REFLECT() instead of ON_NOTIFY(). Since the HDN_ITEMCLICK is a notification from the header control to the list view control, it is a direct notification and not a reflected one.- ON_NOTIFY(HDN_ITEMCLICKA, 0, OnHeaderClicked)
ON_NOTIFY(HDN_ITEMCLICKW, 0, OnHeaderClicked)
Also, note that the second argument is zero. This value filters for the id of the control and we know that header control id is zero.
Step 4: Write the OnHeaderClicked() function
Heres where you decide what to do when the user clicks on a column header. The expected behaviour is to sort the list based on the values of the items in that column. In this function we have used the SortTextItems() function developed in a previous section. If any of the columns displays numeric or date values, then you would have to provide custom sorting for them.void CMyListCtrl::OnHeaderClicked(NMHDR* pNMHDR, LRESULT* pResult)
{
HD_NOTIFY *phdn = (HD_NOTIFY *) pNMHDR;
if( phdn->iButton == 0 )
{
// User clicked on header using left mouse button
if( phdn->iItem == nSortedCol )
bSortAscending = !bSortAscending;
else
bSortAscending = TRUE;
nSortedCol = phdn->iItem;
SortTextItems( nSortedCol, bSortAscending );
}
*pResult = 0;
}

Comments
hnCDi MgW YDrf
Posted by xiFZfhMHBG on 11/15/2012 02:31pmsoma drug can i buy soma online - soma in urine drug screen
ReplyThe HDN_ITEMCLICK is not sent to the CMyListCtrl, why?
Posted by cwgk_zc on 07/02/2006 03:45pmI do it following the steps above. I derive a class CMListCtrl from CListCtrl and then go as the steps. At last, I declare a variable CMyListCtrl m_list which is from resource. I insert three columns but when I click the headers, nothing happened. Can anyone tell me the reason? If send me the source code, this is very good.
-
ReplyIt's sent to the parent (us. a dialog) instead
Posted by Mr. X on 10/03/2007 11:36amThe notification is sent to the parent - usually a dialog. You'll need to read up on the reflection mechanism (the MFC one, not the .NET one).
ReplySortTextItems?
Posted by mathieu1975 on 05/01/2006 01:46pmWhat is the SortTextItems doing? how do you sort the list? (manually? do a predefined method exist already?)
-
ReplySortTextItems
Posted by Mr. X on 10/04/2007 08:41amI just call my method RefreshList(), which I use in several places. It does the following: 1. creates a Clist of any selected items 2. Clears the CListCtrl 3. Requests & populates list data afresh 4. Uses the CList from 1. to restore the selected items 5. Calls my method - SortList() SortList() is just a switch which sets a function pointer to the appropriate compare-function to sort based on the selected column. It then calls CListCtrl::SortItems - the CListCtrl's built-in sort method: void CMyDlg::SortList() { PFNLVCOMPARE pfnCompare = NULL; // Pointer to compare function switch( m_nSortedCol ) { case COLUMN_PROMPT_ID: // Sort by ID pfnCompare = CMyDlg::CompareIds; break; case COLUMN_PROMPT_NAME: // Sort by file name pfnCompare = CMyDlg::CompareNames; break; case COLUMN_PROMPT_TIME: // Sort by date-time default: pfnCompare = CMyDlg::CompareTimes; break; } m_ctrListFailedPrompts.SortItems( pfnCompare, (LPARAM)this ); }ReplyNice and Simple.Great!!!
Posted by Legacy on 12/12/2003 12:00amOriginally posted by: Danushka Menikkumbura
This helped me a lot.Nice work.Thanks a lot.
ReplyIt worked! Thank you!
Posted by Legacy on 06/04/2003 12:00amOriginally posted by: zhangyi
ReplyThanx for the Info....very helpful
Posted by Legacy on 05/14/2003 12:00amOriginally posted by: Vikas Hegde
ReplyThank you Zafir...The callback function gave me problems....This saved a lot of my time.A very useful aricle.
Anyone got a work around for this to work with Integer columns
Posted by Legacy on 04/25/2003 12:00amOriginally posted by: LizardKing
This works great for String or Character based columns however numeric based columns get sorted incorrectly ( I know that this was pointed out in article) - Just wondering has anyone modified it to work on Integer based columns and if so , could they share the knowledge :)
Cheers
LK--<
ReplyThanks a lot!
Posted by Legacy on 04/10/2003 12:00amOriginally posted by: Ligh56t
It's a good idea to make a message entry by myself.
Thank you to let me know that
Since the HDN_ITEMCLICK is a notification from the header control to the list view control, it is a direct notification and not a reflected one.
Reply
dang
Posted by Legacy on 10/09/2002 12:00amOriginally posted by: amit gupta
its very good but we want complete FAQ in a proper sequence
ReplyIt Worked
Posted by Legacy on 07/29/2002 12:00amOriginally posted by: Sheethal Shneoy
Thanks Zafirji,Works absolutel fine.
ReplyLoading, Please Wait ...