Link to home
Start Free TrialLog in
Avatar of jayku
jayku

asked on

CListCtrl.. sort on column 2

Hi,
I have a listctrl in a dialog box. I want to sort if the user clicks on the column. So i mapped the message "LVN_COLUMNCLICK" and call the sort function(which is static member function) and pass pointer to listctrl as the paramter.. as
m_lstFiles.SortItems( SortFunc, &m_lstFiles);

In the sort function how do I get the data in the second column. I tried using GetItemText but returns the text of first column always.? The two columns are FileName and FileSize. I want to sort on file size?
Please write the entire function for me to cut and paste. I have given good points and will consider increasing it..
ASKER CERTIFIED SOLUTION
Avatar of chensu
chensu
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Sorting list based on integers in any column
http://www.codeguru.com/listview/simple_sort_on_integer_col.shtml

Sorting the list when user clicks on column header
http://www.codeguru.com/listview/sort_on_col_click.shtml
Greetings Jayku,
Here's a description that should answer your problems.

Sorting the list when user clicks on column header

--------------------------------------------------------------------------------
If you don’t 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. You may choose to sort the items in a different manner.

Step 1: 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)
 Note that we specify the same function for both the notification. Actually the program will receive one or the other and not both. What notification it receives will depend on the OS. The list view control on Windows 95 will send the ANSI version and the control on NT will send the UNICODE version.
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
Here’s 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. Use the Sort() function that you have developed in place of the one I have put in there. 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;
                SortItems( nSortedCol, bSortAscending );

        }
        *pResult = 0;
}
 
Avatar of jayku
jayku

ASKER

Adjusted points to 1100
Avatar of jayku

ASKER

Yeah! this cleared all my questions and I was able to implement what I wanted.

Execellent help..100 bonus points..enjoy

Thanks

Jayant