Sorting Items in Response to a Column Header Click

In the preceding C code, I handled a click on a column header by calling the ListView_SortItems macro and providing a pointer to a callback function. It is up to the application to provide the code to sort list view items when the user clicks a column header; the list view control does not sort the items for you. (Drat!) This makes some sense (albeit in a twisted kind of way)—how would the system know which criterion to use for the sort (for example, color or size)? Nevertheless, I wish that Windows 95 provided some built-in sorting callbacks for “standard” sorting needs such as string comparisons and numeric sorts. Because the list view control lacks this capability, you must provide a callback function to do the sorting. The saving grace is that this isn't hard to do.

The following code demonstrates one method of sorting. It uses the lstrcmpi function to compare strings and uses simple arithmetic to sort numbers. The callback function is given pointers to the two items to compare; it returns a negative value if the first item should precede the second, a positive value if the first item should follow the second, or 0 if the two items are equivalent. The lParamSort parameter is an application-defined value (which I did not use in my function). It would be useful in the sort to include any special information about the sort criterion. For instance, if you want to let the user specify whether to sort forward or backward, you can pass an indication of this in the lParamSort parameter.

int CALLBACK ListViewCompareProc (LPARAM lParam1, LPARAM
lParam2,
LPARAM lParamSort)
{
HOUSEINFO *pHouse1 = (HOUSEINFO *)lParam1;
HOUSEINFO *pHouse2 = (HOUSEINFO *)lParam2;
LPSTR lpStr1, lpStr2;
int iResult;

if (pHouse1 && pHouse2)
{
switch (lParamSort)
{
case 0: // sort by address
lpStr1 = pHouse1->szAddress;
lpStr2 = pHouse2->szAddress;
iResult = lstrcmpi (lpStr1, lpStr2);
break;

case 1: // sort by city
lpStr1 = pHouse1->szCity;
lpStr2 = pHouse2->szCity;
iResult = lstrcmpi (lpStr1, lpStr2);
break;

case 2: // sort by price
iResult = pHouse1->iPrice - pHouse2->iPrice;
break;

case 3: // sort by number of bedrooms
iResult = pHouse1->iBeds - pHouse2->iBeds;
break;

case 4: // sort by number of bathrooms
iResult = pHouse1->iBaths - pHouse2->iBaths;
break;

default:
iResult = 0;
break;
}
}

return (iResult);
}