CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Jun 2007
    Posts
    6

    [RESOLVED] Strange CListCtrl Sort Behaviour

    Hi There!

    First of all, thank you all for your participation i this board! I am watching it frequently and it has helped me many many times by now!

    This is the first time I encounter a problem, to wich I can not find a solution here!

    I am trying to sort a CListCtrl. The Control has the colums "Last Name","First Name", "Date of Birth" and "ID" wich is a unique number.
    (if Patients are displayed, there is also the possibility that the List contains Measurements, but that's not the topic right now! Trying to sort the Patients first!)

    If i sort the List for "First Name" it works once. Second time I do it, the List gets back to the prev. sort order! If I dont sort for First name the second time, but for Patients ID, everything is in a chaos (no sorting to recognize!).

    Here is my Callback Function:

    Code:
    void CAngEDlg::OnLvnColumnclickListe(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    	m_ColToSort=pNMLV->iSubItem; //Store the Column To Sort in Member Var.
    	m_pListe->SortItems((PFNLVCOMPARE)MyCompareProc, (LPARAM) m_pListe);//Try to Sort
    	*pResult = 0;
    }
    
    //Sortier-Callback
    int CALLBACK CAngEDlg::MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
    {
    	CAngEDlg* main;
    	   // lParamSort contains a pointer to the list view control.
    	CListCtrl* pListCtrl = (CListCtrl*) lParamSort;
    	main=(CAngEDlg*)pListCtrl->GetParent(); //Get Parent to access members
    	if(main->m_bPatientsListed)	//If Patients are displayed, do the following
    	{
    		CString    strItem1 = pListCtrl->GetItemText(lParam1, main->m_ColToSort);
    		CString    strItem2 = pListCtrl->GetItemText(lParam2, main->m_ColToSort);
    		if( main->m_ColToSort==0 ||  main->m_ColToSort==1) //Sort for First or Second Name
    			return strcmp( strItem1,strItem2);
    		if( main->m_ColToSort==3) // Sort for unique ID
    		{
    			int aa;
    			int b;
    			aa = atoi (strItem1);
    			b= atoi (strItem2);
    			if(aa<b) return 1;
    			else -1;
    		}
    		//No Sorting for Birthday yet!
    	}
    	else //If Measurements are displayed, do nothing by now
    	{
    
    	}
    	return 0;
    }
    Any Ideas??
    Thank's in advance
    Marc

  2. #2
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Strange CListCtrl Sort Behaviour

    Not sure if this is the only problem, but you forgot to "return" a value in one of the if's:

    Code:
    void CAngEDlg::OnLvnColumnclickListe(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    	m_ColToSort=pNMLV->iSubItem; //Store the Column To Sort in Member Var.
    	m_pListe->SortItems((PFNLVCOMPARE)MyCompareProc, (LPARAM) m_pListe);//Try to Sort
    	*pResult = 0;
    }
    
    //Sortier-Callback
    int CALLBACK CAngEDlg::MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
    {
    	CAngEDlg* main;
    	   // lParamSort contains a pointer to the list view control.
    	CListCtrl* pListCtrl = (CListCtrl*) lParamSort;
    	main=(CAngEDlg*)pListCtrl->GetParent(); //Get Parent to access members
    	if(main->m_bPatientsListed)	//If Patients are displayed, do the following
    	{
    		CString    strItem1 = pListCtrl->GetItemText(lParam1, main->m_ColToSort);
    		CString    strItem2 = pListCtrl->GetItemText(lParam2, main->m_ColToSort);
    		if( main->m_ColToSort==0 ||  main->m_ColToSort==1) //Sort for First or Second Name
    			return strcmp( strItem1,strItem2);
    		if( main->m_ColToSort==3) // Sort for unique ID
    		{
    			int aa;
    			int b;
    			aa = atoi (strItem1);
    			b= atoi (strItem2);
    			if(aa<b) return 1;
    			else return   -1;
    		}
    		//No Sorting for Birthday yet!
    	}
    	else //If Measurements are displayed, do nothing by now
    	{
    
    	}
    	return 0;
    }
    Mike

  3. #3
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Strange CListCtrl Sort Behaviour

    In addition, you forgot to store each item's current index into the "extra data" part of each item. If you are not using the data part of each item for some other purpose, then the simplest way is simply to set the data item to the item's current index, as shown below. If you are using the data part of each item for some purpose, then you will need to modify the structure that it points to, so as to include an extra member for storing the current value of the item's index, and extract the index in the sort callback function.
    Code:
    void CAngEDlg::OnLvnColumnclickListe(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    	m_ColToSort=pNMLV->iSubItem; //Store the Column To Sort in Member Var.
    
    	// insert item indices into the "extra" data of each entry
    	// so as to match the expected data passed to the sort callback function
    
    	int iCount = m_pList->GetItemCount();
    
    	for (int i=0; i < iCount; i++)
    	{
    		m_pListe->SetItemData(i, static_cast<DWORD>(i) );
    	}
    
    	m_pListe->SortItems((PFNLVCOMPARE)MyCompareProc, (LPARAM) m_pListe);//Try to Sort
    	*pResult = 0;
    }
    
    //Sortier-Callback
    int CALLBACK CAngEDlg::MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
    {
    	CAngEDlg* main;
    	   // lParamSort contains a pointer to the list view control.
    	CListCtrl* pListCtrl = (CListCtrl*) lParamSort;
    	main=(CAngEDlg*)pListCtrl->GetParent(); //Get Parent to access members
    	if(main->m_bPatientsListed)	//If Patients are displayed, do the following
    	{
    		CString    strItem1 = pListCtrl->GetItemText(lParam1, main->m_ColToSort);
    		CString    strItem2 = pListCtrl->GetItemText(lParam2, main->m_ColToSort);
    		if( main->m_ColToSort==0 ||  main->m_ColToSort==1) //Sort for First or Second Name
    			return strcmp( strItem1,strItem2);
    		if( main->m_ColToSort==3) // Sort for unique ID
    		{
    			int aa;
    			int b;
    			aa = atoi (strItem1);
    			b= atoi (strItem2);
    			if(aa<b) return 1;
    			else return   -1;
    		}
    		//No Sorting for Birthday yet!
    	}
    	else //If Measurements are displayed, do nothing by now
    	{
    
    	}
    	return 0;
    }
    Mike

  4. #4
    Join Date
    Jun 2007
    Posts
    6

    Re: Strange CListCtrl Sort Behaviour

    Hi Mike

    Thanks a lot!
    That works now!
    The forgotten return has not solved the problem, but the "SetItemData" thingie.

    I have already filled the SetItemData during building up the list, but maybe something went wrong there.
    Or do i have to "reorganize" this field each time before sorting??

    Anyway, thank you!

  5. #5
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Strange CListCtrl Sort Behaviour

    You need to reorganize it each time before sorting, so that it correctly reflects the currect index of the item.

    Glad it works now.

    Mike

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured