列表控件(CListCtrl)的顶部有一排按钮,用户可以通过选择不同的列来对记录进行排序请问如何实现?最好有源码。。谢谢。。

解决方案 »

  1.   

    http://blog.programfan.com/article.asp?id=31162
      

  2.   

      WTL 源码里面有个封装好的类 可以参考下!好像叫 CSortListCtrl
      

  3.   

    在CHeaderCtrl的单击事件中调用一个回调函数,此函数用于排序,然后从CListCtrl派生一个类,就好了.
      

  4.   

    使用CListCtrl类的SortItems:
    a.向对话框中添加CListCtrl m_List绑定到对话框上的控件,添加bool asc,初始化为false;
    在对话框的头文件中加入一个排序器:
    struct MyData
    {
    CListCtrl* List;
    bool asc;
    int iSubItem;
    };
    再加一个回调函数的声明语句:
    static int CALLBACK SortItem(LPARAM,LPARAM,LPARAM);
    此语句用于当m_List调用SortItem方法时,执行的排序算法。
    b.添加一个LVN_COLUMNHEADER的通知消息,
    加入消息声明:
    afx_msg void OnColumnClick(NMHDR* pnmhdr,LRESULT* presult);
    加入消息注册:
    ON_NOTIFY(LVN_COLUMNCLICK,IDC_LIST1,&CMyListCtrlDlg::OnColumnClick)
    加入消息体:
    void CMyListCtrlDlg::OnColumnClick(NMHDR* pnmhdr,LRESULT* presult)
    {
    LPNMLISTVIEW listView=(LPNMLISTVIEW)pnmhdr;
    int index=listView->iSubItem;//将子列索引增加到排序器中
    MyData mydata;
    mydata.asc=this->asc;
    mydata.iSubItem=index;//将项目索引增加到排序器中
    mydata.List=&m_List;
    m_List.SortItems((PFNLVCOMPARE)SortItem,(DWORD_PTR)&mydata);
    asc=!asc;//如果当前为升序排序,那么之后则为降序}
    CListCtrl的SortItems方法会调用PFNLVCOMPARE类型的方法,此方法的第三个参数将接受mydata排序器,调用CListCtrl的SortItems会把排序器指针送入。
    c.添加回调函数SortItem的实现:
    int CALLBACK SortItem(LPARAM param1,LPARAM param2,LPARAM sortor)
    {
    MyData* data=(MyData*)sortor;
    CListCtrl* list=data->List;
    LVFINDINFO fi;
    fi.flags=LVFI_PARAM;
        fi.lParam=param1;
    LVFINDINFO fi1;
    fi1.flags=LVFI_PARAM;
    fi1.lParam=param2;
    int index1=list->FindItem(&fi);//从LVITEM结构中的lParam成员来查找对应项的索引号
    int index2=list->FindItem(&fi1);
    CString text1=list->GetItemText(index1,data->iSubItem);//得到指定行和列号的单元格文本
    CString text2=list->GetItemText(index2,data->iSubItem);
    LPTSTR txt1=text1.GetBuffer();//以下七句用于将CString转化成const char*
    LPTSTR txt2=text2.GetBuffer();
    USES_CONVERSION;   
    const   char*   pSth1=T2A(txt1);
    const   char*   pSth2=T2A(txt2);
    text1.ReleaseBuffer();
    text2.ReleaseBuffer();
    if(data->asc)
    { return strcmp(pSth2,pSth1);
    }
    else
    {
    return strcmp(pSth1,pSth2);
    }
    return 0;
    注意:回调函数中的param1和param2都是指添加列表项时用的LVITEM结构中的成员lParam,因此为了使排序生效,必须将第一个列表项采用LVITEM结构的方式添加,并且LVITEM结构中的成员lParam必须有效且唯一。当回调函数返回TRUE时,会按升序的方式,返回FALSE时,则会按降序的方式。
      

  5.   

    7楼的方法正确,使用CListCtrl::SortItems。
      

  6.   

    http://www.vckbase.com 中搜索 list+sort 有好几个源码
      

  7.   

    王骏《列表控件排序功能的实现》 这个很不错。我是copy这个类完成自己的功能
    http://www.vckbase.com/code/listcode.asp?mclsid=3&sclsid=323