c++ - 使用 ListView 对表格进行排序

标签 c++ winapi jquery-ui-sortable

我正在编写使用 listView 的小程序,我想将表中的数据排序到我单击的列,并且当我使用 ListView_SortItems 进行比较时是传递三个参数。问题是在函数 comp 元素 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。如果它是负数,我按一种方式排序(升序/降序),如果它是正数,我按另一种方式排序。该数字只是标题被单击的从 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);
    }
}

关于c++ - 使用 ListView 对表格进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22879397/

相关文章:

c++ - 如何从 Boost Spirit X3 词素解析器中获取字符串?

c - 多线程单服务器多客户端应用程序中的阻塞套接字与非阻塞套接字

jQuery UI 可排序,就像 Windows 资源管理器文件/文件夹列表一样

jQuery sortable - 检测项目是否在列表中向上或向下移动

c++ - 初始化一个 GUID 变量 : How?

c++ - 如何在 gcc v4.1.2 中获取 unordered_set 的 header ?

c++ - 单元测试 Boost 文件系统 create_directories

c++ - 从 PNG 加载 Gdiplus 的 HICON 质量低

winapi - 同步 WinHTTP 请求的异步回调调用

Jquery 在可排序列表上拖放