65.9K
CodeProject 正在变化。 阅读更多。
Home

MSDN 中 CListCtrl::SortItems(...) 的示例

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.74/5 (13投票s)

2002 年 2 月 27 日

viewsIcon

189783

文档中给出的 CListCtrl::SortItems(...) 示例,恰恰展示了使用该函数的**错误**方法。

查看 MSDN 中 CListCtrl::SortItems(...) 的文档,我们发现以下示例展示了如何按相反的字母顺序对项目进行排序

// Sort the item in reverse alphabetical order.
static int CALLBACK 
MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
   // lParamSort contains a pointer to the list view control.
   CListCtrl* pListCtrl = (CListCtrl*) lParamSort;
   CString    strItem1 = pListCtrl->GetItemText(lParam1, 0);
   CString    strItem2 = pListCtrl->GetItemText(lParam2, 0);

   return strcmp(strItem2, strItem1);
}

void snip_CListCtrl_SortItems()
{
   // The pointer to my list view control.
   extern CListCtrl* pmyListCtrl;

   // Sort the list view items using my callback procedure.
   pmyListCtrl->SortItems(MyCompareProc, (LPARAM) pmyListCtrl);
}
这种方法显然不起作用,原因如下:MyCompareProc(...) 的参数 - lParam1 和 lParam2 不是项目的索引,而是它们的 32 位关联值。

还有一个问题:即使我们将每个项目的 32 位关联值设置为与项目索引相同,此示例仍然无法工作。这是因为项目在每次调用 MyCompareProc(...) 时都会改变位置,并且 32 位关联值将不再代表项目的索引。

只有当我们存储一个指针在 32 位关联值中,并且想要根据该指针中的某个值对项目进行排序时,函数 CListCtrl::SortItems(...) 才有用。

在 CListCtrl 派生类中实现反向字母排序的一种简单方法是使用 STL 集合

#pragma warning(disable : 4786)
#include <functional>
#include <set>

struct LVITEM_less : public std::binary_function<LVITEM*, LVITEM*, bool>
{
    bool operator()(const LVITEM* pItem1, const LVITEM* pItem2) const
    {
        CString strItem1(pItem1->pszText);
        CString strItem2(pItem2->pszText);

        return (strItem1 < strItem2);
    }
};

void CSortableListCtrl::SortItemsDescending()
{
    // Sort all items in descending aphabetical order using an STL set
    typedef std::set<LVITEM*, LVITEM_less> ItemSet;
    ItemSet setItems;
    int iCount = GetItemCount();
    for (int i = 0; i < iCount; i++)
    {
        LVITEM* pLVI = new LVITEM();
        ::memset(pLVI, 0, sizeof(LVITEM));
        pLVI->iItem = i;
        pLVI->mask = LVIF_IMAGE | LVIF_INDENT | LVIF_PARAM | LVIF_STATE | LVIF_TEXT;
        pLVI->pszText = new TCHAR[1024];
        pLVI->cchTextMax = 1024;
        GetItem(pLVI);

        setItems.insert(pLVI);
    }

    // Remove all items from the list control
    DeleteAllItems();

    // Put the items back in the list control in reverse order
    int iIndex = 0;
    for (ItemSet::reverse_iterator it = setItems.rbegin(); it != setItems.rend(); ++it)
    {
        (*it)->iItem = iIndex++;
        InsertItem(*it);
        delete [] (*it)->pszText;
        delete *it;
    }
}
© . All rights reserved.