?
Solved

CListCtrl, LVS_SORTASCENDING and LVITEM.lParam

Posted on 2000-03-21
2
Medium Priority
?
1,633 Views
Last Modified: 2013-11-20
I am using an Explorer-type application generated in Visual C++ 6.0 and I'm trying to populate the CListCtrl depending on values selected in the CTreeCtrl.  I am storing a pointer to an object in the ItemData of each CListCtrl entry.

My problem is that when using the LVS_SORTASCENDING style for the list control, the labels seem to get sorted, but the underlying LVITEMs don't seem to be following suit. If the item sort order differs from my item insertion order, then the ItemData for the item is null.

I wish to use the CListCtrl's default behaviour of sorting based on the ItemText.

I would assume that the CListCtrl actually sorts (and moves around) individual LVITEM structs under the covers (I think the CTreeCtrl does this) but the behaviour of the CListCtrl seems to indicate that LVITEMs and the item labels themselves are entirely different creatures.

The Insertion and Retrieval routines are below:

void CAdminClientView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
   CAdminClientDoc*   pDoc = GetDocument();
   CListCtrl&   ctlList = GetListCtrl();

   LISTINFOVECTOR::iterator it;

   // LISTINFOVECTOR is a vector<listInfo>
   //  typedef struct listInfoStruct {
   //      CString strLabel;
   //      LPARAM lParam;   // a pointer to a CKindOfRecord object
   //   } listInfo;

   ctlList.DeleteAllItems();

   LISTINFOVECTOR* pLst = pDoc->GetListItems();
      
   int i = 0;
   for ( it = pLst->begin(); it < pLst->end(); it++)
   {
      int rc = ctlList.InsertItem(i, (LPCTSTR)(it->strLabel));
      rc = ctlList.SetItemData(i, it->lParam);

      // following line just to verify values in debugger
      DWORD res = ctlList.GetItemData(i);

      i++;
   }

The retrieval routine I'm using to retrieve the ItemData goes something like this:

   CAdminClientDoc* pDoc = GetDocument();
   CListCtrl& ctlList = GetListCtrl();
   void* pRec = 0;

   // following algorithm shamelessly pilfered from MSDN
   POSITION pos = ctlList.GetFirstSelectedItemPosition();
   if (pos == NULL)
   {
      TRACE0("No items were selected!\n");
   }
   else
   {
      while (pos)
      {
         int nItem = ctlList.GetNextSelectedItem(pos);
         TRACE1("Item %d was selected!\n", nItem);

         CString strTest = ctlList.GetItemText( nItem, 0 );

         // following lines expanded for walking through debugger with
         DWORD temp = ctlList.GetItemData(nItem);
         pRec = (void*)temp;
         CKindOfRecord* pWorkRec = (CKindOfRecord*)pRec;
      }
}

Does storing ItemData throw off the sort routine? Will I have to implement a callback sort function? Will I have to manually intercept an LVM_SORTITEMS message?

Thanks,
0
Comment
Question by:ayang_ca
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
2 Comments
 
LVL 2

Accepted Solution

by:
paulburns earned 400 total points
ID: 2642218
I think your problem is in using 'i' in setting the item data...

int rc = ctlList.InsertItem(i, (LPCTSTR)(it->strLabel));
rc = ctlList.SetItemData(i, it->lParam);

Change this to...

int rc = ctlList.InsertItem(i, (LPCTSTR)(it->strLabel));
if (rc != -1)
   ctlList.SetItemData(rc, it->lParam);


The reason is that when you insert the item the list control will sort it and possibly change its index, therefore 'i' will no longer be its index.
0
 

Author Comment

by:ayang_ca
ID: 2644755
Excellent! Just what I needed. Thanks.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
Suggested Courses

801 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question