先必须了解这些:
CListCtrl::SortItems
BOOL SortItems(PFNLVCOMPARE pfnCompare,DWORD dwData)
返回值:
如果成功,则返回非零值,否则为0。
参数:
pfnCompare |
应用定义的比较函数的地址。当需要比较两个列表项的相互关系而进行排序操作时,则调用比较函数。比较函数要么是类的静态成员,要么是不属于任何类的独立函数。 |
dwData |
应用定义的、传递给比较函数的值。 |
说明:
使用应用定义的比较函数对列表视图项进行排序。为了影响新的次序,每一项的索引需要做一些改变。
比较函数有下列形式:
int CALLBACK CompareFunc(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort);
如果第一项在第二项之前,则返回一个负值;若第一项在第二项之后,则返回一个正值;如果两者等价;则返回零。
参数lParam1和lParam2指定了要进行比较的两项的数据,而参数lParamSort与dwData值相同。
-----------------------------传说中的分割线------------------------------
代码开始:
struct DATA
{
CListCtrl *plist;
int col;
};//回调函数第三个参数对应的数据结构,可以自定义,至少要包含这两项
bool fav=false; //排序方法(递增或递减)
int CALLBACK MylistCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{/*回调函数,第一二个参数是列表其中两项(行)相关联的32位值(通常是个指向某一结构的指针),第三个是用户自定义的参数(DATA *)*/
DATA* MyData = (DATA*)lParamSort;
int col = MyData->col;//点击的列项传递给col,用来判断点击了第几列
//取项的字符串
CString strItem1, strItem2;
strItem1=MyData-> plist-> GetItemText((int)lParam1,col);
strItem1=MyData-> plist-> GetItemText((int)lParam2,col);
if(col==0)
{//第一列,对比整型数
char ch1[MAX_PATH],ch2[MAX_PATH];
wsprintfA(ch1, "%s", (LPCTSTR)strItem1);
wsprintfA(ch2, "%s", (LPCTSTR)strItem2);
if(fav)
return (atoi(ch1)-atoi(ch2));
else
return (atoi(ch2)-atoi(ch1));
}
else if(col==1)
{//第二列,对比浮点数(其他字符串比较太简单了,不值得列出^_^)
wsprintfA(ch1, "%s",(LPCTSTR)cstr);
wsprintfA(ch2, "%s",(LPCTSTR)cstr2);
if(fav)
return (int)(100*(atof(ch1)-atof(ch2))); //精确到小数点后两位(可修改)
else
return (int)(100*(atof(ch2)-atof(ch1)));
}
return 0;
}
/*给CListCtrl添加LVN_COLUMNCLICK(点击列表的列)消息响应函数,注:也可以将函数内的代码添加到你需要的地方*/
void CXxxxDlg::OnLvnColumnclickList1 (NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
DATA data;
data.col = pNMLV->iSubItem; //取列
data.plist = &m_list1; //取列表指针
fav=!fav; //排序每点一次列就变一次,若想固定排序,那就去掉这句
//设置列表项相关项,以便于排序
int len=m_list1.GetItemCount();
for(int i=0;i<len;i++)
{
m_list1.SetItemData(i,(DWORD_PTR)i); //列表项相关项设为项号
}
m_list1.SortItems(MylistCompare,(LPARAM)&data);
*pResult = 0;
}