为list控件增加排序功能,并添加header排序图标

内容摘要

列表排序功能在很多报表功能的软件中应用很多,本文只介绍如何快速的实现简单的列表排序功能。后续又添加了如何在列表头添加排序图标。

列表排序

               实现列表排序功能的方法很多,网上搜索了一下,每个人的理解不同,实现方法也各不相同。大部分人的实现是基于CListCtrl控件提供的SortItems方法,本文中也将介绍该方法实现。

               【题外话】首先,想谈一个C++程序员的弊端,C++程序员非常喜欢将功能封装到类中,并且所有的方法和变量都要做成类成员。其实,仔细研究一下类,实际上也只是一种数据类型。就我遇到的情况,有时候需要在一个类中使用的线程,则非常希望把线程函数写到类中,貌似这样就能保证线程的安全,并且保证这个线程和这个类之间的某种必然的关系。或者有时候的某个变量,分明是一个全局的变量,可以供多个类或者是模块使用,但大部分程序员不自觉的就将该变量做成类变量,然后使用一堆的机制,保证各个模块共享该变量。

                最近自己意识到这个问题,所以想重点提一下,C++程序员确实被类的封装给禁锢的太深了。

闲话少说,开始今天的话题。

  • 响应列表控件的LVN_COLUMNCLICK消息,在该消息响应函数中调用SortItems函数,实现文件列表的排序。

LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);

static int nCurSortCol = -1;		// 保存当前的排序列表
// 一开始表示为-1,标识尚未按任何列排序
// 若当前排序列与点击列相同,则更改增、减的排序方式。
// 若点击列与当前排序列不同的列,则改变排序列,并将排序方式改为增序
if (nCurSortCol == pNMListView->iSubItem)
{
      if (nSortOrder == 1)
      {
            nSortOrder = -1;
      }else
      {
            nSortOrder = 1;
      }
}else
{
      nCurSortCol = pNMListView->iSubItem;
      nSortOrder = 1;
}

Item mItem
mItem.mList = &m_FileList;
mItem.Isub = pNMListView->iSubItem;

for (int i = 0; i < m_FileList.GetItemCount(); i++)
{
       m_FileList.SetItemData(i,i);
}
m_FileList.SortItems(CompareFunc, (LPARAM)&mItem);
SetSortArrow(nCurSortCol,nSortOrder < 0 ? true : false);

int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
       // 得到排序方式
       if (lParam1 == 0 || lParam2 == 0)         // 禁止第一行排序
       {
             return 0;
       }
       Item *pItem = (Item*)lParamSort;
       ASSERT(pItem);
       // 得到两个列的排序信息
       CString str1 = pItem->mList->GetItemText(lParam1,pItem->Isub);
       CString str2 = pItem->mList->GetItemText(lParam2,pItem->Isub);

       switch(pItem->Isub)
       {
       default:
              ASSERT(0);
              return 0;
       case 0:
               {
                       if (nSortOrder == 1)
                       {
                              return str1.Compare(str2);
                       }else
                       {
                              return -str1.Compare(str2);
                       }
               }
               break;
       case 1:
               {
                       double dbVal1 = _wtof(str1.GetString());
                       double dbVal2 = _wtof(str2.GetString());
                       if  (nSortOrder == 1)
                       {
                               return dbVal1 <= dbVal2 ? 1 : -1;
                      }else
                      {
                               return dbVal1 <= dbVal2 ? -1 : 1;
                      }
               }
               break;
       }
       return 0;
}

  • 排序状态图标

// SetSortArrow ( int colIndex, bool ascending)
#if (_WIN32_WINNT >= 0x501)
        for (int i = 0; i < m_FileList.GetHeaderCtrl()->GetItemCount(); ++i)
        {
               HDITEM hditem = {0};
               hditem.mask = HDI_FORMAT;
               VERIFY( m_FileList.GetHeaderCtrl()->GetItem( i, &hditem ) );
               hditem.fmt &= ~(HDF_SORTDOWN|HDF_SORTUP);
               if (i == colIndex)
               {
                       hditem.fmt |= ascending ? HDF_SORTDOWN : HDF_SORTUP;
               }
               VERIFY( m_FileList.GetHeaderCtrl()->SetItem( i, &hditem) );
        }
#endif

UINT bitmapID = m_Ascending ? IDB_DOWNARROW : IDB_UPARROW; 
for(int i = 0; i < GetHeaderCtrl()->GetItemCount(); ++i)
{
        HDITEM hditem = {0};
        hditem.mask = HDI_BITMAP | HDI_FORMAT;
        VERIFY( GetHeaderCtrl()->GetItem( i, &hditem ) );
        if (hditem.fmt & HDF_BITMAP && hditem.fmt & HDF_BITMAP_ON_RIGHT)
        {
               if (hditem.hbm)
               {
                      DeleteObject(hditem.hbm);
                      hditem.hbm = NULL;
               }
               hditem.fmt &= ~(HDF_BITMAP|HDF_BITMAP_ON_RIGHT);
               VERIFY( CListCtrl::GetHeaderCtrl()->SetItem( i, &hditem ) );
        }
        if (i == colIndex)
        {
               hditem.fmt |= HDF_BITMAP|HDF_BITMAP_ON_RIGHT;
               hditem.hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(bitmapID), IMAGE_BITMAP, 0,0, LR_LOADMAP3DCOLORS); 
               VERIFY( hditem.hbm!=NULL );
               VERIFY( CListCtrl::GetHeaderCtrl()->SetItem( i, &hditem ) );
        }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值