1. CSortList是CListCtrl的派生类。

2. 要让CSortList自行排序,当然得让CSortList自己处理LVN_COLUMNCLICK消息

    ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnLvnColumnclick)
    OnLvnColumnclick的作用就是设置排序列,排序方式,最后调用SortItems()。

3. 排序的具体实现,也就是CALLBACK ListCompare(...)的实现:
    基本要求: 让CSortList根据Item进行排序,而与数据源无关。(当然这样也有不足之处,就是排序只能按文本排序了。如果你需要按数字排序的话,那就只有特殊处理了。)

   这里涉及到的最主要的函数是:
   (1)ListCompare - 实现排序的回调函数
   int CALLBACK CSortList::ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
   (2)CListCtrl::FindItem - 查找相应的Item, 查找方式可指定
   int FindItem( LVFINDINFO* pFindInfo, int nStart = -1 ) const;
   FindItem的具体细节请参考MSDN.
  
   基本思路:
   (1)ListCompare的原型:传入的参数lParam1,lParam2是相应两行的ItemData;
   (2)FindItem根据lParam1,lParam2得到相应的Item;
   FindItem有多种查找方式(查找方式通过LVFINDINFO->flags进行设置),这里只是根据ItemData进行查找。
   (3)再用GetItemText得到排序列的ItemText;
   (4)最后就是比较ItemText了。

下面是源代码:
只有两个文件:CSortListCtrl.H, CSortListCtrl.cpp
直接把这两个文件放到项目里就可以了。
/Files/amazon/CSortListCtrl.rar

在对话框程序C***Dlg中,可添加如下初始化信息,设置控件的风格和扩展风格。注意要根据HDITEM类型变量和CHeaderCtrl::SetItem函数设置列的类型属性。

CSortListCtrl m_test;

// 初始化控件
 DWORD dwStyle  =  ::GetWindowLong(m_test.m_hWnd, GWL_STYLE); 
 dwStyle 
&=   ~ (LVS_TYPEMASK);
 dwStyle 
&=   ~ (LVS_EDITLABELS);
 
// 设置新风格
 SetWindowLongW(m_test.m_hWnd, GWL_STYLE, dwStyle | LVS_REPORT | LVS_NOLABELWRAP | LVS_SHOWSELALWAYS);
 
// 设置扩展风格
 DWORD styles  =  LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES;
 ListView_SetExtendedListViewStyleEx(m_test.m_hWnd, styles, styles);
 m_test.SetExtendedStyle(m_test.GetExtendedStyle() 
|  LVS_EX_SUBITEMIMAGES);

 HDITEM headerItem;
 headerItem.mask 
=  HDI_LPARAM;
 CHeaderCtrl
*  pHeaderCtrl  =  m_test.GetHeaderCtrl( );

 m_test.InsertColumn(
0 , _T( " 歌曲 " ), LVCFMT_LEFT,  150 );
 .
..

 headerItem.lParam 
=  CSortListCtrl::DATA_TYPE::STRING_TYPE;
 pHeaderCtrl
-> SetItem( 0 & headerItem);
 .
..