给你一个例子,做的不是很好:
#if !defined(AFX_NEWLISTCTRL_H__8C532984_C739_11D3_A6D6_444553540000__INCLUDED_)
#define AFX_NEWLISTCTRL_H__8C532984_C739_11D3_A6D6_444553540000__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// NewListCtrl.h : header file
///////////////////////////////////////////////////////////////////////////////
// CNewListCtrl window
#define LVS_NOTSORT 0x00
#define LVS_SORTSTRING 0X01
#define LVS_SORTINTEGER 0X02
#define LVS_SORTDECIMAL 0X03
#define LVS_SORTDATE 0X04class CNewListCtrl : public CListCtrl
{
// Construction
public:
CNewListCtrl();// Attributes
public:
static CNewListCtrl * m_pOuter;
CArray<BYTE,BYTE> m_SortType;
// Operations
public:// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CNewListCtrl)
//}}AFX_VIRTUAL// Implementation
public:
void ReSetItemData();
int CompareDate(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort);
int CompareNumber(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort);
int CompareString(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort);
friend int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
virtual ~CNewListCtrl(); // Generated message map functions
protected:
//{{AFX_MSG(CNewListCtrl)
afx_msg void OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG DECLARE_MESSAGE_MAP()
};typedef struct tagSortItemlParam{
long lProductID;
int nIndex;
}SortItemlParam;
///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_NEWLISTCTRL_H__8C532984_C739_11D3_A6D6_444553540000__INCLUDED_)
// NewListCtrl.cpp : implementation file
//#include "stdafx.h"
#include "QChannels.h"
#include "NewListCtrl.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endifCNewListCtrl * CNewListCtrl::m_pOuter = 0;/////////////////////////////////////////////////////////////////////////////
// CNewListCtrlCNewListCtrl::CNewListCtrl()
{
m_pOuter = this;
}CNewListCtrl::~CNewListCtrl()
{
}
BEGIN_MESSAGE_MAP(CNewListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CNewListCtrl)
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnDeleteitem)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CNewListCtrl message handlers
void CNewListCtrl::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult) 
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
if(m_SortType[pNMListView->iSubItem] & 0x80)
m_SortType[pNMListView->iSubItem] &= ~0x80;
else
m_SortType[pNMListView->iSubItem]  and = 0x80;
if(m_SortType[pNMListView->iSubItem] & 0x7F != 0x00)
SortItems(CompareFunc,pNMListView->iSubItem);
ReSetItemData();
*pResult = 0;
}int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
int result = 0;
BYTE SortType = (CNewListCtrl::m_pOuter)->m_SortType[lParamSort];
switch(SortType & 0x7F)
{
case LVS_SORTSTRING:
result = (CNewListCtrl::m_pOuter)->CompareString(lParam1,lParam2,lParamSort);
break;
case LVS_SORTINTEGER:
result = (CNewListCtrl::m_pOuter)->CompareNumber(lParam1,lParam2,lParamSort);
break;
case LVS_SORTDECIMAL:
result = (CNewListCtrl::m_pOuter)->CompareNumber(lParam1,lParam2,lParamSort);
break;
case LVS_SORTDATE:
result = (CNewListCtrl::m_pOuter)->CompareDate(lParam1,lParam2,lParamSort);
}
return SortType & 0x80 ? result : -result;
}int CNewListCtrl::CompareString(LPARAM lParam1, LPARAM lParam2,LPARAM lParamSort)
{
CString string1 = GetItemText( ( (tagSortItemlParam*)lParam1 )->nIndex,lParamSort );
CString string2 = GetItemText( ( (tagSortItemlParam*)lParam2 )->nIndex,lParamSort );
int result = string1.Compare(string2);
return result;
}int CNewListCtrl::CompareNumber(LPARAM lParam1, LPARAM lParam2,LPARAM lParamSort)
{
float dNum1,dNum2;
CString string1 = GetItemText( ( (tagSortItemlParam*)lParam1 )->nIndex,lParamSort );
CString string2 = GetItemText( ( (tagSortItemlParam*)lParam2 )->nIndex,lParamSort );
dNum1 = atof(string1);
dNum2 = atof(string2);
if(dNum1 > dNum2)
return 1;
else if(dNum1 < dNum2)
return -1;
else if(dNum1 == dNum2)
return 0;
return 0;
}
int CNewListCtrl::CompareDate(LPARAM lParam1, LPARAM lParam2,LPARAM lParamSort)
{
CString string1 = GetItemText( ( (tagSortItemlParam*)lParam1 )->nIndex,lParamSort );
CString string2 = GetItemText( ( (tagSortItemlParam*)lParam2 )->nIndex,lParamSort );
COleDateTime date1,date2;
date1.ParseDateTime(string1);
date2.ParseDateTime(string2);
if(date1> date2)
return 1;
else if(date1 < date2)
return -1;
else if(date1 == date2)
return 0;
return 0;
}void CNewListCtrl::ReSetItemData()
{
tagSortItemlParam* lParam;
for(int i = 0 ; i < GetItemCount() ; i ++)
{
lParam = (tagSortItemlParam*)GetItemData(i);
lParam->nIndex = i;
SetItemData( i,(LONG)lParam );
}
}void CNewListCtrl::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult) 
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
tagSortItemlParam* lParam = (tagSortItemlParam*)GetItemData(pNMListView->iItem);
if(lParam != NULL)
delete lParam;
*pResult = 0;
}

解决方案 »

  1.   

    响应LVN_COLUMNCLICK,在xxx::OnColumnclickXXX中调用CList::SortItems,SortItems的第一个参数是一个函数指针,指向你写的用来比较CList中各项大小的回调函数(称之为foo),第二个参数是一个指针,指向要传给foo的数据(即foo的第三个参数l3),foo有三个参数,l1,l2,l3,CList::SortItems每次取出表中的两个数据作为l1和l2调用foo,如果foo返回-1表示l1<l2,1表示l1>l2,0表示l1=l2,如此循环知道所有数据比完.
      

  2.   

    在向ListCtrl添加数据项时,在初始化LVITEM时使 
    LVITEM.lParam = (LPARAM)&LVITEM;在OnColumnclick的消息事件中调用SortItems,在第一个参数中指定Compare Callback Function,在第一个参数中指定排序方式。在Compare Callback Function:
    int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2,
    LPARAM lParamSort);
    其中lParam1,lParam2中分别为待比较的两个数据项的指针,
    lParamSort为用户指定的排序方式。Now,what is you want to do?There goes anything!
      

  3.   

    更正:排序方式应在Compare Callback Function的第二个参数中指定。
      

  4.   

    我的ListCtrl是一个对话框中的控件.
    .....
    void CFilecontrol::OnColumnclickFileconlist(NMHDR* pNMHDR, LRESULT* pResult) 
    {
      NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
      // TODO: Add your control notification handler code here
      long item ;//保存用户单击的列号
      item = pNMListView->iSubItem ;//得到行号
      //根据不同的列选择不同的排序方法
      m_fileconlist.SortItems(CompareFunc,item);
      *pResult = 0;
    }
    int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
    {
      //在此得到的前两个参数总是0,为什么????????
      int result = 0;
      result = CFilecontrol::m_pFilecon->CompareStringlParam1,lParam2,lParamSort);
      return result ;
    }int CFilecontrol::CompareString(LPARAM lParam1, LPARAM lParam2,LPARAM lParamSort)
    {
      CString string1 = m_fileconlist.GetItemText(lParam1,lParamSort );
      CString string2 = m_fileconlist.GetItemText(lParam2,lParamSort );
      int result = string1.Compare(string2);
      return result;
    }
      

  5.   

    我从CodeGuru站点找到了答案.自己改了改用上了.但还是感谢大家!