Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Sorting items in CListCtrl ? Sample from MSDN..

Sorting items in CListCtrl ? Sample from MSDN..

Scheduled Pinned Locked Moved C / C++ / MFC
questiontutorialdatabasealgorithmshelp
8 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    Lost User
    wrote on last edited by
    #1

    Hello, folks, I got some trouble on sorting items in my CListCtrl. That is, I have a list control (i.e, of type CListCtrl), and this list control has 4 columns. I want to sort the items on this list control by a given column (i.e, clicking the column header on the GUI of this list control.)Now, I found some sample codes from MSDN but I don't understand. I posted the MSDN sample as follows. My question is: where and how to pass the 2 parameters (lParam1 and lParam2) to the callback function ? Because I don't know the sample code has something to do with passing 2 parameters (lparam1 and lparam2) to the callback function (MyCompareProc). And, this MyCompareProc callback function just compares 2 items ? If my list control has more than 2 items, what is the mechanism about this compare function ? And how can I use this callback function to sort many many items in my list control ? Thanks for your help ! Any response would be greatly appreciated ! Example // Sort the item in reverse alphabetical order. static int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { // lParamSort contains a pointer to the list view control. // The lParam of an item is just its index. CListCtrl* pListCtrl = (CListCtrl*) lParamSort; CString strItem1 = pListCtrl->GetItemText(lParam1, 0); CString strItem2 = pListCtrl->GetItemText(lParam2, 0); return strcmp(strItem2, strItem1); } void snip_CListCtrl_SortItems() { // The pointer to my list view control. extern CListCtrl* pmyListCtrl; // Sort the list view items using my callback procedure. pmyListCtrl->SortItems(MyCompareProc, (LPARAM) pmyListCtrl); }

    K O 3 Replies Last reply
    0
    • L Lost User

      Hello, folks, I got some trouble on sorting items in my CListCtrl. That is, I have a list control (i.e, of type CListCtrl), and this list control has 4 columns. I want to sort the items on this list control by a given column (i.e, clicking the column header on the GUI of this list control.)Now, I found some sample codes from MSDN but I don't understand. I posted the MSDN sample as follows. My question is: where and how to pass the 2 parameters (lParam1 and lParam2) to the callback function ? Because I don't know the sample code has something to do with passing 2 parameters (lparam1 and lparam2) to the callback function (MyCompareProc). And, this MyCompareProc callback function just compares 2 items ? If my list control has more than 2 items, what is the mechanism about this compare function ? And how can I use this callback function to sort many many items in my list control ? Thanks for your help ! Any response would be greatly appreciated ! Example // Sort the item in reverse alphabetical order. static int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { // lParamSort contains a pointer to the list view control. // The lParam of an item is just its index. CListCtrl* pListCtrl = (CListCtrl*) lParamSort; CString strItem1 = pListCtrl->GetItemText(lParam1, 0); CString strItem2 = pListCtrl->GetItemText(lParam2, 0); return strcmp(strItem2, strItem1); } void snip_CListCtrl_SortItems() { // The pointer to my list view control. extern CListCtrl* pmyListCtrl; // Sort the list view items using my callback procedure. pmyListCtrl->SortItems(MyCompareProc, (LPARAM) pmyListCtrl); }

      K Offline
      K Offline
      Koep
      wrote on last edited by
      #2

      Hello, try this ! ::SendMessage(pmyListCtrl->GetSafeHwnd(), LVM_SORTITEMS, (LPARAM)this, (LPARAM)(PFNLVCOMPARE)CRightView1::MyCompareProc); Marco

      1 Reply Last reply
      0
      • L Lost User

        Hello, folks, I got some trouble on sorting items in my CListCtrl. That is, I have a list control (i.e, of type CListCtrl), and this list control has 4 columns. I want to sort the items on this list control by a given column (i.e, clicking the column header on the GUI of this list control.)Now, I found some sample codes from MSDN but I don't understand. I posted the MSDN sample as follows. My question is: where and how to pass the 2 parameters (lParam1 and lParam2) to the callback function ? Because I don't know the sample code has something to do with passing 2 parameters (lparam1 and lparam2) to the callback function (MyCompareProc). And, this MyCompareProc callback function just compares 2 items ? If my list control has more than 2 items, what is the mechanism about this compare function ? And how can I use this callback function to sort many many items in my list control ? Thanks for your help ! Any response would be greatly appreciated ! Example // Sort the item in reverse alphabetical order. static int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { // lParamSort contains a pointer to the list view control. // The lParam of an item is just its index. CListCtrl* pListCtrl = (CListCtrl*) lParamSort; CString strItem1 = pListCtrl->GetItemText(lParam1, 0); CString strItem2 = pListCtrl->GetItemText(lParam2, 0); return strcmp(strItem2, strItem1); } void snip_CListCtrl_SortItems() { // The pointer to my list view control. extern CListCtrl* pmyListCtrl; // Sort the list view items using my callback procedure. pmyListCtrl->SortItems(MyCompareProc, (LPARAM) pmyListCtrl); }

        O Offline
        O Offline
        Orbital
        wrote on last edited by
        #3

        You will never call by youself MyCompareProc().It is called by SortItem which internaly implement some kind of sorting algoritm witch need to have a way to compare 2 elements. So your list may have any number of elements ... Bye, Orbital^ ...the night is long ... but not long enought to do some real coding ...

        1 Reply Last reply
        0
        • L Lost User

          Hello, folks, I got some trouble on sorting items in my CListCtrl. That is, I have a list control (i.e, of type CListCtrl), and this list control has 4 columns. I want to sort the items on this list control by a given column (i.e, clicking the column header on the GUI of this list control.)Now, I found some sample codes from MSDN but I don't understand. I posted the MSDN sample as follows. My question is: where and how to pass the 2 parameters (lParam1 and lParam2) to the callback function ? Because I don't know the sample code has something to do with passing 2 parameters (lparam1 and lparam2) to the callback function (MyCompareProc). And, this MyCompareProc callback function just compares 2 items ? If my list control has more than 2 items, what is the mechanism about this compare function ? And how can I use this callback function to sort many many items in my list control ? Thanks for your help ! Any response would be greatly appreciated ! Example // Sort the item in reverse alphabetical order. static int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { // lParamSort contains a pointer to the list view control. // The lParam of an item is just its index. CListCtrl* pListCtrl = (CListCtrl*) lParamSort; CString strItem1 = pListCtrl->GetItemText(lParam1, 0); CString strItem2 = pListCtrl->GetItemText(lParam2, 0); return strcmp(strItem2, strItem1); } void snip_CListCtrl_SortItems() { // The pointer to my list view control. extern CListCtrl* pmyListCtrl; // Sort the list view items using my callback procedure. pmyListCtrl->SortItems(MyCompareProc, (LPARAM) pmyListCtrl); }

          K Offline
          K Offline
          Koep
          wrote on last edited by
          #4

          Hi again, here a snipit from MSDN: The comparison function has the following form: int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); 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. The lParamSort parameter is the same value passed to the LVM_SORTITEMS message. U have to fill the params associated with the items/subitems first. For instance, pointer to the DataClass instance. Then u can get/compare everything from inside the class. I had implemented today, and this is the fastest and easiest way to do sorting in a listcontrol. Marco

          L 2 Replies Last reply
          0
          • K Koep

            Hi again, here a snipit from MSDN: The comparison function has the following form: int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); 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. The lParamSort parameter is the same value passed to the LVM_SORTITEMS message. U have to fill the params associated with the items/subitems first. For instance, pointer to the DataClass instance. Then u can get/compare everything from inside the class. I had implemented today, and this is the fastest and easiest way to do sorting in a listcontrol. Marco

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #5

            >>U have to fill the params associated with the items/subitems first. >>For instance, pointer to the DataClass instance. Then u can get/compare >>everything from inside the class. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Thanks ! I have tried it. But I still got some problems on this lParam1 and lParam2. That is, when I implement the Compare Function just like the sample from MSDN, as follows: int CALLBACK CSortListCtrl::CompareFunction(LPARAM lParam1, LPARAM lParam2, LPARAM lParamData) { CSortListCtrl* pListCtrl = reinterpret_cast( lParamData ); ASSERT( pListCtrl->IsKindOf( RUNTIME_CLASS( CListCtrl ) ) ); CString strItem1 = pListCtrl->GetItemText( lParam1, pListCtrl->m_iSortColumn ); CString strItem2 = pListCtrl->GetItemText( lParam2, pListCtrl->m_iSortColumn ); return strcmp(strItem2, strItem1); } I always got lParam1 and lParam2 the SAME !! That is, the Compare Function is always comparing the same thing ! (The first item always ! And I found the lParam1 and lParam2 are always 0 !!) The following is how I added items to my list control: /// m_CtrlEntryList is of type CSortListCtrl, which is also of type CListCtrl //// add subitem 0 first m_CtrlEntryList.InsertItem( iItemNo, szString ); LV_ITEM lvitem; ZeroMemory( &lvitem, sizeof( lvitem ) ); /// then add subitem 1 ~ 3 lvitem.mask = LVIF_TEXT; lvitem.iItem = iItemNo; lvitem.pszText = szString; lvitem.iSubItem = iSubItemNo; lvitem.lParam = iItemNo; // <------ I DO specify this lParam m_CtrlEntryList.SetItem( &lvitem ); I used something like above to add items to my list control, and it really worked and displayed fine. I don't know why when I get them compared, the 2 parameters passed to compare function are always 0. Anything wrong ?

            1 Reply Last reply
            0
            • K Koep

              Hi again, here a snipit from MSDN: The comparison function has the following form: int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); 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. The lParamSort parameter is the same value passed to the LVM_SORTITEMS message. U have to fill the params associated with the items/subitems first. For instance, pointer to the DataClass instance. Then u can get/compare everything from inside the class. I had implemented today, and this is the fastest and easiest way to do sorting in a listcontrol. Marco

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              I found one sample for sorting list control on this web site. The URL is: http://www.codeproject.com/listctrl/sortlistctrl.asp And, I have also tried his codes. His codes are fine and I found he did "Add Items" to his list control something like this: /// CSortListCtrl is derived from CListCtrl int CSortListCtrl::AddItem( LPCTSTR pszText, ... ) { //..... skipped VERIFY( CListCtrl::SetItem( iIndex, iColumn, LVIF_TEXT, pszText, 0, 0, 0, 0 ) ); ///... skipped } Why not just use something like: this->SetItem( iIndex, iColumn, LVIF_TEXT, pszText, 0, 0, 0,0 ) ); ??? So, I should use something like CListCtrl::SetItem(.....) to add my items ?

              K 1 Reply Last reply
              0
              • L Lost User

                I found one sample for sorting list control on this web site. The URL is: http://www.codeproject.com/listctrl/sortlistctrl.asp And, I have also tried his codes. His codes are fine and I found he did "Add Items" to his list control something like this: /// CSortListCtrl is derived from CListCtrl int CSortListCtrl::AddItem( LPCTSTR pszText, ... ) { //..... skipped VERIFY( CListCtrl::SetItem( iIndex, iColumn, LVIF_TEXT, pszText, 0, 0, 0, 0 ) ); ///... skipped } Why not just use something like: this->SetItem( iIndex, iColumn, LVIF_TEXT, pszText, 0, 0, 0,0 ) ); ??? So, I should use something like CListCtrl::SetItem(.....) to add my items ?

                K Offline
                K Offline
                Koep
                wrote on last edited by
                #7

                Hello, try to use "SetItemData()" instead of "xx.lParam=xx". Marco

                L 1 Reply Last reply
                0
                • K Koep

                  Hello, try to use "SetItemData()" instead of "xx.lParam=xx". Marco

                  L Offline
                  L Offline
                  Lost User
                  wrote on last edited by
                  #8

                  Thanks ! It really helps. Now the 2 parameters passed in are different. But, I still got trouble on sorting result. The sorting result is very weird. I have traced in my compare function and I thought it should get the right result but actually it doesn't. My Compare function is something like the following: int CALLBACK CSortListCtrl::CompareFunction(LPARAM lParam1, LPARAM lParam2, LPARAM lParamData) { int r = 0; CSortListCtrl* pListCtrl = reinterpret_cast( lParamData ); ASSERT( pListCtrl->IsKindOf( RUNTIME_CLASS( CListCtrl ) ) ); CString strItem1 = pListCtrl->GetItemText( lParam1, pListCtrl->m_iSortColumn ); CString strItem2 = pListCtrl->GetItemText( lParam2, pListCtrl->m_iSortColumn ); if ( pListCtrl->m_bSortAscending ) // ascending sort r = strcmp( strItem1, strItem2 ); else r = strcmp( strItem2, strItem1 ); return r; } I have tested an original sequence of alphabet of a specified column like: M, H, D, V (4 chars) If ascending sort on 1st time, it would get right result like: D, H, M, V but when next time I want to sort descendingly, it is wrong !! (i.e, the sequence is NOT V, M, H, D, but something else instead. ) And another run of ascending sort, it got another weird sequence again !! (I have modified adding items to something like the following: /// insert sub-item 0 m_CtrlEntryList.InsertItem( iItemNo, szString ); /// insert sub-items 1~3 m_CtrlEntryList.SetItem( iItemNo, iSubItemNo, LVIF_TEXT, szString, 0, 0, 0, 0 ); /// as you suggested, this lParam should be unique, right ? m_CtrlEntryList.SetItemData( iItemNo, ( DWORD ) iItemNo );

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups