I have a list view report style. Im trying to sort by click on a header. For some reason it does nothing.

This Peice of code is invoked when the column is clicked.

if (pnm->hdr.code == LVN_COLUMNCLICK)
	{
	 //DialogBoxParam(ghInstance, MAKEINTRESOURCE(IDD_SORT), 
	 // NULL, (DLGPROC)SortDlgProc, 0); 
	 if(nSortDir[pnm->iSubItem])
	 nSortDir[pnm->iSubItem] = false;
	 else
	 nSortDir[pnm->iSubItem] = true;
 
	 ListView_SortItems (hList, ListViewCompareProc, pnm->iSubItem);
 
 
	 nItem1=0;
	 return 0;
	}

Now Here is my Call back function

int CALLBACK ListViewCompareProc (LPARAM lParam1, LPARAM lParam2, LPARAM
lParamSort)
{
static LV_FINDINFO fi;
static int		 nItem1, nItem2;
static char		szBuf1[30], szBuf2[30];
 
// Determine the items that we are comparing.
//...........................................
fi.flags = LVFI_PARAM;
fi.lParam = lParam1;
nItem1 = ListView_FindItem(hList, -1, &fi);
 
fi.lParam = lParam2;
nItem2 = ListView_FindItem(hList, -1, &fi);
 
// Retrieve the item text so we can compare it.
//.............................................
ListView_GetItemText(hList, nItem1, lParamSort, szBuf1,
sizeof(szBuf1));
ListView_GetItemText(hList, nItem2, lParamSort, szBuf2,
sizeof(szBuf2));
 
// Return the comparison results.
//...............................
if (nSortDir[lParamSort] ) // ACENDING ORDER
	return(strcmp(szBuf1, szBuf2));
else
	return(strcmp(szBuf1, szBuf2) * -1);
}

According to MSDN, the Sort Macro should handle the results of the callback just like strcmp, and switch the items accordingly. Once again, the callback function is called and works, yet it does not sort properly, what could be wrong?

It looks kosher. Can you debug it and make sure the two strings are being fetched?

thoughts: What happens if the strings are > 30 bytes? Why are the strings static? Just to save stack space? Do you need to invalidate the list view to get it to redraw?

Since the callback function pretty much enumerates the list, I made the buffers static to save space on the stack.

I did find something funny after playing with it. The two strings that are being compared are always the same. From this I have concluded that the LPARAM value returned from the Find Item macro is pointing to the same item.

It dosn't really make sense since the two LPRAM items being compared are passed in as different values.

I'm so lost :cry:

Hey I got it working!!!!!!! After digging a bit more through MSDN I came up with a solution. The problem was that finding the item index, for the purpose of getting the text is unstable within the call back procedure, the index returned by the lparam found, will always be the same. The solution was to use ListView_SortItemsEx macro instead of ListView_SortItems. The reason being is that ListView_SortItemsEx passes the intem index as the first two prarmeters of the callback procedure, where as ListView_SortItems simple passes the lparam. IT ALL MAKES SO MUCH SENSE NOW. Think about it why would you ever need to use ListView_SortItems? For owner drawn lists where sometimes, text is not avaible! So for anything text oriented ListView_SortItemsEx would be the right macro to use.

Here is the working code for listview sorting and callback.

if (pnm->hdr.code == LVN_COLUMNCLICK)
 
{
 
//DialogBoxParam(ghInstance, MAKEINTRESOURCE(IDD_SORT), 
 
// NULL, (DLGPROC)SortDlgProc, 0); 
 
if(nSortDir[pnm->iSubItem])
 
nSortDir[pnm->iSubItem] = false;
 
else
 
nSortDir[pnm->iSubItem] = true;
 
ListView_SortItemsEx(hList, ListViewCompareProc, pnm->iSubItem);
 
nItem1=0;
 
return 0;
 
}

and for the callback....

int CALLBACK ListViewCompareProc (LPARAM lParam1, LPARAM lParam2, LPARAM
 
lParamSort)
 
{
 
staticchar szBuf1[30], szBuf2[30];
 
// Determine the items that we are comparing.
 
//...........................................
 
 
 
// Retrieve the item text so we can compare it.
 
//.............................................
 
ListView_GetItemText(hList, lParam1, lParamSort, szBuf1,
 
sizeof(szBuf1));
 
ListView_GetItemText(hList, lParam2, lParamSort, szBuf2,
 
sizeof(szBuf2));
 
// Return the comparison results.
 
//...............................
 
if (nSortDir[lParamSort] ) // ACENDING ORDER
 
return(strcmp(szBuf1, szBuf2) * -1);
 
else
 
return(strcmp(szBuf1, szBuf2));
 
}

As simple as that! Thnx for the help.

This article has been dead for over six months. Start a new discussion instead.