Reputation: 11237
In this winapi program, I am sorting all the items based on the "Date" column. However, it is sorting by the "Description" column instead of the "Date" column.
Here is the code in WM_NOTIFY:
static char szText[10];
NM_LISTVIEW *pNm = (NM_LISTVIEW *)lParam;
switch (((LPNMHDR)lParam)->code) {
case LVN_COLUMNCLICK:
if (pNm->iSubItem == 2)
if (ListView_SortItems(pNm->hdr.hwndFrom, CompareFunc,
(LPARAM) (pNm->iSubItem)) == FALSE)
MessageBox(hwnd, "FALSE", "", MB_OK);
break;
/* other WM_NOTIFY code */
}
ListView_SortItems
returns TRUE, strangely.
Here is the CompareFunc function:
int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
if (lParamSort == 2) {
date d1, d2; // app-defined "date" class
char b1[32], b2[32];
sscanf((char *) lParam1, "%s %d %d", b1, &d1.day, &d1.yr);
sscanf((char *) lParam2, "%s %d %d", b2, &d2.day, &d2.yr);
d1.month = monthtoi(b1); // converts month as string to number
d2.month = monthtoi(b2);
if (d1 > d2) // overloading the ">" and "<" operators
return 1;
else if (d1 < d2)
return -1;
return 0;
}
}
I tried checking iSubItem against 3 rather than 2 (1-based vs 0-based), but that didn't work either. What am I doing wrong?
Edit:
int monthtoi(char *s)
{
int i;
for (i = 0; i < 12; ++i) {
// MONTHS is a global array of char *, containing the months
if (strcmp(MONTHS[i], s) == 0)
return i;
}
return -1;
}
bool date::operator>(const date &x)
{
switch (this->cmp(x)) { // cmp is a private member function
case 0:
case -1:
return false;
case 1:
return true;
}
return false;
}
bool date::operator<(const date &x)
{
switch (this->cmp(x)) {
case 0:
case 1:
return false;
case -1:
return true;
}
return false;
}
int date::cmp(const date &x)
{
if (this->yr > x.yr)
return 1;
else if (this->yr < x.yr)
return -1;
if (this->yr == x.yr) {
if (this->month > x.month)
return 1;
else if (this->month < x.month)
return -1;
else if (this->day > x.day)
return 1;
else if (this->day < x.day)
return -1;
else
return 0;
}
return 0;
}
Upvotes: 2
Views: 530
Reputation: 6204
The input lParam1
and lParam2
are not the string of the sub-item but as the documentation says they are the data associated with the item:
The lParam1 parameter is the 32-bit value associated with the first item being compared; and the lParam2 parameter is the value associated with the second item. These are the values that were specified in the lParam member of the items' LVITEM structure when they were inserted into the list.
You can find a complete ListView sorting example here but the basics of it are as follows:
// Custom type storing the item's information, or a link to it
struct myitemdata_t
{
char* pFood;
char* pDescription;
date Date;
...
};
// When adding items to a listview set the item data
m_ctlListView.InsertItem(i, "food");
m_ctlListView.SetItemText(i, 1, "Saturday shopping");
...
// Set the item data for the list item
m_ctlListView.SetItemData(i, (LPARAM) GetItemData(i));
// Your sort function should look like
int CALLBACK SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
myitemdata_t* pData1 = (myitemdata_t *)lParam1;
myitemdata_t* pData2 = (myitemdata_t *)lParam2;
...
Upvotes: 2