CList 点击表头排序 (2)两种排序方法中其中一种

时间:2021-08-23 18:54:24

上一篇讲解SortItem()方法如何使用,虽然都是抄别人的但是就是想让大家有个大概的了解

CList 点击表头排序 (1)SortItems函数

点击表头排序基本思路都是

1.首先响应HDN_ITEMCLICK 消息来获取点击表头的位置

2.设置结构体来存储排序信息,结构体信息主要有三个 (1)CListCtrl的指针,(2)点击第几列的列数,(3)排序,主要以int型为主

3.获取当前行的内容和下一行的内容

4.使用SortItems函数来进行排序,SortItems函数如何使用我在上一篇已经提到CList 点击表头排序 (1)SortItems函数

第一种排序是使用SetItemDate和GetItemDate来进行位置的定位和要比对的单元格的内容的获取,缺点是如果你要想使用SetItemDate存放个数据的话,例如结构体,那么排序则会失效

(1)首先响应消息ON_NOTIFY(HDN_ITEMCLICK, 0, &CFinishWellToFind::OnLvnColumnclickListFinishWell)

(2)实现方法

  void CFinishWellToFind::OnLvnColumnclickListFinishWell(NMHDR *pNMHDR, LRESULT *pResult)

{ 

////排序第一种
 NMLISTVIEW *pLV = (NMLISTVIEW *) pNMHDR;

//int column and asc
 static int sSortColumn = 0;

//init New head ctrl,让它不显示上下三角
 HDITEM hdrItem; 
 //int iColumn = pLV->iSubItem;
 m_ListCtrl.GetHeaderCtrl()->GetItem(sSortColumn, &hdrItem);
 hdrItem.mask = HDI_FORMAT;
 hdrItem.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP);
 m_ListCtrl.GetHeaderCtrl()->SetItem(sSortColumn, &hdrItem);

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

//init new head ctrl,显示上三角或下三角
 m_ListCtrl.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;
 }
 m_ListCtrl.GetHeaderCtrl()->SetItem(sSortColumn, &hdrItem);

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

 }

(3)内容绑定   注*如果缺少内容绑定的话,则排序一定不会成功

其中,nItem是CListCtrl的行,dwData是一个32位的值,这个值是和该行相绑定的。通常这个值是作为lparam使用。

如果不使用SetItemData设置时,默认的lparam都是0,所以同学在排序的时候lParam1和lParam2一直是0。

故只要在Init()中添加下述代码就可以正确实现排序了:

  m_ListCtrl.SetItemData(i,i);

(3)实现内容比对方法

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);

//if (nSubItem ==  2)
 //{
 // int prev = _ttol(strPrev);
 // int next = _ttol(strNext);
 // if (prev > next)
 //  return nAsc;
 // else
 //  return -nAsc;
 //}
 return wcscmp(strPrev, strNext) * nAsc;

}

下一篇我来说说如果不用SetItemDate如何来实现点击表头排序 CList 点击表头排序 (3)两种排序的第二种