为CListCtrl用sortitems来排序时,大于等于二列的列表排序都正常,只有一列的列表排序不正确。
下面是回调函数CompareFunc的一段代码。
LVFINDINFO fi1;
memset(&fi1, 0, sizeof(fi1));
fi1.flags = LVFI_PARAM; 
fi1.lParam = lParam1; 
LVFINDINFO fi2; 
memset(&fi2, 0, sizeof(fi2));
fi2.flags = LVFI_PARAM; 
fi2.lParam = lParam2;  int iIndex1 = pInvDtlList->FindItem(&fi1);
int iIndex2 = pInvDtlList->FindItem(&fi2);用TRACE时,发现用lParam去找索引,居然找不到,索引为-1,lPARAM在正常范围内,也就是说item data的绑定出现了混乱。
在网上到处查也没有发现这个问题有人提过,觉得很奇怪,希望各位赐教。

解决方案 »

  1.   

    直接把Item的索引值作为lParam参数不好吗。
      

  2.   

    看我的source~~
    void CInvItemDetailListCtrl::OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult)
    {
    LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    // TODO: ここにコントロール通知ハンドラ コードを追加します。
    if (m_bSorted != TRUE)
    {
    return;
    }

    //並べ替えるために必要な処理
    int iCount = GetItemCount();
    for (int i = 0; i < iCount; i++)
    {
    SetItemData(i, i);
    }
    m_iCurCol = (int)pNMLV->iSubItem; SortItems((PFNLVCOMPARE)CompareFunc, (DWORD_PTR)this);

    m_bSortAscending = !m_bSortAscending;

    *pResult = 0;
    }
      

  3.   

    CompareFunc里的TRACE:
    TRACE(_T("%s (lParam1:%d;index1:%d) == %s (lParam2:%d;index2:%d) | 0\n"), strItem1, lParam1, iIndex1, strItem2, lParam2, iIndex2);Output:
     (lParam1:65;index1:-1) < 2007 Microsoft Office Suite Service Pack 1 (SP1) (lParam2:117;index2:72) | -1
      

  4.   

    既然是用索引值做lParam,在比较函数中,lParam1、lParam2就是要比较的两个Item的索引值了,不需要再FindItem。
      

  5.   

    恩,我在网上查的时候尝试了一下FindItem。就算不FindItem,情况还是一样的。直接把lParam当作Index,情况还是一样的。
      

  6.   

    排序相关的,步骤基本和网上的那些代码一样,用字符来排的void CInvItemDetailListCtrl::OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult)
    {
    LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    // TODO: ここにコントロール通知ハンドラ コードを追加します。
    if (m_bSorted != TRUE)
    {
    return;
    }

    //並べ替えるために必要な処理
    int iCount = GetItemCount();
    for (int i = 0; i < iCount; i++)
    {
    SetItemData(i, i);
    } m_iCurCol = (int)pNMLV->iSubItem; SortItems((PFNLVCOMPARE)CompareFunc, (DWORD_PTR)this);

    m_bSortAscending = !m_bSortAscending;

    *pResult = 0;
    }int CALLBACK CInvItemDetailListCtrl::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
    {
    CInvItemDetailListCtrl* pInvDtlList = (CInvItemDetailListCtrl*) lParamSort; CString strItem1 = pInvDtlList->GetItemText((int)lParam1, pInvDtlList->m_iCurCol);
    CString strItem2 = pInvDtlList->GetItemText((int)lParam2, pInvDtlList->m_iCurCol);

    if (pInvDtlList->m_bSortAscending == TRUE)
    {
    return strItem1 < strItem2;
    }
    else
    {
    return strItem1 > strItem2;
    }
    }
      

  7.   

    BOOL CInvItemDetailListCtrl::DisplayInvDetail(CInventoryInfo* pInvInfo)//CInventoryInfo是一个储存数据结构体的类
    {
    //全部にアイテムと列を削除する
    DeleteAllItems();
    while(DeleteColumn(0));

    int i;

    switch (m_iInvItemIndex)
    {
    case ……:
    ……;
    break;
    case INV_REGISTRY_IMAGE:
    //----------------------------------------------------
        //レジストリ検索結果情報
        //----------------------------------------------------
    InsertColumn(0, INV_RGRST_SOFT_N, LVCFMT_LEFT, SINGLE_COLUMN_WIDTH, 0);
    LoadColumnInfo(COLUMN_NAME13, 1); for(i = 0; i < pInvInfo->m_InvRegClntInfoArray.GetCount(); i++)
    {
    InsertItem(0, pInvInfo->m_InvRegClntInfoArray.ElementAt(i).szSoftware);
    }
    m_bSorted = TRUE;

    //並べ替えるために必要な処理
    {
    int iCount = GetItemCount();

    for (i = 0; i < iCount; i++)
    {
    SetItemData(i, (DWORD)pInvInfo->m_InvRegClntInfoArray.ElementAt(i).szSoftware);
    } m_iCurCol = 0;
    SortItems(CompareFunc, (DWORD_PTR)this);
    m_bSortAscending = FALSE;
    }

    break;
      

  8.   

    目前有两种我不大满意的解决办法:
    一种就是把一列变两列,再插入一列,排序就正常了。
    另一种是将item的字符串和item绑定,排序也正常了。
      

  9.   

    int CALLBACK CInvItemDetailListCtrl::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
    {
        CInvItemDetailListCtrl* pInvDtlList = (CInvItemDetailListCtrl*) lParamSort;    CString strItem1 = pInvDtlList->GetItemText((int)lParam1, pInvDtlList->m_iCurCol);
        CString strItem2 = pInvDtlList->GetItemText((int)lParam2, pInvDtlList->m_iCurCol);
        
        if (pInvDtlList->m_bSortAscending == TRUE)
        {
            return strItem1.Compare(strItem2);
        }
        else
        {
            return strItem2.Compare(strItem1);
        }
    }
      

  10.   

    DisplayInvDetail是要在ListCtrl上显示一些信息,当m_iInvItemIndex = INV_REGISTRY_IMAGE(宏常量)时,插入一列,并将结构体中的相应数据插入ListCtrl中去。
    因为一开始就要将数据排序,所以在插入之后还调用了SortItems。
      

  11.   

    绝对有重大关系,你原本的写法只能返回0或1,没法返回负值。
    另外
    m_bSortAscending = !m_bSortAscending;
    应该加在排序之前,并判断此次点击的列号与上次相同时执行。
      

  12.   

    mhh~ 个人绝对还是虚拟列表控件好。
    排序调用Qsort 绝对没有说哪行哪列不能排的。
    而且虚拟列表控件那个速度~爽