问题是这样的,我想实现的是在列表控件中实现对数据的排序。具体是当单击列表某一列名时,让列表中的数据,按所单击列的数据值大小进行升序和降序排序(即单击一下按升序排序再单击一下按降序排序)。我的列表中列名有“学号”(第一列)、“不及格人数”、“英语”、“数学”等。
其实我仿照了一个实例对列表中数据的排序。但是它所完成的功能是:不管你单击列表中的哪一个列名,它都是按“学号”(第一列)的数值大小进行排序,单击“英语”、“数学”也是按“学号”(第一列)的数值大小进行排序。下面是它的代码:
static int CALLBACK Compare(LPARAM lParam1,LPARAM lParam2,LPARAM lParamData);
afx_msg void OnColumnclickchenjiLIST1(NMHDR* pNMHDR, LRESULT* pResult);
//这两句是函数的声明。
下面是函数的代码:
//比较函数
int CALLBACK Cchengjiguanli::Compare(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort)
{
CListCtrl* pListCtrl=reinterpret_cast <CListCtrl*>(lParamSort);
//如果返回-1表示不进行排序
return 1;
}
//单击列表控件列名的消息处理函数
void Cchengjiguanli::OnColumnclickchenjiLIST1(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
m_Grid.SortItems(Compare,reinterpret_cast <DWORD>(this));
*pResult = 0;
}
代码就是这样了,而我想实现的是单击不同的列名按不同的列进行排序,请问应该这么改呢。
还有一个问题是我的列数不是固定的!
最好是能教我怎么改!谢谢了。

解决方案 »

  1.   

    简单的就把数据保存到数组中,用qsort进行排序,再把排好序的数据填写到控件中
      

  2.   

    首先扩展你的lParamSort参数,将你的需要的列同时传到比较函数中,这样就可以比较了// 比较参数,如果需要这个还可以扩充
    typedef struct _tagCompareSort
    {
    CListCtrl* pListCtrl;    //指向ListView控件的指針
    int        idCol;        //指向ListView的列
    bool       isInc;        //排序方式(升序為TRUE,降序為FALSE)
    bool       isStr;        //是否按字符排序   
    }tagCompareSort;int CALLBACK Cchengjiguanli::Compare(LPARAM lParam1,LPARAM lParam2,LPARAM ParamSort) 

        tagCompareSort* pparam = (tagCompareSort*)lParamSort;
        CString str1=pparam->pListCtrl->GetItemText(lParam1,pparam->idCol); 
        CString str2=pparam->pListCtrl->GetItemText(lParam2,pparam->idCol);  
        
        // 接下来比较这两个值就行了,根据需要返回你的值0,1,-1
        if(pparam->isStr)  
    ret=strcmp(str1, str2);
        else
    ret=atof(str1)<=atof(str2)?-1:1;    return (pparam->isInc) ? ret : -ret;

    //单击列表控件列名的消息处理函数 
    void Cchengjiguanli::OnColumnclickchenjiLIST1(NMHDR* pNMHDR, LRESULT* pResult) 

    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; 
    // TODO: Add your control notification handler code here // 获取相关的值填充这个比较参数
    tagCompareSort sortparam;
    sortparam.pListCtrl=&m_list;  // 将你的List指针传进去
    sortparam.idCol=idColindex;   // 获取你当前的列的Index
    sortparam.isInc=bInc;  // 排序的方式
    sortparam.isStr=TRUE;  // 比较的方式m_Grid.SortItems(Compare,(DWORD)&sortparam);*pResult = 0; 

      

  3.   

    http://blog.csdn.net/hityct1/archive/2008/03/26/2219811.aspx
    这个可否?
      

  4.   

    关键是获得列,然后CALLBACK里获取该列数据后进行比较,交换顺序。
      

  5.   

    sortparam.idCol=idColindex;// 获取你当前的列的
    idcolindex我是用了GetItemCont应该就是获取所选列了吧?
      

  6.   

    sortparam.idCol=idColindex;// 获取你当前的列的
    idcolindex我是用了GetItemCont应该就是获取所选列了吧?
      

  7.   


    GetItemCont是获取的列吗?查一下msdn吗,看字面意思都不是啦NM_LISTVIEW中的iSubItem是
      

  8.   

    哦,是用pNMListView->iSubItem吧,
    但是程序运行后单击列名还是没反映啊,这是为什么呢?
    下面是改后的代码:typedef struct _tagCompareSort
    {
        CListCtrl* pListCtrl;    //指向ListView控件的指針
        int        idCol;        //指向ListView的列
        bool       isInc;        //排序方式(升序為TRUE,降序為FALSE)
        bool       isStr;        //是否按字符排序   
    }tagCompareSort;
    int CALLBACK Cchengjiguanli::Compare(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort)
    {
     tagCompareSort* pparam = (tagCompareSort*)lParamSort;
        CString str1=pparam->pListCtrl->GetItemText(lParam1,pparam->idCol); 
        CString str2=pparam->pListCtrl->GetItemText(lParam2,pparam->idCol);  
        
        // 接下来比较这两个值就行了,根据需要返回你的值0,1,-1
        int ret;
    if(pparam->isStr)  
       
        ret=strcmp(str1, str2);
        else
        ret=atof(str1)<=atof(str2)?-1:1;
        return (pparam->isInc) ? ret : -ret;
    //如果返回-1表示不进行排序
    // return 1;
    }
    //单击列表控件列的消息处理函数
    void Cchengjiguanli::OnColumnclickchenjiLIST1(NMHDR* pNMHDR, LRESULT* pResult) 
    {
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; 
    // TODO: Add your control notification handler code here // 获取相关的值填充这个比较参数
    tagCompareSort sortparam;
    sortparam.pListCtrl=&m_Grid;  // 将你的List指针传进去
    sortparam.idCol=pNMListView->iSubItem;  // 获取你当前的列的Index
    sortparam.isInc=TRUE;  // 排序的方式
    sortparam.isStr=TRUE;  // 比较的方式m_Grid.SortItems(Compare,(DWORD)&sortparam);
    *pResult =0; 
      

  9.   

    哦,是用pNMListView->iSubItem吧,
    但是程序运行后单击列名还是没反映啊,这是为什么呢?
    下面是改后的代码:typedef struct _tagCompareSort
    {
        CListCtrl* pListCtrl;    //指向ListView控件的指針
        int        idCol;        //指向ListView的列
        bool       isInc;        //排序方式(升序為TRUE,降序為FALSE)
        bool       isStr;        //是否按字符排序   
    }tagCompareSort;
    int CALLBACK Cchengjiguanli::Compare(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort)
    {
     tagCompareSort* pparam = (tagCompareSort*)lParamSort;
        CString str1=pparam->pListCtrl->GetItemText(lParam1,pparam->idCol); 
        CString str2=pparam->pListCtrl->GetItemText(lParam2,pparam->idCol);  
        
        // 接下来比较这两个值就行了,根据需要返回你的值0,1,-1
        int ret;
    if(pparam->isStr)  
       
        ret=strcmp(str1, str2);
        else
        ret=atof(str1)<=atof(str2)?-1:1;
        return (pparam->isInc) ? ret : -ret;
    //如果返回-1表示不进行排序
    // return 1;
    }
    //单击列表控件列的消息处理函数
    void Cchengjiguanli::OnColumnclickchenjiLIST1(NMHDR* pNMHDR, LRESULT* pResult) 
    {
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; 
    // TODO: Add your control notification handler code here // 获取相关的值填充这个比较参数
    tagCompareSort sortparam;
    sortparam.pListCtrl=&m_Grid;  // 将你的List指针传进去
    sortparam.idCol=pNMListView->iSubItem;  // 获取你当前的列的Index
    sortparam.isInc=TRUE;  // 排序的方式
    sortparam.isStr=TRUE;  // 比较的方式m_Grid.SortItems(Compare,(DWORD)&sortparam);
    *pResult =0;