自身支持排序的ListCtrl[1]

[入库:2005年8月18日] [更新:2007年3月24日]

本文简介:选择自 coldcrane 的 blog

自身支持排序的listctrl


vc里的clistctrl是个很不好用的控件,特别是排序,实现起来很麻烦。

关于排序的基本用法,有一篇很好的文章:
http://www.vchelp.net/vchelp/zart/sortl.asp?type_id=9&class_id=1&cata_id=1&article_id=73&search_term=

但是,在这个例子里也存在个问题:排序的实现是和数据源相关的,如果有若干个表需要排序的话,每个表都要写相应的代码,这是一件非常痛苦的事。

所以,在上面的基础上,重新写了一个自身支持排序的csoftlist,从某个意义上说,也算是实现文档和视图的真正分离。

下面说说几个主要的地方。


1. csortlist是clistctrl的派生类 (好象是废话)

2. 要让csortlist自行排序,当然得让csortlist自己处理lvn_columnclick消息
 on_notify_reflect(lvn_columnclick, onlvncolumnclick)
   onlvncolumnclick的作用就是设置排序列,排序方式,最后调用sortitems()。

3. 排序的具体实现,也就是callback listcompare(...)的实现:
   基本要求: 让csortlist根据item进行排序,而与数据源无关。(当然这样也有不足之处,就是排序只能按文本排序了。如果你需要按数字排序的话,那就只有特殊处理了。)

   这里涉及到的最主要的函数是:
   1)listcompare - 实现排序的回调函数
   int callback csortlist::listcompare(lparam lparam1, lparam lparam2, lparam lparamsort);
   2)clistctrl::finditem - 查找相应的item, 查找方式可指定
   int finditem( lvfindinfo* pfindinfo, int nstart = -1 ) const;
   finditem的具体细节请参考msdn.
  
   基本思路:
   1)listcompare的原型:传入的参数lparam1,lparam2是相应两行的itemdata;
   2)finditem根据lparam1,lparam2得到相应的item;
     finditem有多种查找方式(查找方式通过lvfindinfo->flags进行设置),这里只是根据itemdata进行查找。
   3)再用getitemtext得到排序列的itemtext;
   4)最后就是比较itemtext了。
  
4. 显示指明排序方式的标记
   简单地说,就是给clistctrl的cheadctrl指定一个cimagelist,根据需要指定column要显示的image。
   主要函数:
   1)cheaderctrl::getitem - 取得表头控制中某一项目的内容
   bool getitem( int npos, hditem* pheaderitem ) const;
   2)cheaderctrl::setitem - 设置表头控制中某一项目的内容
   bool setitem( int npos, hditem* pheaderitem );


下面是源代码:
只有两个文件:csortlist.h, csortlist.cpp
直接把这两个文件放到项目里就可以了。
唯一要注意的是:idb_hdrup, idb_hdrdown 是两个位图资源,分别表示顺序和倒序,这个就需要自己弄了。

a. softlist.h

#if !defined(afx_sortlist_h__6ace2f6f_aefe_11d3_bde9_f4145aa4f676__included_)
#define afx_sortlist_h__6ace2f6f_aefe_11d3_bde9_f4145aa4f676__included_

#if _msc_ver > 1000
#pragma once
#endif // _msc_ver > 1000
// sortlist.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// csortlist window

class csortlist : public clistctrl
{
// construction
public:
 csortlist();
// attributes
public:

// operations
public:

// overrides
 // classwizard generated virtual function overrides
 //{{afx_virtual(csortlist)
 //}}afx_virtual

// implementation
public:
 virtual ~csortlist();

 // generated message map functions
protected:
 //{{afx_msg(csortlist)
 afx_msg bool oncolumnclick(nmhdr* pnmhdr, lresult* presult);
 //}}afx_msg
  
 declare_message_map()
public:
 afx_msg void onlvncolumnclick(nmhdr *pnmhdr, lresult *presult);

 void createsorticons();
 void setsorticon();

 bool getfullrowselect();
 // 设置为行选中
 void setfullrowselect( bool bfullrowselect );

 bool getgridlines();
 // 设置绘制表格
 void setgridlines( bool bgridlines );

 static callback listcompare(lparam lparam1, lparam lparam2, lparam lparamsort);
public:
 bool m_basc;//是否顺序排序
 int m_nsortedcol;//当前排序的列

private:
 cbitmap                            m_bmpuparrow; 
 cbitmap                            m_bmpdownarrow;
 int                                m_nuparrow;
 int                                m_ndownarrow;
 cimagelist                         m_imglstsorticons;
};

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

本文关键:自身支持排序的ListCtrl
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top