在mfc对话框工程中采用了listctrl控件,需要点击控件列头,实现控件内容的自动排序,方法如下。
假设listctrl控件已经添加了控制变量 CListCtrl m_ListCtrl。
1、在.h文件中添加
public:
int sort_column; // 表示需要排序的列
static bool method; //类内申明
static int CALLBACK listCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
其中,method表示是升序还是降序,这是一个static变量。
2、设置排序规则。值得注意的是,这里根据列头的内容可能需要设置不同的排序规则。
在.cpp函数中添加:
bool CFeatureData::method = false; // 类外定义
int CALLBACK CFeatureData::listCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
DATA* pListCtrl = (DATA*)lParamSort;
int col = pListCtrl->subitem; //点击的列项传递给col,用来判断点击了第几列
//CString header[]={"姓名","年龄","编号"}; //假设现在的列头是这几项
//得到该列的前2项
CString strItem1 = (pListCtrl->plist)->GetItemText(lParam1, col);
CString strItem2 = (pListCtrl->plist)->GetItemText(lParam2, col);
if (col== 0) // CString
{
int tmp = strItem1.CompareNoCase(strItem2); //如果两个对象完全一致则返回0,如果小于lpsz,则返回-1。
if (method) // true--升序
{
if (tmp <= 0)
return -1;
else
return 1;
}
else
{
if (tmp >= 0)
return -1;
else
return 1;
}
}
else if (col== 1 || col==2 ) // int
{
__int64 n1=_atoi64(strItem1);
__int64 n2=_atoi64(strItem2);
if (method)//
{
if (n1 <= n2)
return -1;
else
return 1;
}
else
{
if (n1 >= n2)
return -1;
else
return 1;
}
}
return -1; // -1表示第一项在第二项前面,0表示两项相等
}
这里,列头有三项,其中第一项是姓名,按照string排序,第二三项是数字型,按照int型比较排序,上面的函数已经根据不同的列头设置了不同的排序规则。
3、设置listctrl列头的点击响应函数
打开资源视图下dialog中的需要设置listctrl排序的对话框,右键-->类向导—》命令,找到该listctrl控件名称IDC_LISTCTRL1—》单击找到其中对应的消息LVN_COLUMNCLICK--》添加处理程序后编辑代码。
4、修改响应函数代码。
将OnColumnClickList1函数改为:
void CFeatureData::OnColumnclickList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
sort_column = pNMLV->iSubItem;//点击的列
int count = m_ListCtrl.GetItemCount();
for (int i=0;i<count;i++)
m_ListCtrl.SetItemData(i,i);
DATA data;
data.subitem = sort_column;
data.plist = &m_ListCtrl;
method = !method;
//m_ListCtrl.SortItems(listCompare,(LPARAM)&m_ListCtrl);
m_ListCtrl.SortItems(listCompare,(LPARAM)&data);
*pResult = 0;
}
完成