您的位置:首页 > 其它

ListCtrl点击表头排序的总结

2013-03-07 18:05 387 查看
要使用CListCtrl点击表头进行排序的功能:

    对ListCtrl排序的总结;

    记得还要添加Sort属性(在资源里)

    要实现这个功能,首先要调用c_lstRcdData.SetItemData(i,i);遍历每一个元素,

    然后就是点击表头的消息处理了,注意:这里非常关键,因为有两个消息都可以响

应表头被点击的的操作,一个标准的是void UCFVDataSel::OnColumnclickListRcddata(NMHDR *pNMHDR, LRESULT *pResult);

但是在排序里面不要用这个,因为它传的第一个参数老是出问题,所有用另一个:

void UCFVDataSel::OnItemclickListRcddata(NMHDR *pNMHDR, LRESULT *pResult);这个虽然看起来不像

点击表头触发的消息,但是它确实是啊,贴一段我完整的关于这个消息处理的函数:

void UCFVDataSel::OnItemclickListRcddata(NMHDR *pNMHDR, LRESULT *pResult)

{
LPNMHEADER pNMLV = reinterpret_cast<LPNMHEADER>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
static int sSortColumn = 0;

//让它不显示上下三角
HDITEM hdrItem;
c_lstRcdData.GetHeaderCtrl()->GetItem(sSortColumn, &hdrItem);
hdrItem.mask = HDI_FORMAT;
hdrItem.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP);
c_lstRcdData.GetHeaderCtrl()->SetItem(sSortColumn, &hdrItem);

//点击相同列,排序方式变反。
//点击不同列,升序排列
static int nAsc = 1;
if(sSortColumn == pNMLV->iItem)
{
nAsc = - nAsc;
}
else
{
sSortColumn = pNMLV->iItem;
nAsc = 1;
}

//显示上三角或下三角
c_lstRcdData.GetHeaderCtrl()->GetItem(sSortColumn, &hdrItem);
hdrItem.mask = HDI_FORMAT;
if(nAsc == 1)
{
hdrItem.fmt |= HDF_SORTUP;
hdrItem.fmt &= ~HDF_SORTDOWN;
}
else
{
hdrItem.fmt |= HDF_SORTDOWN;
hdrItem.fmt &= ~HDF_SORTUP;
}
c_lstRcdData.GetHeaderCtrl()->SetItem(sSortColumn, &hdrItem);

PSORTDATA pSortData = new SORTDATA;
pSortData->nAsc = nAsc;
pSortData->pList = &c_lstRcdData;
pSortData->nSubItem = sSortColumn;
c_lstRcdData.SortItems(SortFunc,(DWORD_PTR)pSortData);

*pResult = 0;

}

其它的注释已经很清楚了,大家运行一下就知道是什么了,需要注意看的是倒数第二句代码

c_lstRcdData.SortItems(SortFunc,(DWORD_PTR)pSortData);这就是API,第一个是回调函数,第二个参数是

回调函数的参数,我把完整的回调函数也贴出来了

///////////////////////////////////////////////////////

/// \brief

///  自定义排序函数

/// 

/// \param lParam1

///  第一行数据

///

/// \param lParam2

///  第二行数据

///

/// \param lParamSort

///  自定义数据结构SortData类型变量,SortItems()函数的第二个参数

///

/// \return 

///  第一个数据大于第二个数据返回正数,否则返回负数

int CALLBACK SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)

{
PSORTDATA pSortData = (PSORTDATA) lParamSort;
CListCtrl *pList = pSortData->pList;
int nSubItem = pSortData->nSubItem;
int nAsc = pSortData->nAsc;

//find item index
LVFINDINFO  findInfo;
findInfo.flags = LVFI_PARAM;
findInfo.lParam = lParam1;
//1st index
int nPrevIndex = pList->FindItem(&findInfo, -1);
findInfo.lParam = lParam2;
//2nd index
int nNextIndex = pList->FindItem(&findInfo, -1);

//get item string
CString strPrev = pList->GetItemText(nPrevIndex, nSubItem);
CString strNext = pList->GetItemText(nNextIndex, nSubItem);

int prev = 0, next = 0;
switch ( nSubItem )
{
case  0:
prev = _ttol(strPrev);
next = _ttol(strNext);
if (prev > next)
return nAsc;
else
return -nAsc;
case  1:
strPrev.Replace( _TEXT("/"),_TEXT("") );
strNext.Replace( _TEXT("/"),_TEXT("") );
strPrev.Replace( _TEXT(":"),_TEXT("") );
strNext.Replace( _TEXT(":"),_TEXT("") );
strPrev.Replace( _TEXT(" "),_TEXT("") );
strNext.Replace( _TEXT(" "),_TEXT("") );
prev = _ttol(strPrev);
next = _ttol(strNext);
if (prev > next)
return nAsc;
else
return -nAsc;
default:
return _tcscmp(strPrev, strNext) * nAsc;
}

}

只需几步,我们的功能就实现了,哦对了,还有这个结构

/// ListCtrl排序用的结构

typedef struct SortData

{
int nAsc;
//1或-1
CListCtrl *pList;
int nSubItem;

} SORTDATA, * PSORTDATA;

完整的代码在我的资源里面,资源名字叫《ListCtrl分页》,因为同时实现了分页显示和排序的功能

注意!!!!!!

      排序有一个问题就是ListCtrl会屏蔽掉内容相同的项,一定要注意这个问题
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ListCtrl排序