zoukankan      html  css  js  c++  java
  • CList 点击表头排序 (1)SortItems函数

    点击表头排序整体的思路都是去 CListCtrl类中的方法SortItems去实现

    CListCtrl::SortItems的原型是:

    BOOL SortItems( PFNLVCOMPARE pfnCompare, DWORD dwData );

    第一个参数pfnCompare为回调函数,形式为:
    int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);

    lParam1,lParam2是什么?这是SortItems难理解的原因。

    简单的说:是LV_ITEM::lParam。
    LV_ITEM是个结构,见msdn。

    可见,我们在向CListCtrl插入item时,必须使用
    int InsertItem( const LVITEM* pItem );
    InsertItem有好几种形式,只有这种形式才能够使用LV_ITEM::lParam。

    下面是插入item的代码的一个示例:

       tagInfo *pFileInfo = new tagInfo;//tagInfo是个结构,存储了你排序的所需要的信息。
        pFileInfo->strFileName = strFileName;
        pFileInfo->strFileSize = FormatFileSize(filefind.GetLength());
        pFileInfo->strFileType = GetTypeName(lpszFileName);
        //pFileInfo->strFilePath = strPath;

        int nItem = GetItemCount();
        int nIcon = GetIconIndex(lpszFileName, filefind.IsDirectory(), FALSE);   
        
         LV_ITEM lvi;
        lvi.mask = LVIF_TEXT|LVIF_PARAM|LVIF_IMAGE;
        lvi.iItem = nItem;
        lvi.iSubItem = 0;
        lvi.pszText = (LPTSTR)(LPCTSTR)pFileInfo->strFileName;
        lvi.lParam = (LPARAM)pFileInfo;
        lvi.iImage = nIcon;
        
            if( (nItem = InsertItem(&lvi)) != -1 )//插入文件名(即第0列),并显示相应图标
        {    
            //MessageInt(nItem);
            lvi.mask = LVIF_TEXT;        
            lvi.iItem = nItem;

            //设置第1列(即设置文件大小)        
            lvi.iSubItem = 1;            
            if(!filefind.IsDirectory())//如果不是目录
            {    
                lvi.pszText = (LPTSTR)(LPCTSTR)pFileInfo->strFileSize;
                SetItem( &lvi );
            }
            else//如果是目录
            {        
                lvi.pszText = (LPTSTR)YCT_UNKNOW_SIZE;
                SetItem( &lvi );
            }                    
                    
            //设置第2列(即设置文件类型)
            lvi.iSubItem = 2;
            lvi.pszText = (LPTSTR)(LPCTSTR)pFileInfo->strFileType;
            SetItem( &lvi );

            //设置第3列(即设置文件所在目录)
            lvi.iSubItem = 3;
            lvi.pszText = (LPTSTR)(LPCTSTR)strPath;
            SetItem( &lvi );

            //更新界面
            //Update( lvi.iItem );
        }

     

    第二个参数dwData为用户自定义值。
    dwData实际传入的是列数,等于1)中的lParamSort。

    void CUpListCtrl::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult) 
    {
            NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

            //排序
            //CompareFunc是回调函数
            //pNMListView->iSubItem就是列数

       SortItems( (PFNLVCOMPARE)CompareFunc, pNMListView->iSubItem );

            *pResult = 0;
    }

    现在lParam指向的是new出来的空间,当然要用delete删除。以下是删除代码:

    //LVN_DELETEITEM消息响应函数
    //每删除一个item,系统都要自动调用这个函数的
    void CUpListCtrl::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult) 
    {
        NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

        //删除LV_ITEM::lParam所指向的空间
        LV_ITEM lvi;
        lvi.mask = LVIF_PARAM;
        lvi.iItem = pNMListView->iItem;
        lvi.iSubItem = 0;
        if ( GetItem( &lvi ) )
        {
            CUpListCtrl::tagInfo* pInfo = (CUpListCtrl::tagInfo*)(lvi.lParam);
            delete pInfo;
        }
        
        *pResult = 0;
    }

    (三)编写回调函数

    这个就比较简单了,按你的规则排序就可以了。
    这里回调函数是个静态成员函数。

    int CALLBACK CUpListCtrl::CompareFunc(CUpListCtrl::tagInfo* pInfo1, CUpListCtrl::tagInfo* pInfo2, LPARAM lCol)
    {
    //CListCtrl::SortItems使用的回调函数
    //[IN]pInfo1,pInfo2:传入的是LV_ITEM::lParam,在调用InsertItem(const LVITEM* pItem)时指定
    //[IN]lCol:指定列数(从零开始),即按哪一列排序


        int nRet = 0;
        ASSERT(lCol>=0 && lCol<NumCol-1);
        ASSERT(pInfo1 != NULL);
        ASSERT(pInfo2 != NULL);
        switch(lCol)
        {
        case 0://0列
                //自己按0列规则排序代码
                    //想要pInfo1(所代表的item)排在pInfo2(所代表的item)之前,则nRet小于0;反之大于0;顺序不变等于0
            break;
        case 1://1列

            //自己按1列规则排序代码
                    //...
            break;
        }

        return nRet;
    }

      我会在下两篇讲解如何去实现排序

    CList 点击表头排序 (2)两种排序方法中其中一种

    CList 点击表头排序 (3)两种排序的第二种

  • 相关阅读:
    [BJOI2019] 光线
    C# 从零开始写 SharpDx 应用 笔刷
    BAT 脚本判断当前系统是 x86 还是 x64 系统
    BAT 脚本判断当前系统是 x86 还是 x64 系统
    win2d 通过 CanvasActiveLayer 画出透明度和裁剪
    win2d 通过 CanvasActiveLayer 画出透明度和裁剪
    PowerShell 拿到显卡信息
    PowerShell 拿到显卡信息
    win10 uwp 如何使用DataTemplate
    win10 uwp 如何使用DataTemplate
  • 原文地址:https://www.cnblogs.com/ye-ming/p/9262819.html
Copyright © 2011-2022 走看看