CMFCListCtrl::OnCompareItems 排序处理

1.在插入数据时:

      DWORD itemIndex = m_lstCtrlSysStatus.GetItemCount();

      m_lstCtrlSysStatus.InsertItem(itemIndex, netShareNode.szNetShareName);
      m_lstCtrlSysStatus.SetItemData(itemIndex, itemIndex); //itemIndex 必须唯一

      .........

 

2. 重写下面函数

///以下是纯字符串比较,如果要比较中文 or 数字自己得另写了

int CMFCListCtrlEx::OnCompareItems(LPARAM lParam1, LPARAM lParam2, int iColumn) 

{

      CString strItem1, strItem2;
      LVFINDINFO lvfi;

      lvfi.flags     = LVFI_PARAM;
      lvfi.lParam = lParam1;
      strItem1    = GetItemText(FindItem(&lvfi,-1), iColumn);

      lvfi.lParam = lParam2;
      strItem2    = GetItemText(FindItem(&lvfi,-1), iColumn);

      //字符串比较
      return _tcsicmp(strItem1, strItem2);

}

 

网上资料:

1.

要点一:添加一项的时候要使用SetItemData(i,i)绑定一个序号,该序号要唯一。

  CString str;
  str.Format(_T("%d"), i);
  m_ListDB_sblx.InsertItem(i, str);
  m_ListDB_sblx.SetItemData(i, (DWORD)i);    // 一般就设置一个唯一的值.不唯一排序可能有点乱,


要点二:重载比较函数时,要通过下面的方法才能保证正确的取出要比较的字段。


//重载的排序比较函数:用于比较两个项的大小关系
int CMFCListCtrlEx::OnCompareItems(LPARAM lParam1, LPARAM lParam2, int iColumn) 
{
    // 取出两个比较项内容
    CString strItem1,strItem2;
    LVFINDINFO lvfi;
    lvfi.flags=LVFI_PARAM;
    lvfi.lParam=lParam1;
    strItem1 = GetItemText(FindItem(&lvfi,-1),iColumn);
    lvfi.lParam=lParam2;
    strItem2 = GetItemText(FindItem(&lvfi,-1),iColumn); 

    //第0列按整数排序
   if (iColumn == 0 )
   {
        int nItem1 = _ttoi(strItem1);
        int nItem2 = _ttoi(strItem2);

        if (nItem1 == nItem2)  
       {  
            return 0;  
       }
       else
            return(nItem1 < nItem2 ? -1 : 1);
    }
    else
    {
          //比较字符串
         int iSort = _tcsicmp(strItem1, strItem2);
         return(iSort);
    }
}

在注意了以上两点之后,控件置为"Report"类型,把控件的"Sort"属性置为"None",再设置其他属性。即可得到正确的排序结果。

 

 

2.

CListCtrl自带的,给你一份代码吧,自动生成列头上的箭头图标。

#ifndef _SORTLISTCTRL_INCLUDE__
#define _SORTLISTCTRL_INCLUDE__

/////////////////////////////////////////////////////////////////////////////////////////
//一个点击列头时可以排序的列表类
class CSortListCtrl : public CListCtrl
{
// Construction
public:
    CSortListCtrl();
// Attributes
public:
   
struct Info
    {
        CListCtrl
* pListCtrl;
       
int nSubItem;
        BOOL bAsc;
    };

   
int ModiHeardCtrl(CHeaderCtrl* pHeardCtrl,int nItem,int nMode);
   
static int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
// Operations
public:
   
    CImageList m_ImageList;
    BOOL m_bInit;
// Overrides
   
// ClassWizard generated virtual function overrides
   
//{{AFX_VIRTUAL(CSortListCtrl)
   
//}}AFX_VIRTUAL

// Implementation
public:
   
virtual ~CSortListCtrl();

   
// Generated message map functions
protected:
    CBitmap
* MakeColorBoxImage(BOOL bUp);

   
//{{AFX_MSG(CSortListCtrl)
    afx_msg void OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult);
   
//}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};
#endif

/*
创建人:   iamshuke
创建日期: 2002.06.28
说明: 一个单击表头时能排序的列表控件
*/
#include
"stdAfx.h"
#include
"sortlistctrl.h"

/////////////////////////////////////////////////////////////////////////////
// CSortListCtrl
CSortListCtrl::CSortListCtrl()
{
    m_bInit
= FALSE;
}

CSortListCtrl::
~CSortListCtrl()
{   
}

BEGIN_MESSAGE_MAP(CSortListCtrl, CListCtrl)
   
//{{AFX_MSG_MAP(CSortListCtrl)
    ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
   
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSortListCtrl message handlers
//单击表头时进行排序
void CSortListCtrl::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
{
    NM_LISTVIEW
* pNMListView = (NM_LISTVIEW*)pNMHDR;
   
// TODO: Add your control notification handler code here
    *pResult = 0;

   
if(m_bInit == FALSE)
    {
        m_bInit
= TRUE;
       
        m_ImageList.Create(
8,8,ILC_COLOR24|ILC_MASK,2,0);
        m_ImageList.Add(MakeColorBoxImage(TRUE),RGB(
0,0,255));
        m_ImageList.Add(MakeColorBoxImage(FALSE),RGB(
0,0,255));
        GetHeaderCtrl()
->SetImageList(&m_ImageList);
    }

    CHeaderCtrl
*pHeardCtrl=GetHeaderCtrl();   
   
for(int i=pHeardCtrl->GetItemCount()-1; i>=0; i--)
    {
       
if(i == pNMListView->iSubItem)
        {
           
continue;
        }
       
        ModiHeardCtrl(pHeardCtrl, i,
-1);
    }
   
   
int nMode = ModiHeardCtrl(pHeardCtrl,pNMListView->iSubItem,-2);
   
    Info SortInfo;
    SortInfo.pListCtrl
= this;
    SortInfo.nSubItem
= pNMListView->iSubItem;

   
if(nMode == 0 )
    {
        SortInfo.bAsc
=1;
    }
   
else if(nMode == 1)
    {
        SortInfo.bAsc
=0;
    }
   
else
    {
       
return;
    }
   
   
int nItemCount = GetItemCount();
    DWORD
*buf = new DWORD[nItemCount];
       
   
for(i=0; i<nItemCount; i++)
    {
        buf[i]
= GetItemData(i);
        SetItemData(i,i);
    }

   
//如果只有一列,ListCtrl将不能正确排序,所以添加一临时列,这是ListCtrl的一个BUG。
    BOOL bOnlyOneColumn = FALSE;
   
if(pHeardCtrl->GetItemCount() == 1)
    {
        InsertColumn(
1,"");
        bOnlyOneColumn
= TRUE;
    }

    SortItems(MyCompareProc,(DWORD)
&SortInfo);

   
if(bOnlyOneColumn)
    {
        DeleteColumn(
1);//去掉临时列
    }
   
   
for(i=0; i<nItemCount; i++)
    {
        SetItemData(i, buf[GetItemData(i)]);
    }

    delete []buf;
}

int CALLBACK
CSortListCtrl::MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
   
// lParamSort contains a pointer to the list view control.
   
// The lParam of an item is just its index.
   
    Info
*pSortInfo;
    pSortInfo
=(Info*)lParamSort;
   
    CString    strItem1
= pSortInfo->pListCtrl->GetItemText(lParam1, pSortInfo->nSubItem);
    CString    strItem2
= pSortInfo->pListCtrl->GetItemText(lParam2, pSortInfo->nSubItem);
   
   
if(pSortInfo->bAsc)
       
return strItem1.CompareNoCase(strItem2);
   
else
       
return strItem2.CompareNoCase(strItem1);
}


int CSortListCtrl::ModiHeardCtrl(CHeaderCtrl* pHeardCtrl,int nItem,int nMode)
{
    HDITEM hdi;
    TCHAR  lpBuffer[
256];   
    hdi.mask
= HDI_TEXT | HDI_IMAGE | HDI_LPARAM | HDI_FORMAT;
    hdi.pszText
= lpBuffer;
    hdi.cchTextMax
= 256;
   
   
if(pHeardCtrl->GetItem(nItem,&hdi) == FALSE)
    {
       
return -2;
    }
   
   
if((nMode < -1) || (nMode > 1))
    {
        nMode
= (hdi.lParam == 0 ? 1 : 0) ;
    }
   
    hdi.lParam
= nMode;

   
if(nMode == -1)
    {
        hdi.fmt
&= ~HDF_BITMAP_ON_RIGHT;
        hdi.fmt
&= ~HDF_IMAGE;
        hdi.mask
&= ~HDI_IMAGE;
    }
   
else
    {
        hdi.iImage
= nMode;
        hdi.fmt
|= HDF_BITMAP_ON_RIGHT|HDF_IMAGE;
    }
   
    pHeardCtrl
->SetItem(nItem,&hdi);
   
   
return nMode;
}

//生成表头上"向上箭头"和"向下箭头"两个位图
CBitmap* CSortListCtrl::MakeColorBoxImage(BOOL bUp)
{
    CClientDC dc(
this);
    CBitmap
* pBitmap = new CBitmap;
    pBitmap
->CreateCompatibleBitmap(&dc,8,8);
   
    CDC tempDC;
    tempDC.CreateCompatibleDC(
&dc);
   
    CBitmap
* pOldBitmap;
    pOldBitmap
= tempDC.SelectObject(pBitmap);

    CPen penLight,penShadow,
*pOldPen;
   
    tempDC.FillSolidRect(
0,0,8,8,RGB(0,0,255));

   
if(bUp == TRUE)
    {
       
static POINT s_PtShadow[9]={{3,0},{3,1},{2,1},{2,2},{2,3},{1,3},{1,4},{1,5},{0,5}};
       
static POINT s_PtLight[9]={{4,0},{4,1},{5,1},{5,2},{5,3},{6,3},{6,4},{6,5},{7,5}};

        penLight.CreatePen(PS_SOLID,
1,RGB(255,255,255));
       
        pOldPen
= tempDC.SelectObject(&penLight);
        tempDC.MoveTo(
0,6);
        tempDC.LineTo(
7,6);
       
for(int i=0;i<9;i++)
        {
            tempDC.SetPixel(s_PtLight[i],RGB(
255,255,255));
        }
       
       
for(i=0;i<9;i++)
        {
            tempDC.SetPixel(s_PtShadow[i],RGB(
100,100,100));
        }

        tempDC.SelectObject(pOldPen);
    }
   
else if(bUp == FALSE)
    {
       
static POINT s_PtShadow[9]={{0,1},{1,1},{1,2},{1,3},{2,3},{2,4},{2,5},{3,5},{3,6}};
       
static POINT s_PtLight[9]={{7,1},{6,1},{6,2},{6,3},{5,3},{5,4},{5,5},{3,5},{4,6}};
       
        penShadow.CreatePen(PS_SOLID,
1,RGB(100,100,100));
       
        pOldPen
= tempDC.SelectObject(&penShadow);
        tempDC.MoveTo(
7,0);
        tempDC.LineTo(
0,0);
       
       
for(int i=0;i<9;i++)
        {
            tempDC.SetPixel(s_PtLight[i],RGB(
255,255,255));
        }
       
       
for(i=0;i<9;i++)
        {
            tempDC.SetPixel(s_PtShadow[i],RGB(
100,100,100));
        }

        tempDC.SelectObject(pOldPen);
    }
   
else
    {
       
//空白位图
    }
   
    tempDC.SelectObject(pOldBitmap);
       
   
return pBitmap;   
}

 
   

 

你可能感兴趣的:(CMFCListCtrl::OnCompareItems 排序处理)