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






2.74/5 (13投票s)
2002 年 2 月 27 日

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; } }