使用列表视图对表进行排序

sorting tables with listview

本文关键字:排序 列表 视图      更新时间:2023-10-16

我正在编写使用listView的小程序,我想将表中的数据排序到我单击的列中,当我使用ListView_SortItems到比较功能时,正在传输三个参数。问题是在函数复合元素中,lParam1lParam2总是得到值 0,我比较表中的相同单元格。

当我使用ListView_SortItems(hListView,0,lParam)时;表排序良好,但仅按第一列排序。

我该如何解决这个问题?我的代码

int CALLBACK comp(LPARAM lParam1, LPARAM lParam2, LPARAM lParam){
    NMLISTVIEW *pnmlv = (NMLISTVIEW*)lParam;
    TCHAR str[MAX_PATH];
    TCHAR str2[MAX_PATH];
    ListView_GetItemText(pnmlv->hdr.hwndFrom, lParam1, pnmlv->iSubItem, str, MAX_PATH);
    ListView_GetItemText(pnmlv->hdr.hwndFrom, lParam2, pnmlv->iSubItem, str2, MAX_PATH);
    return (lstrcmp(str2, str));
}
case WM_NOTIFY:
if ((((LPNMHDR)lParam)->idFrom == 1000/*listViev ID*/) && (((LPNMHDR)lParam)->code == LVN_COLUMNCLICK)){
    ListView_SortItems(hListView, comp, lParam);
}

基本上,您需要使用第三个参数,在您的例子中名为 lParam - 您可以使用它来传递有关哪一列应该作为排序基础的信息。

下面是我从我的一个旧的RSS阅读器项目中找到的一些代码。希望它有一些用处。

看起来我只是用它来保持 -1,-2,

-3 或 1,2,3。如果它是负数,我以一种方式排序(asc/desc),如果它是正数,我以另一种方式排序。该数字只是单击其标题的从 1 开始的列号。

前两个函数演示如何确定单击了哪一列以及是按升序还是降序排序,而第三个函数负责向下或向上的小箭头,以指示排序的列和方向。

/*
int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2,
    LPARAM lParamSort);

The lParam1 parameter is the 32-bit value associated with the first item being compared;
and the lParam2 parameter is the value associated with the second item. These are the
values that were specified in the lParam member of the items' LV_ITEM structure when they
were inserted into the list. The lParamSort parameter is the same value passed to the
LVM_SORTITEMS message.
The comparison function must return a negative value if the first item should precede the
second, a positive value if the first item should follow the second, or zero if the two
items are equivalent.
*/
int CALLBACK myCompFunc(LPARAM lp1, LPARAM lp2, LPARAM sortParam)
{
    bool isAsc = (sortParam > 0);
    int column = abs(sortParam)-1;
    rssItem_t *item1, *item2;
    item1 = (rssItem_t*) lp1;
    item2 = (rssItem_t*) lp2;
    switch (column)
    {
        case 0:
            if (isAsc) return parseDateStr(item1->pubdate) - parseDateStr(item2->pubdate);
            else return parseDateStr(item2->pubdate) - parseDateStr(item1->pubdate);
            break;
        case 1:
            if (isAsc) return strcasecmp(item1->title.c_str(), item2->title.c_str());
            else return strcasecmp(item2->title.c_str(), item1->title.c_str());
        case 2:
            if (isAsc) return strcasecmp(item1->author.c_str(), item2->author.c_str());
            else return strcasecmp(item2->author.c_str(), item1->author.c_str());
            break;
    }
    return 0;
}
// +----------------------------------------------------------------------------
// | -OnColumnClick()-
// | Called whenever the user clicks one of the list view's column headings.
// +----------------------------------------------------------------------------
void OnColumnClick(LPNMLISTVIEW pLVInfo)
{
    static int nSortColumn = 0;
    static BOOL bSortAscending = TRUE;
    LPARAM lParamSort;
    // get new sort parameters
    if (pLVInfo->iSubItem == nSortColumn)
        bSortAscending = !bSortAscending;
    else
    {
        nSortColumn = pLVInfo->iSubItem;
        bSortAscending = TRUE;
    }
    // combine sort info into a single value we can send to our sort function
    lParamSort = 1 + nSortColumn;
    if (!bSortAscending)
        lParamSort = -lParamSort;
    // sort list
    ListView_SortItems(pLVInfo->hdr.hwndFrom, myCompFunc, lParamSort);
    setListViewSortIcon(pLVInfo->hdr.hwndFrom, nSortColumn, bSortAscending+1);
}
// state can be
// sortOrder - 0 neither, 1 ascending, 2 descending
void setListViewSortIcon(HWND listView, int col, int sortOrder)
{
    HWND headerWnd;
    const int bufLen = 256;
    char headerText[bufLen];
    HD_ITEM item;
    int numColumns, curCol;
    headerWnd = ListView_GetHeader(listView);
    numColumns = Header_GetItemCount(headerWnd);
    for (curCol=0; curCol<numColumns; curCol++)
    {
        item.mask = HDI_FORMAT | HDI_TEXT;
        item.pszText = headerText;
        item.cchTextMax = bufLen - 1;
        SendMessage(headerWnd, HDM_GETITEM, curCol, (LPARAM)&item);
        if ((sortOrder != 0) && (curCol==col))
        switch (sortOrder)
        {
            case 1:
                item.fmt &= !HDF_SORTUP;
                item.fmt |= HDF_SORTDOWN;
                break;
            case 2:
                item.fmt &= !HDF_SORTDOWN;
                item.fmt |= HDF_SORTUP;
                break;
        }
        else
        {
            item.fmt &= !HDF_SORTUP & !HDF_SORTDOWN;
        }
        item.fmt |= HDF_STRING;
        item.mask = HDI_FORMAT | HDI_TEXT;
        SendMessage(headerWnd, HDM_SETITEM, curCol, (LPARAM)&item);
    }
}