CListCtrl自动排序

在C++界面开发中,WLT::CListCtrl和MFC的CListCtrl都没有自动排序功能,不过他们都提供了一个回调函数,通过SortItems或者SortItemsEx方法来进行。激活SortItems方法,需要接受Column的Click事件,然后设置合适的数据,就可以实现自动排序了。

 

 

CListCtrl的排序

微软的VC++实在是个弱智的IDE,编程10小时,至少有5小时是在和windows作斗争,还是C++Builder好啊。不过微软横行霸道,Borland已经没有turbo c时代的雄风了,现在做WinCE的程序,不用VC++还不行。

CListCtrl是个让人头痛不已的控件,十分难用。CListCtrl的排序,是通过调用SortItems函数实现的。
 BOOL SortItems(
 PFNLVCOMPARE pfnCompare,
 DWORD_PTR dwData 
 ); 
其中, pfnCompare 是排序时被调用的回调函数, dwData是调用SortItems时传给回调函数的参数,是回调函数的第三个参数。
pfnCompare的定义是:
int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, 
LPARAM lParamSort);
 
其中,lParam1、lParam2是和两个列表项相关的参数,这个参数在调用InsertItem/SetItem时,被存储于LVITEM:: lParam中。这个参数被用于标定列表项,是我们在排序和查找列表项的“特征”,就像人名用于标定一个人一样。设置LVITEM:: lParam是排序的关键,不设置这个变量,就无法找到进行比较的两个项目,调用SortItems()就不起作用。这一点,MSDN里面没有说的很清楚。

知道排序的原理,那么来看看具体的实现方法:

1. 添加回调函数

//********************************
// Call back funtion for sorting
//********************************
static int CALLBACK
MyCompareProc(LPARAM lParam1,    //lParam1 and lParam2 are set                                  //in LVITEM::lParam
              LPARAM lParam2,    //In this case, we associate
                                 //it with item index;
              LPARAM lParamSort  //The parameter transfered
                                 //from SortItem();
             

    CSPListCtrl * pListCtrl = (CSPListCtrl*)lParamSort; 
    LVFINDINFO pInfo1, pInfo2;
    pInfo1.flags = LVFI_PARAM;
    pInfo2.flags = LVFI_PARAM;
    pInfo1.lParam = lParam1;
    pInfo2.lParam = lParam2;
    int ind1 = pListCtrl->FindItem(&pInfo1);//根据在
                                            //Insert/SetItem时
                                            //指定的参数找到
                                            //被比较的项目
    int ind2 = pListCtrl->FindItem(&pInfo2);
    //本例根据第一列项目(item)的名字排序,故读取项目的text:
    //GetItemText第一个参数是项目号,实际是List行号,
    //第二个参数是子项目号,实际是项目的列号,本例是0
    //代表只对第一列的名字排序:
    CString strItem1 = pListCtrl->GetItemText(ind1,0);
    CString strItem2 = pListCtrl->GetItemText(ind2,0);
    //进行比较,m_iSortAsc是自定义CListCtrl类中的int类型标志变量.
    //用于指定按照降序还是升序排序:
    return pListCtrl->m_iSortAsc ? lstrcmp( strItem1, strItem2 )
           : lstrcmp( strItem2, strItem1 );
 

2. 在自定义的CListCtrl派生类中定义SortItem函数:
BOOL CSPListCtrl::SortItem(int sortup)
{
    m_iSortAsc=sortup;
    SortItems(MyCompareProc,(DWORD_PTR)this);
    return 1;
}

3. 在插入/设置项目时,设置项目的标识参数lParam

    没有这一步,是调用SortItems函数失败的关键。代码如下:
     ...............
    //Insert items for the item:
    item.mask=LVIF_TEXT|LVIF_IMAGE|LVIF_STATE|LVIF_PARAM;
    item.iItem   =nrow;
    item.iSubItem=ncol;
    item.pszText=text;
    item.iImage=nimg;
    item.state=state;
    //The parameter identifies the item:
    item.lParam=(LPARAM)(nrow*100+ncol);
    //Insert item:
    if(nrow>=GetRowCount()&&ncol==0)
    {
        re=CListCtrl::InsertItem(&item);
    }
    //If the item exists
    else if((nrow<GetRowCount()&&ncol<GetColCount())||ncol>0)
    {
        re=CListCtrl::SetItem(&item);
    }
    ...............

4. 在使用ListCtrl的对话框类中,调用我们的派生类的SortItem函数:
    ...................
    m_pListMain=(CSPListCtrl *) GetDlgItem(IDC_LISTMAIN);
    ...................
    m_pListMain->SortItem();
    ...................

    这里再就CListCtrl的项目说明一下。CListCtrl的项目分为项目和子项目,项目(item)就是列表某一行的第一列的元素,项目号实际就是行号,而该行第一列之后的叫子项目(subitem),子项目号实际就是列号。添加项目需要先添加第一列,再用InserItem()函数添加,而子项目的添加则不同,在添加列以后,只要调用SetItem()函数即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值