When I need to do it, I use the lParam of each item added to the listView to point to the struct that contains the item itself. This way, when in the compare function, you can simply use the two lParam values to access all of the data that each item in the listView represents.
This allows you (for instance) to use the lParamSort param as a way of telling your sorting function how to behave. I often use this to designate the column I'd like to base the sort on, using negative or positive to designate the direction.
Here's an addItems func and the sortFunc that goes with that listView
if (numItems != 0)
{
HWND lvWnd = GetDlgItem(mainDlgHwnd, IDC_ITEM_LIST);
clearListView(lvWnd);
for (int i=0; i<numitems;> {
addListViewItem(lvWnd,
(char*)makeNiceDate(curFeedItems[i].pubdate).c_str(),
(char*)curFeedItems[i].title.c_str(),
(char*)curFeedItems[i].author.c_str(),
(LPARAM)&curFeedItems[i]);
}
}
lParamSort = 1 + nSortColumn;
if (!bSortAscending)
lParamSort = -lParamSort;
ListView_SortItems(pLVInfo->hdr.hwndFrom, myCompFunc, lParamSort);
typedef struct
{
string title;
string description;
string link;
string author;
string pubdate;
string subject;
} rssItem_t;
void addListViewItem(HWND listView, char *timeStr, char *titleStr, char *authorStr, LPARAM ptrToInRssItem)
{
LV_ITEM newItem;
int insertIndex;
insertIndex = ListView_GetItemCount(listView);
newItem.mask = LVIF_TEXT|LVIF_PARAM;
newItem.iItem = insertIndex;
newItem.pszText = timeStr;
newItem.cchTextMax = strlen(timeStr);
newItem.iSubItem = 0;
newItem.lParam = ptrToInRssItem;
insertIndex = SendMessage(listView, LVM_INSERTITEM, 0, (LPARAM)&newItem);
newItem.mask = LVIF_TEXT;
newItem.pszText = titleStr;
newItem.cchTextMax = strlen(titleStr);
newItem.iSubItem = 1;
SendMessage(listView, LVM_SETITEM, 0, (LPARAM)&newItem);
newItem.mask = LVIF_TEXT;
newItem.pszText = authorStr;
newItem.cchTextMax = strlen(authorStr);
newItem.iSubItem = 2;
SendMessage(listView, LVM_SETITEM, 0, (LPARAM)&newItem);
}
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;
}