上一篇讲解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)两种排序的第二种

CList 点击表头排序 (2)两种排序方法中其中一种的更多相关文章

  1. CList 点击表头排序 (3)两种排序的第二种

    在头两篇中介绍了CListCtrl::SortItems() 方法的使用和其中的一个排序方法,这篇介绍另一种方法 CList 点击表头排序 (1)SortItems函数 CList 点击表头排序 (2 ...

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

    点击表头排序整体的思路都是去 CListCtrl类中的方法SortItems去实现 CListCtrl::SortItems的原型是: BOOL SortItems( PFNLVCOMPARE pfn ...

  3. JAVA文件的两种读取方法和三种写入方法

    在使用java对文件进行读写操作时,有多种方法可以使用,但不同的方法有不同的性能. 此文对常用的读写方法进行了整理,以备不时之需. 1.文件的读取 主要介绍两种常用的读取方法.按行读取和按字符块读取. ...

  4. Qt中事件处理的方法(三种处理方法,四种覆盖event函数,notify函数,event过滤,事件处理器。然后继续传递给父窗口。可观察QWidget::event的源码,它是虚拟保护函数,可改写)

    一.Qt中事件处理的方式   1.事件处理模式一 首先是事件源产生事件,最后是事件处理器对这些事件进行处理.然而也许大家会问, Qt中有这么多类的事件,我们怎么样比较简便的处理每个事件呢?设想,如果是 ...

  5. 非常强大的table根据表头排序,点击表头名称,对其内容排序

    js代码: /** * 通过表头对表列进行排序 * * @param sTableID * 要处理的表ID<table id=''> * @param iCol * 字段列id eg: 0 ...

  6. EasyUI Datagrid 分页的情况下实现点击表头的小三角图标对数据库中所有数据重新排序

    说明一下: 当点击 datagrid 表头某一列的小三角图标时,easyui 本身是有排序的,但是在当我们对 datagrid 进行了分页的情况下,点击排序只是对当前页的数据进行排序,而需求需要我对数 ...

  7. android studio gradle 两种更新方法更新

    android studio gradle 两种更新方法更新 第一种.Android studio更新 第一步:在你所在项目文件夹下:你项目根目录gradlewrappergradle-wrapper ...

  8. Linux系统中存储设备的两种表示方法

    转:https://blog.csdn.net/holybin/article/details/38637381 一.对于IDE接口的硬盘的两种表示方法: 1.IDE接口硬盘,对于整块硬盘的两种表示方 ...

  9. iOS中 三种随机数方法详解

    ios 有如下三种随机数方法: //第一种 srand((unsigned)time(0)); //不加这句每次产生的随机数不变 int i = rand() % 5; //第二种 srandom(t ...

随机推荐

  1. Java,泛型类型通配符和C#对照

    c#的泛型没有类型通配符,原因是.net的泛型是CLR支持的泛型,而Java的JVM并不支持泛型,仅仅是语法糖,在编译器编译的时候都转换成object类型 类型通配符在java中表示的是泛型类型的父类 ...

  2. python学习之--SyntaxError: Non-ASCII character '\xe5'

    在安装好eclipse之后试了一下 创建了了一个pydev project package.module 在test.py中编写最简单的命令 print "helloworld" ...

  3. 111.final与override

    #include <iostream> using namespace std; class myclass { public: //后面加一个final,则禁止虚函数被子类重写 //fi ...

  4. Weka中数据挖掘与机器学习系列之Weka3.7和3.9不同版本共存(七)

    不多说,直接上干货! 为什么,我要写此博客,原因是(以下,我是weka3.7.8) 以下是,weka3.7.8的安装版本. Weka中数据挖掘与机器学习系列之Weka系统安装(四) 基于此,我安装最新 ...

  5. ubuntu server 网络配置,主机名配置

    一.通过命令ifconfig -a 查看可用网络设备 通过上面的命令,本机可用的网络设备为enp4s0f0 和enp4s0f1 ,不同的系统版本和硬件配置网络设备名可能不一样,所以一定要先确认本机可用 ...

  6. Flex之柱状图实例

    Flex之柱状图实例 <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns ...

  7. javaScript for in循环遍历对象

    for循环常被我们用来遍历数组,而如何遍历对象呢? 这时就需要用到for in循环了 写一个遍历对象名简写如下: for(var xxx in ooo){console.log(xxx)} 其中xxx ...

  8. Mysql学习总结(11)——MySql存储过程与函数

    摘要:存储过程和函数是在数据库中定义一些SQL语句的集合,然后直接调用这些存储过程和函数来执行已经定义好的SQL语句.存储过程和函数可以避免开发人员重复的编写相同的SQL语句.而且,存储过程和函数是在 ...

  9. java设计模式--事件监听器模式(观察者模式)

    这两个模式实质上很简单,在实际项目中也是非常常用的.但却被有些人说的云里雾里,这里用白话解释一下. 本质上两者都是同一个模式.专业的说法是这样的(觉得绕口的请直接转到白话解释部分,再回头来看下面这几句 ...

  10. 关于app.FragmentManager和v4包的FragmentPagerAdapter冲突

    这几天发现一个问题我用getFragmentManager()得到FragmentManager不能放到FragmentPagerAdapter里面去.由于FragmentPagerAdapter里面 ...