ListControl + sort
-
ich versuche verzweifelt mein
listcontrol dazu zu bekommen, dass es nach einer
spalte sortiert. in der listcontrol mehrere werte.
die vergleichsfunktion wird auch mehrmals aufgerufen,
seltsamerweise sind die parameter lParam1 und lParam2 immer 0
(bei jedem aufruf, dh. es wird nicht sortiert):void KlasseX::OnLvnColumnclickmeinListControl(NMHDR *pNMHDR, LRESULT *pResult) { meinListControl.SortItems( list_compare, (LPARAM)&meinListControl ); } // ... // die callback funktion wird mehrere male aufgerufen immer mit // lParam1 und lParam2 == 0 int CALLBACK list_compare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { // lParamSort contains a pointer to the list view control. CListCtrl* pListCtrl = (CListCtrl*) lParamSort; // LParam1 und lParam2 sind IMMER 0 // strItem hat den korrekten inhalt von zeile 0 und SPALTE_1 CString strItem1 = pListCtrl->GetItemText( lParam1, SPALTE_1 ); CString strItem2 = pListCtrl->GetItemText( lParam2, SPALTE_1 ); return strcmp(strItem2, strItem1); }
-
In lParam1 und lParam2 stehen nicht die Indices der zu vergleichenden Einträge.
Siehe FAQ:
http://www.c-plusplus.net/forum/viewtopic.php?t=39109
-
danke, jetzt hab ich es hinbekommen

ich habe aber eine einfachere loesung genommen.
fuer alle, die sich nicht stundenlang durch die mengen der
quelltexte wuehlen wollen hier meine loesung:- zuerst muesst ihr beim hinzufuegen eines items noch zusaetzlich
den data-wert des items setzen
(dieser wird der sortier-funktion als LPARAM p1 und p2 uebergeben)long index = m_ctrlBannedPlayers.GetItemCount(); m_ctrlBannedPlayers.InsertItem( index , "" ); // item hinzufuegen // als daten einfach nochmal den index uebergeben m_ctrlBannedPlayers.SetItemData( index , index ); // .... // das setzen der funktion zum sortieren und sortieren // im ereignis: LVN_COLUMNCLICK if ( listControl.SortItems( list_compare, (LPARAM)&listControl) == 0 ) MessageBox( "Sortieren nicht moeglich", "Liste" );die sortierfunktion:
int CALLBACK list_compare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { // lParamSort contains a pointer to the list view control. CListCtrl* pListCtrl = reinterpret_cast<CListCtrl*>( lParamSort ); LVFINDINFO info; // den index der items bestimmen info.flags = LVFI_PARAM; info.lParam = lParam1; int i1 = pListCtrl->FindItem( &info ); info.lParam = lParam2; int i2 = pListCtrl->FindItem( &info ); // den inhalt der items holen CString strItem1 = pListCtrl->GetItemText( i1, LIST_COLUMNS_BANNED_PLAYERS_NAME ); CString strItem2 = pListCtrl->GetItemText( i2, LIST_COLUMNS_BANNED_PLAYERS_NAME ); return strItem1.CompareNoCase( strItem2 ); }
-
Es reicht in den meisten Fällen nicht aus, den ItemData-Wert nur beim Hinzufügen zu setzen. Du musst bei dieser Lösung vor jedem Sort-Aufruf die Indices in die ItemData-Werte neu reinschreiben, weil sich beim Sortieren, Einfügen oder Löschen die Indices der Items ändern, die ItemData-Werte aber nicht.
-
MFK schrieb:
Es reicht in den meisten Fällen nicht aus, den ItemData-Wert nur beim Hinzufügen zu setzen. Du musst bei dieser Lösung vor jedem Sort-Aufruf die Indices in die ItemData-Werte neu reinschreiben, weil sich beim Sortieren, Einfügen oder Löschen die Indices der Items ändern, die ItemData-Werte aber nicht.
nein. das macht die FindItem-methode. die sucht zu einem ItemData-wert
den passenden index.
-
entelechie schrieb:
nein. das macht die FindItem-methode. die sucht zu einem ItemData-wert den passenden index.
Jo, hast Recht, hatte ich übersehen.
-
und habe malk das beispiel von oben genommen beim kompilieren bekomme ich diese Meldung,... ich weiss aber nicht zu tun mit ihr

schaut mal:
error C2664: 'SortItems' : cannot convert parameter 1 from 'int (long,long,long)' to 'int (__stdcall *)(long,long,long)'
None of the functions with this name in scope match the target type
-
Hallo,
hast du das CALLBACK vergessen? Und Deklaration nicht vergessen, wenn der Aufruf vor der Definition stattfindet:
Deklaration
[cpp]
int CALLBACK
list_compare(LPARAM, LPARAM, LPARAM);
[/cpp]Definition
int CALLBACK list_compare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { // lParamSort contains a pointer to the list view control. CListCtrl* pListCtrl = reinterpret_cast<CListCtrl*>( lParamSort ); LVFINDINFO info; // den index der items bestimmen info.flags = LVFI_PARAM; info.lParam = lParam1; int i1 = pListCtrl->FindItem( &info ); info.lParam = lParam2; int i2 = pListCtrl->FindItem( &info ); // den inhalt der items holen CString strItem1 = pListCtrl->GetItemText( i1, LIST_COLUMNS_BANNED_PLAYERS_NAME ); CString strItem2 = pListCtrl->GetItemText( i2, LIST_COLUMNS_BANNED_PLAYERS_NAME ); return strItem1.CompareNoCase( strItem2 ); }MfG