c++ - 排序 CMFCListCtrl 时出现奇怪的行为

标签 c++ mfc

我扩展了 CMFCListCtrl 类,主要是为了能够轻松地按列排序。据我所知,实现 SortOnCompareItems 函数应该足够了。

所发生的情况是,排序对于类型为整数的第一列工作正常,但对类型为字符串的第二列给出了奇怪的排序。没有错误,顺序已更改,但不是按字母顺序排列。


int MyCMFCListCtrl::OnCompareItems(LPARAM lParam1, LPARAM lParam2, int iColumn)
{
    if (iColumn == 0)
    {
        if (lParam1 > lParam2)
            return -1;
        else if (lParam1 < lParam2)
            return 1;
        else
            return 0;
    }
    else if (iColumn == 1)
    {
        CString strCol1, strCol2;
        strCol1 = GetItemText(lParam1, iColumn);
        strCol2 = GetItemText(lParam2, iColumn);
        return strCol1.Compare(strCol2);
    }
    return 0;
}

void MyCMFCListCtrl::Sort(int iColumn, BOOL bAscending, BOOL bAdd)
{
    // Sort available for first and second column
    if (iColumn > 1) return;
    CMFCListCtrl::Sort(iColumn, bAscending, bAdd);
}

我在 OnCompareItems 中获得的值对于两列来说都可以。但最终结果仅对第一个有效。还需要其他功能才能实现此功能吗?

最佳答案

CMFCListCtrl::Sort 将调用 CListCtrl::SortItemsSortItems 会将 LPARAM 项数据传递给回调函数。此LPARAM是一个可以使用SetItemData设置的值。

OnCompareItems中的lParam1lParam2,仅引用LPARAM数据。

GetItemText(lParam1, iColumn) 在这种情况下是未定义的行为,因为 lParam1 不引用行号。

另请参阅 LVM_SORTITEMS 的文档和 LVM_SORTITEMSEX

<小时/> 您可以重写 Sort 并调用 SortItemsEx。这样,lParam1lParam2 将引用行号,并且 GetItemText(lParam1, iColumn) 将是有效的调用,如下所示。请注意,仅当之前调用 SetItemData 时才使用 (iColumn == 0) 条件。

int MyCMFCListCtrl::OnCompareItems(LPARAM lParam1, LPARAM lParam2, int iColumn)
{
    if(iColumn == 0)//assuming SetItemData was called earlier
        return lParam1 - lParam2;

    CString strCol1 = GetItemText(lParam1, iColumn);
    CString strCol2 = GetItemText(lParam2, iColumn);
    return strCol1.Compare(strCol2);
}

void MyCMFCListCtrl::Sort(int iColumn, BOOL bAscending, BOOL bAdd)
{
    if(iColumn == 0)//assuming SetItemData was called earlier
    {
        //call SortItem and get LPARAM data in call back function
        CMFCListCtrl::Sort(iColumn, bAscending, bAdd);
        return;
    }

    //call SortItemEx instead, get row numbers in callback function
    CWaitCursor wait;
    GetHeaderCtrl().SetSortColumn(iColumn, bAscending, bAdd);
    m_iSortedColumn = iColumn;
    m_bAscending = bAscending;
    SortItemsEx(CompareProc, (LPARAM)this);
}

关于c++ - 排序 CMFCListCtrl 时出现奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58934094/

相关文章:

c++ - 改变 HICON 的尺寸

c++ - 如何以编程方式查询 Windows 控制面板?

c++ - 如何读取指向派生类的基类指针数组的内存布局

c++ - 从我的 C/C++ 代码中获取等效的汇编代码 - x86 和 ARM

c++ - ThreadSanitizer 说我的 spin_lock 有数据竞争,但是怎么办?

c++ - 将模板指针传递给 memcpy

c++ - 在没有 GUI 的情况下使用 OpenCV 捕获图像(在 Linux 控制台上)

C++ CImage 不完整的类型是不允许的

c++ - MFC - 手动扩展stringtable

c++ - MFC COleControl::DoPropExchange 在哪里存储持久属性?