我的软件做好了,想增加排序功能
我是直接用ListView的,所以网上的CSortListCtrl无法使用
后来找到一个直接将内容排序的代码,发现其中有错
然后干脆自己写,用了冒泡排序,感觉这个算法思想最熟悉,但是效率难以忍受
大家谁给我指点一下下面是网上找到的代码
// http://www.vckbase.com/english/code/listview/sort_on_col.shtml.htm
// SortTextItems - Sort the list based on column text
// Returns - Returns true for success
// nCol - column that contains the text to be sorted
// bAscending - indicate sort order
// low - row to start scanning from - default row is 0
// high - row to end scan. -1 indicates last row
BOOL C102_1View::SortTextItems(int nCol, BOOL bAscending, int low, int high)
{
CListCtrl& lc = GetListCtrl();
CHeaderCtrl* pCtrl = lc.GetHeaderCtrl();
if(nCol >= pCtrl->GetItemCount())
return FALSE;//如果待排序的列超过最大值,返回FALSE if( high == -1 ) high = pCtrl->GetItemCount() - 1; int lo = low;
int hi = high;
CString midItem; if( hi <= lo ) return FALSE; midItem = lc.GetItemText( (lo+hi)/2, nCol ); // loop through the list until indices cross
while( lo <= hi )
{
// rowText will hold all column text for one row
CStringArray rowText; // find the first element that is greater than or equal to 
// the partition element starting from the left Index.
if( bAscending )
while( ( lo < high ) && ( lc.GetItemText(lo, nCol) < midItem ) )
++lo;
else
while( ( lo < high ) && ( lc.GetItemText(lo, nCol) > midItem ) )
++lo; // find an element that is smaller than or equal to 
// the partition element starting from the right Index.
if( bAscending )
while( ( hi > low ) && ( lc.GetItemText(hi, nCol) > midItem ) )
--hi;
else
while( ( hi > low ) && ( lc.GetItemText(hi, nCol) < midItem ) )
--hi; // if the indexes have not crossed, swap
// and if the items are not equal
if( lo <= hi )
{
// swap only if the items are not equal
if( strcmp(lc.GetItemText(lo, nCol), lc.GetItemText(hi, nCol)) != 0)
//if( lc.GetItemText(lo, nCol) != lc.GetItemText(hi, nCol))
{
// swap the rows//这里省略部分内容
} ++lo;
--hi;
}
} // If the right index has not reached the left side of array
// must now sort the left partition.
if( low < hi )
SortTextItems( nCol, bAscending , low, hi); // If the left index has not reached the right side of array
// must now sort the right partition.
if( lo < high )
SortTextItems( nCol, bAscending , lo, high ); return TRUE;}

解决方案 »

  1.   

    你的listctrl中的数据的数据源是什么?数据库?
    为什么不先把数据源排序,然后再读入listctrl呢?
      

  2.   

    没那么麻烦。CListCtrl::SortItems就可以啊。不过要自己写个比较函数,作为函数指针传给该函数。MSDN上有现成的。
      

  3.   

    http://blog.csdn.net/hityct1/archive/2008/03/26/2219811.aspx
      

  4.   

    自己写个如MyCompareProc的回调函数 
    static int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
    { int iReture = 0;//返回值
    int i=0;//字符编号

    CString str1;
    CString str2;
    unsigned long lIP1;
    unsigned long lIP2; str1 = pCheckBoxListCtrl->GetItemText((int)lParam1, (int)lParamSort);
    str2 = pCheckBoxListCtrl->GetItemText((int)lParam2, (int)lParamSort); WCHAR *pChar1 = str1.GetBuffer(str1.GetLength());
    WCHAR *pChar2 = str2.GetBuffer(str2.GetLength()); if (lParamSort == 3)//当为ID时进行特殊判断
    {

    char Buf1[255];
    char Buf2[255];
    WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)pChar1, -1, Buf1, sizeof(Buf1), NULL, NULL);
    WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)pChar2, -1, Buf2, sizeof(Buf2), NULL, NULL);
    lIP1 = inet_addr(Buf1);
    lIP2 = inet_addr(Buf2); if (((lIP1 > lIP2) * s_bSign) > 0)
    {
    iReture = 1;

    else if (((lIP1 < lIP2) * s_bSign) < 0)
    {
    iReture = -1;
    }
    else iReture = 0;

    else
    {

    int nSize = min(str1.GetLength(),str2.GetLength());

    while (pChar1[i] == pChar2[i])
    {
    if (i == nSize -1) break;
    i++;
    } if (i == nSize - 1)
    {
    iReture = str1.GetLength() - str2.GetLength();
    }
    else
    {
    iReture = pChar1[i] - pChar2[i];
    } } str1.ReleaseBuffer();
    str2.ReleaseBuffer(); return (s_bSign * iReture);
    }
    void CCheckBoxListCtrl::OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult)
    {
    LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    // TODO: 在此添加控件通知处理程序代码 int nSize = this->GetItemCount();
    for (int i = 0; i<nSize; i++)
    {
    SetItemData(i,i);//动态更改编号
    }
    s_bSign *= -1;//点击变换排序顺序
    SortItems((PFNLVCOMPARE)MyCompareProc, pNMLV->iSubItem); *pResult = 0;

    }
      

  5.   

    http://www.vckbase.com/document/viewdoc/?id=243
    这里有个现成的类,你可以直接用他就可以了