在ListCtrl中进行排序

  列表控件(CListCtrl)的顶部有一排按钮,用户可以通过选择不同的列来对记录进行排序。但是
CListCtrl并没有自动排序的功能,我们需要自己添加一个用于排序的回调函数来比较两个数据的大小,此外还需要响应排序按钮被点击的消息。下面讲述一下具体的做法。

  CListCtrl提供了用于排序的函数,函数原型为:BOOL CListCtrl::SortItems( PFNLVCOMPARE
pfnCompare, DWORD dwData
)。其中第一个参数为全局排序函数的地址,第二个参数为用户数据,你可以根据你的需要传递一个数据或是指针。该函数返回-1代表第一项排应在第二项前面,返回1代表第一项排应在第二项后面,返回0代表两项相等。

  用于排序的函数原形为:int
CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM
lParamSort),其中第三个参数为调用者传递的数据(即调用SortItems时的第二个参数dwData)。第一和第二个参数为用于比较的两项的ItemData,你可以通过DWORD
CListCtrl::GetItemData( int nItem )/BOOL CListCtrl::SetItemData( int nItem,
DWORD dwData
)来对每一项的ItemData进行存取。在添加项时选用特定的CListCtrl::InsertItem也可以设置该值。由于你在排序时只能通过该值来确定项的位置所以你应该比较明确的确定该值的含义。

  最后一点,我们需要知道什么时候需要排序,实现这点可以在父窗口中对LVN_COLUMNCLICK消息进行处理来实现。


  下面我们看一个例子,这个例子是一个派生类,并支持顺序/倒序两种方式排序。为了简单我对全局数据进行排序,而在实际应用中会有多组需要排序的数据,所以需要通过传递参数的方式来告诉派序函数需要对什么数据进行排序。

一、在父窗口中对LVN_COLUMNCLICK消息进行处理来实现

二、.h头文件:

static int sort_column; // 记录点击的列
 static bool method; //
记录比较方法
 static int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM
lParam2, LPARAM lParamSort);

三、.cpp文件实现:

1  int CViewFileDlg::sort_column = 0; // 记录点击的列
2 bool CViewFileDlg::method = true;; // 记录比较方法


 //处理消息
1 void CViewFileDlg::OnLvnColumnclickList1(NMHDR *pNMHDR, LRESULT *pResult)
2 {
3 LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
4 // TODO: Add your control notification handler code here
5 CViewFileDlg::sort_column = pNMLV->iSubItem;//点击的列
6 int count = m_listcontrol.GetItemCount();
7
8 for (int i=0;i<count;i++)
9 m_listcontrol.SetItemData(i,i); // 每行的比较关键字,此处为列序号(点击的列号),可以设置为其他比较函数的第一二个参数
10 m_listcontrol.SortItems(MyCompareProc,(DWORD_PTR)&m_listcontrol);//排序第二个参数是比较函数的第三个参数
11
12 //取反排序模式后,才能进行下次排序
13 CViewFileDlg::method = !CViewFileDlg::method;
14
15 *pResult =0;
16 }


//排序函数实现
1 int CALLBACK CViewFileDlg::MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
2 {
3 // 从参数中提取所需比较lc的两行数据
4 int row1 = (int) lParam1;
5 int row2 = (int) lParam2;
6 CListCtrl* lc = (CListCtrl*)lParamSort;
7
8 CString lp1 = lc->GetItemText(row1, sort_column);
9 CString lp2 = lc->GetItemText(row2, sort_column);
10
11 // 比较,对不同的列,不同比较,注意记录前一次排序方向,下一次要相反排序
12 if (sort_column == 0 || sort_column == 2) //根据列的数据类型选择比较的类型
13 {
14 // int型比较
15 if (method)
16 return atoi(lp1)-atoi(lp2);
17 else
18 return atoi(lp2)-atoi(lp1);
19 }
20 else
21 {
22 // 文字型比较
23 if (method)
24 return lp1.CompareNoCase(lp2);
25 else
26 return lp2.CompareNoCase(lp1);
27 }
28 return 0;
29 }

在ListCtrl中进行排序

时间: 2024-10-12 10:13:23

在ListCtrl中进行排序的相关文章

Hadoop学习笔记—11.MapReduce中的排序和分组

一.写在之前的 1.1 回顾Map阶段四大步凑 首先,我们回顾一下在MapReduce中,排序和分组在哪里被执行: 从上图中可以清楚地看出,在Step1.4也就是第四步中,需要对不同分区中的数据进行排序和分组,默认情况下,是按照key进行排序和分组. 1.2 实验场景数据文件 在一些特定的数据文件中,不一定都是类似于WordCount单次统计这种规范的数据,比如下面这类数据,它虽然只有两列,但是却有一定的实践意义. 3 3 3 2 3 1 2 2 2 1 1 1 (1)如果按照第一列升序排列,当

STL笔记(6)标准库:标准库中的排序算法

STL笔记(6)标准库:标准库中的排序算法 标准库:标准库中的排序算法The Standard Librarian: Sorting in the Standard Library Matthew Austern http://www.cuj.com/experts/1908/austern.htm?topic=experts 用泛型算法进行排序    C++标准24章有一个小节叫“Sorting and related operations”.它包含了很多对已序区间进行的操作,和三个排序用泛型

Mysql中的排序规则utf8_unicode_ci、utf8_general_ci的区别总结

Mysql中的排序规则utf8_unicode_ci.utf8_general_ci的区别总结 用了这么长时间,发现自己竟然不知道utf_bin和utf_general_ci这两者到底有什么区别.. ci是 case insensitive, 即 "大小写不敏感", a 和 A 会在字符判断中会被当做一样的; bin 是二进制, a 和 A 会别区别对待. 例如你运行: SELECT * FROM table WHERE txt = 'a' 那么在utf8_bin中你就找不到 txt

Lucene 中自定义排序的实现

使用Lucene来搜索内容,搜索结果的显示顺序当然是比较重要的.Lucene中Build-in的几个排序定义在大多数情况下是不适合我们使用的.要适合自己的应用程序的场景,就只能自定义排序功能,本节我们就来看看在Lucene中如何实现自定义排序功能. Lucene中的自定义排序功能和Java集合中的自定义排序的实现方法差不多,都要实现一下比较接口. 在Java中只要实现Comparable接口就可以了.但是在Lucene中要实现SortComparatorSource接口和 ScoreDocCom

Java集合中对象排序

集合中的对象排序需求还是比较常见的,当然我们可以重写equals方法,循环比较:同时Java为我们提供了更易使用的APIs.当需要排序的集合或数组不是单纯的数字型时,通常可以使用Comparator或Comparable,以简单的方式实现对象排序或自定义排序. 下面通过两个例子分别用Comparable和Comparator实现对User对象中年龄排序. Comparable接口方式 类自身实现Comparable接口,实现该接口中的compareTo方法. import java.util.A

Comparable与Comparator,java中的排序与比较

1:比较和排序的概念 比较:两个实体类之间按>,=,<进行比较. 排序:在集合类中,对集合类中的实体进行排序.排序基于的算法基于实体类提供的比较函数. 基本型别都提供了默认的比较算法,如string提供了按字母进行比较,int提供了按整数大小进行比较. 2:Comparable与Comparator but,在软件开发的世界中,任何没有代码的堆概念都是耍流氓.所以,无论我们解释的多么完美,必须show me the code: 我们首先看这样一段代码: public class Collect

java中的排序Comparable接口和Comparator接口

普通的类要实现排序,必须实现Comparable接口,并重写CompareTo()方法. package test; public class Field implements Comparable<Field> {     private String name;     private int age;     public Field() {     }     public Field(String name, int age) {         this.name = name;

Java中各种排序算法

//插入排序:package org.rut.util.algorithm.support; import org.rut.util.algorithm.SortUtil;/** * @author treeroot * @since 2006-2-2 * @version 1.0 */public class InsertSort implements SortUtil.Sort{ /** (non-Javadoc) * @see org.rut.util.algorithm.SortUtil

linux内核中的排序接口--sort函数

linux内核中的sort函数,事实上跟我们所说的qsort函数非常像,我们来看看qsort: qsort 的函数原型是 void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*)); 參数:  1 .待排序数组首地址 2 .数组中待排序元素数量 3 .各元素的占用空间大小 4 .指向函数的指针.用于确定排序的顺序. 当中compare函数应写为: 1 2 3 4 int c