通过以下方法可以实现排序的。
先贴两个数据结构
// 列表数据行(可以不定义,直接写即可)
typedef struct _student_info
{
CString strName;
CString strBirthday;
CString strSex;
CString strUID;
int nLevel;
}StudentInfo;
// 排序配置选项
typedef struct _list_sort_opt
{
CListCtrl* pList;
int nCol;
bool bInc;
}ListSortOpt;
1.准备数据(列表中的先有数据)
void CtestDlg::InsertItemToList( const StudentInfo& siItem )
{
int nItem = m_list.GetItemCount();
int nSubItem = 1;
CString strLevel;
strLevel.Format(_T("%d"), siItem.nLevel);
m_list.InsertItem(nItem, (LPCTSTR)siItem.strName);
m_list.SetItemText(nItem, nSubItem++, (LPCTSTR)siItem.strBirthday);
m_list.SetItemText(nItem, nSubItem++, (LPCTSTR)siItem.strSex);
m_list.SetItemText(nItem, nSubItem++, (LPCTSTR)siItem.strUID);
m_list.SetItemText(nItem, nSubItem++, (LPCTSTR)strLevel);
}
void CtestDlg::OnBnClickedButton1()
{
StudentInfo s;
int nLen = 0;
srand(GetTickCount());
for (int i=0; i<64; i++)
{
s.strName = "";
nLen = rand()%4+4;
for (int j=0; j<nLen; j++)
{
s.strName.AppendChar('A'+rand()%26);
}
s.strBirthday.Format(_T("%4d-%02d-%02d"), 1980+rand()%30, rand()%12+1, rand()%28+1);
s.strSex = rand()%2 ? _T("男") : _T("女");
s.strUID = "";
nLen = 8;
for (int j=0; j<nLen; j++)
{
s.strUID.AppendChar('0'+rand()%10);
}
s.nLevel = rand()%8;
InsertItemToList(s);
}
}
2.响应消息LVN_COLUMNCLICK
void CtestDlg::OnColumnclickList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
// TODO: Add your control notification handler code here
*pResult = 0;
}
3.设置排序选项:
SetItemData:设置回调函数的LPARAM lParam1, LPARAM lParam2这两个项(每次排序前都得重新设置)
// 设置SortFunc的前两个参数的内容格式
// 每次排序前都要重新设置
for (int i=0; i<m_list.GetItemCount(); i++)
{
m_list.SetItemData(i, i);
}
4.实现自定义的回调比较函数SortFunc
int CALLBACK CtestDlg::SortFunc( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort )
{
CString strData1;
CString strData2;
ListSortOpt* p = (ListSortOpt*)lParamSort;
int nRet = 0;
strData1 = p->pList->GetItemText((int)lParam1, p->nCol);
strData2 = p->pList->GetItemText((int)lParam2, p->nCol);
if(p->nCol < 4)
{
if(p->bInc)
{
nRet = strData1.Compare(strData2);
}
else
{
nRet = strData2.Compare(strData1);
}
}
else
{
int nLevel1 = StrToInt(strData1);
int nLevel2 = StrToInt(strData2);
if(p->bInc)
{
nRet = nLevel1 > nLevel2;
}
else
{
nRet = nLevel2 > nLevel1;
}
}
return nRet;
}
5.功能圆满,调用排序函数:调用m_list.SortItem函数
m_list.SortItems(SortFunc, (DWORD_PTR)&sortOpt);
整体形如:
void CtestDlg::InitList()
{
//设置列表风格
LONG styles;
styles = GetWindowLong(m_list.m_hWnd,GWL_STYLE);
styles &= ~LVS_TYPEMASK;
styles |= LVS_REPORT ;
SetWindowLong(m_list.m_hWnd,GWL_STYLE,styles);
m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
int nCol = 5;
int nCurCol = 0;
CRect rtList;
int nWidth = 0;
m_list.GetClientRect(&rtList);
nWidth = rtList.Width() / nCol;
m_list.InsertColumn(nCurCol++, _T("姓名"), 0, nWidth);
m_list.InsertColumn(nCurCol++, _T("生日"), 0, nWidth);
m_list.InsertColumn(nCurCol++, _T("籍贯"), 0, nWidth);
m_list.InsertColumn(nCurCol++, _T("UID"), 0, nWidth);
m_list.InsertColumn(nCurCol++, _T("等级"), 0, nWidth);
}
int CALLBACK CtestDlg::SortFunc( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort )
{
CString strData1;
CString strData2;
ListSortOpt* p = (ListSortOpt*)lParamSort;
int nRet = 0;
// 这里的lParam1和lParam2的类型即为之前SetItemData的第二个参数的类型
strData1 = p->pList->GetItemText((int)lParam1, p->nCol);
strData2 = p->pList->GetItemText((int)lParam2, p->nCol);
if(p->nCol < 4)
{
if(p->bInc)
{
nRet = strData1.Compare(strData2);
}
else
{
nRet = strData2.Compare(strData1);
}
}
else
{
int nLevel1 = StrToInt(strData1);
int nLevel2 = StrToInt(strData2);
if(p->bInc)
{
nRet = nLevel1 > nLevel2;
}
else
{
nRet = nLevel2 > nLevel1;
}
}
return nRet;
}
void CtestDlg::OnColumnclickList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<lpnmlistview>(pNMHDR);
// TODO: Add your control notification handler code here
static int nCol = -1;
static ListSortOpt sortOpt = {&m_list, 0, true};
// 升序还是降序?
if(nCol == pNMLV->iSubItem)
{
sortOpt.bInc = !(sortOpt.bInc);
}
nCol = pNMLV->iSubItem;
sortOpt.nCol = nCol;
// 设置SortFunc的前两个参数的内容格式
// 每次排序前都要重新设置
for (int i=0; i<m_list.GetItemCount(); i++)
{
m_list.SetItemData(i, i);
}
m_list.SortItems(SortFunc, (DWORD_PTR)&sortOpt);
*pResult = 0;
}
void CtestDlg::InsertItemToList( const StudentInfo& siItem )
{
int nItem = m_list.GetItemCount();
int nSubItem = 1;
CString strLevel;
strLevel.Format(_T("%d"), siItem.nLevel);
m_list.InsertItem(nItem, (LPCTSTR)siItem.strName);
m_list.SetItemText(nItem, nSubItem++, (LPCTSTR)siItem.strBirthday);
m_list.SetItemText(nItem, nSubItem++, (LPCTSTR)siItem.strSex);
m_list.SetItemText(nItem, nSubItem++, (LPCTSTR)siItem.strUID);
m_list.SetItemText(nItem, nSubItem++, (LPCTSTR)strLevel);
}
void CtestDlg::OnBnClickedButton1()
{
StudentInfo s;
int nLen = 0;
srand(GetTickCount());
for (int i=0; i<64; i++)
{
s.strName = "";
nLen = rand()%4+4;
for (int j=0; j<nLen; j++)
{
s.strName.AppendChar('A'+rand()%26);
}
s.strBirthday.Format(_T("%4d-%02d-%02d"), 1980+rand()%30, rand()%12+1, rand()%28+1);
s.strSex = rand()%2 ? _T("男") : _T("女");
s.strUID = "";
nLen = 8;
for (int j=0; j<nLen; j++)
{
s.strUID.AppendChar('0'+rand()%10);
}
s.nLevel = rand()%8;
InsertItemToList(s);
}
}
</lpnmlistview>