ListCtrl排序

源代码及可执行文件下载地址: https://files.cnblogs.com/rainboy2010/CSortListCtrl_Demo.zip

   

界面设计中我们经常会用到ListCtrl控件,那么问题来了,如何实现ListCtrl排序呢?在这里提供一个CListCtrl的继承类CSortListCtrl类,支持某一列按照字符串,十进制或十六进制排序,默认按照字符串方式进行排序。

1
2
3
4
5
6
7
8
9
enum ITEM_COMPARE_TYPE
{
    /// String comparison.
    ICT_STRING,
    /// Integer comparison.
    ICT_INTEGER,
    /// Hexadecimal comparison.
    ICT_HEXADECIMAL
};

首先需要添加点击列表头的响应函数

复制代码
void CSortListCtrl::OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);

    int iColumnNumber=pNMLV->iSubItem;
    _ASSERTE(iColumnNumber >= 0);
    if (m_iColumnNumber == iColumnNumber)
    {
        m_bAscending = ! m_bAscending;
        SetSortImage(m_bAscending?0:1);
    }
    else
    {
        if(m_iColumnNumber>=0)
        {
           SetSortImage(-1);
        }
        m_iColumnNumber=iColumnNumber;
        m_bAscending=TRUE;
        SetSortImage(0);
    }

    LISTVIEW_SORT_PARAMS lvSortParams;
    lvSortParams.hwndList=m_hWnd;
    lvSortParams.iColumnNumber=iColumnNumber;
    lvSortParams.eCompareType=GetSortType(iColumnNumber);
    lvSortParams.bAscending=m_bAscending;
    SortItemsEx(&ListViewCompareFunc,(DWORD_PTR)&lvSortParams);

    *pResult = 0;
}
复制代码

然后实现ListCtrl的排序函数

排序函数的形式为: int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)

当在OnLvnColumnclick中使用SortItems或SortItemsEx时,此时参数lParam1,lParam2,lParamSort所对应的意义有所不同,具体含义可参考MSDN解释

复制代码
int CALLBACK CSortListCtrl::ListViewCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
    LISTVIEW_SORT_PARAMS* plvSortParams=( LISTVIEW_SORT_PARAMS*)lParamSort;
    TCHAR szItemText1[MAX_PATH]={0};
    TCHAR szItemText2[MAX_PATH]={0};

    ListView_GetItemText(plvSortParams->hwndList,lParam1,plvSortParams->iColumnNumber,szItemText1,MAX_PATH);
    ListView_GetItemText(plvSortParams->hwndList,lParam2,plvSortParams->iColumnNumber,szItemText2,MAX_PATH);

    int iResult;
    switch(plvSortParams->eCompareType)
    {
    case ICT_STRING:
        iResult=_tcscmp(szItemText1,szItemText2);
        break;
    case ICT_INTEGER:
        {
            int iItemValue1 = _ttoi(szItemText1);
            int iItemValue2 = _ttoi(szItemText2); 
            iResult=Comparetor(iItemValue1,iItemValue2);
        }
        break;
    case ICT_HEXADECIMAL:
        {
            unsigned uItemValue1 = _tcstoul(szItemText1, NULL, 16);
            unsigned uItemValue2 = _tcstoul(szItemText2, NULL, 16);
            iResult = Comparetor(uItemValue1, uItemValue2);
        }
        break;
    default:
        iResult = 0;
        break;

    }

    return (plvSortParams->bAscending?iResult:-iResult);
}
复制代码

 

posted @   南极冰川雪  阅读(514)  评论(1编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示