Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

clistctrl sorting problem

Status
Not open for further replies.

dima2

Programmer
Jan 20, 2002
85
0
0
LB
hi,
I'm developing an MFC dialog based application.
in my dialog i have a CListCtrl object in which i've inserted 3 columns. Whenever I insert a new item in the list i set it's itemdata equal to it's index.
what i'm trying to do is sort the items in alphabetical order based on the text in a selected column.
so when the user clicks on the column the items should be sorted.

I trapped the LVN_COLUMNCLICK notification and in the hadling function i put the following:

void CMyDlg::OnColumnclickList(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

nSortedCol = pNMListView->iSubItem;
//nSortedCol is a static member variable of the class CMyDlg

m_list.SortItems(SortList, (LPARAM) &m_list);
*pResult = 0;
}

I defined the compare function as a static member as follows:
int CEmailNotDlg::SortList(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
CListCtrl* pListCtrl = (CListCtrl*) lParamSort;
CString strItem1 = pListCtrl->GetItemText(lParam1, nSortedCol);
CString strItem2 = pListCtrl->GetItemText(lParam2, nSortedCol);

int ret=-wcsicmp(strItem2, strItem1);
return ret;
}


Now here comes the question:
when I first click on a colum the sorting is carried out perfectly, HOWEVER if I click again the rows are switched randomly. What's going on??

i would really appreciate any sort of help

thx a lot
 
You can use callback fn to sort the data
I wrote like this..

create a structure with the columns...
for eg., i 've 3 columns first name, last name and term
typedef struct {
LPTSTR pszLastName;
LPTSTR pszFirstName;
LPTSTR pszTerm;
} ITEMDATA, *PITEMDATA;
and use this structure to fill the list control..

for eg to insert an item...
ITEMDATA m_pData[10];

m_pData = new ITEMDATA;
m_pData->pszLastName = "Sachin";
m_pData->pszFirstName = "Tendulkar";
m_pData->pszTerm = "1989-2002*";

m_ctlListView.InsertItem(i, "Sachin");
m_ctlListView.SetItemText(i, 1, "Tendulkar");
m_ctlListView.SetItemText(i, 2, "1989-2002*");
m_ctlListView.SetItemData(i, (LPARAM)m_pData);

OnColumnClick....
=================
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
m_ctlListView.SortItems(SortFunc,pNMListView>iSubItem);

and the call back fn...
=======================
int CALLBACK SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
int nRetVal;

PITEMDATA pData1 = (PITEMDATA)lParam1;
PITEMDATA pData2 = (PITEMDATA)lParam2;


switch(lParamSort)
{
case 0: // Last Name
nRetVal = strcmp(pData1->pszLastName,
pData2->pszLastName);
break;

case 1: // First Name
nRetVal = strcmp(pData1->pszFirstName,
pData2->pszFirstName);
break;

case 2: // Term
nRetVal = strcmp(pData1->pszTerm, pData2->pszTerm);
break;

default:
break;
}

return nRetVal;
}
 
When I try this solution (I get find that lParam1 and lParam2 are always zero.

Here is a snippet of my code.
typedef struct {
LPTSTR pszFeature;
LPTSTR pszVersion;
LPTSTR pszClient;
LPTSTR pszClientNode;
int numLicenses;
int usedLicenses;
} ITEMDATA, *PITEMDATA;

ITEMDATA m_pData[100];


static int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{

ITEMDATA* p1 = (ITEMDATA*)lParam1;
ITEMDATA* p2 = (ITEMDATA*)lParam2;
CString s1 = p1->pszFeature;
CString s2 = p2->pszFeature;

TRACE(_T("Address of lParam1 is: %08x AND lParam2 is %08lx\n"), lParam1, lParam2);

return strcmp(strItem2, strItem1);

}

//
// I populated the ITEMDATA structure as follows..
//
ITEMDATA* pData = new ITEMDATA;
pData->pszFeature = featureInfo->feature_name;
pData->pszVersion = featureInfo->version;

//
// finally, here is what I did on the ItemClick
//
void CABBQCSLicViewerDlg::OnColumnclickList3(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here

// Sort the list view items using my callback procedure.
m_ReportListCTRL.SortItems(MyCompareProc,
(LPARAM) pNMListView->iSubItem);

*pResult = 0;
}

//
//
// Incidenetally, where does the lParam1 and lParam2 parameter even come from in the callback function? I don't see how those parameters get setup. Maybe that is part of my problem, although, as far as I can tell I've implemented my code the same as the example.

I also noticed that m_pData was allocated as a fixed array, but also it was allocated using the new function. I did the same but don't see the need to have the fixed array of ITEMDATA structures. I tried it both ways, but still get zeroes in both the lParam1 and lParam2 parameters when I get to the static CALLBACK function. Needless to say, that causes an exception when I try to fetch the parameters from the ITEMDATA casts of Lparam1 and lParam2.

I sure hope someone will help with this one.

Thanks, Bob
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top