SortItems und CompareFunction



  • 1. Die Daten stehen doch irgendwo.

    Ja im ListCtrl. Aber sonst speichere ich die Daten nirgends. Ich muss die Daten also noch wo speichern ausser im ListCtrl oder?


  • Mod

    Nein! Musst Du nicht. Nur wenn es so wäre könnte man diese benutzen und müsste nicht doppelt Speicher verwenden.

    Siehe also SortItemsEx...



  • Also irgendwie verstehe ich das nicht wenn ich mir das Beispiel von SortItemsEx anschaue aus der MSDN dann steht dort

    CListCtrl* pListCtrl = (CListCtrl*) lParamSort;
    CString    strItem1 = pListCtrl->GetItemText(static_cast<int>(lParam1), 1);
    CString    strItem2 = pListCtrl->GetItemText(static_cast<int>(lParam2), 1);
    

    lParamSort enthält also das ListCtrl
    lParam1 und lParam2 enthalten nun Werte aus der ersten Spalte. Und wo steht nun welche Spalte aufgerufen wurde?



  • Nochmal die Frage: Wo steht nun welche Spalte aufgerufen wurde?


  • Mod

    Atomi schrieb:

    Nochmal die Frage: Wo steht nun welche Spalte aufgerufen wurde?

    Das steht in diesem Beispiel nicht. Du könntest Dir die Übergabe der Parameteranders gestalten und eine Struktur übergeben, in der steht welches List-Control es ist, und welche Spalte.

    Ich habe mir dazu eine eigene CListCtrlEx gebaut, die diese ganze Sortiererrei von selbst handhabt.

    BTW: Hättest Du Google bemüht zu den Themen "SortItemsEx CListCtrl" wärest Duim dritten Link auf ein passendes Beispiel gestoßen:
    http://www.codeproject.com/KB/list/clistctrl_sort.aspx

    Und in der Gruppe
    http://www.codeproject.com/KB/list/index.aspx?#List Controls
    findest Du noch mehr...



  • Hallo.

    Den ersten Beitrag habe ich auch gefunden. Wenn ich aber dort das Beispiel anschaue wird dort das Makro ListView_SortItemsEx verwendet. Und nicht SortItemsEx.

    Ehrlich gesagt bin ich jetzt erst recht verwirrt.



  • Gibt es kein Beispiel wo das genau erklärt wird

    Angefangen von den Daten hinzufügen über den Aufruf der SortFunktion und ermitteln der Daten in der Comparefunktion

    In allen Beispielen ist es immer so, dass alle Daten einer Spalte in z.B. einen String durch Kommas getrennt oder in ein array abgelegt werden und dies dann im lparam übergeben wird. Und dies am Anfang wenn der Dialog initialisiert wird.

    Dies geht in meinem Fall nicht. Die Spalten und Zeilen werden zur Laufzeit dynamisch gefüllt. Das heißt ich fülle zuerst die komplette erste Spalte. Zu der Zeit habe ich noch keine Informationen zur 2ten bis 3ten Spalte. Diese werden später hinzugefügt hierbei wird der entsprechende Eintrag gesucht und im einen Wert zugewiesen. Die Werte in der 4ten Spalte ändern sich ständig.

    Hierzu habe ich noch nirgends was gefunden.


  • Mod

    Warum muss auch alles haarklein erklärt werden?

    ListView_SortItemsEx ist nichts andres als der Wrapper-Makro für SendMessage LVM_SORTITEMSEX, also nichts anderes als der Aufruf des MFC Wrapper für SortItemsEx!

    In dem besagten Beispiel wird eine komplette Struktur übergeben, die das sortieren einer beliebigen Spalte erlaubt...



  • Ich habe aber keine komplette Struktur weil jeder Wert für sich dynamisch ist. Und dafür finde ich halt kein Beispiel.

    Warum muss auch alles haarklein erklärt werden?

    Weil ich nicht auf die Lösung komme.



  • Ein kleines Beispiel zum probieren, den Code mußt allerdings an Dein Programm anpassen, es dient ja auch legendlich als Hilfestellung.

    //Wir sortieren aufsteigend
    int CALLBACK ST_SORTDOWN(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
    {
    	if (lParam1 == 0 || lParam2 == 0)
    	{
    		return 0;
    	}
    
    	CString* pA = (CString*)lParam1;  
    	CString* pB = (CString*)lParam2;
    
    	return pA->Compare(LPCTSTR(*pB));
    }
    
    //Wir sortieren absteigend
    int CALLBACK ST_SORTUP(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
    {
    	if (lParam1 == 0 || lParam2 == 0)
    	{
    		return 0;
    	}
    
    	CString* pA = (CString*)lParam1;  
    	CString* pB = (CString*)lParam2;
    
    	return pB->Compare(LPCTSTR(*pA));
    }
    
    //Der User hat mit der linken Maustaste in den Header des CListCtrl geklick.
    void CSchluesseltabelle::OnHdnItemclickStSchluesseltabelle(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	LPNMHEADER phdn = reinterpret_cast<LPNMHEADER>(pNMHDR);
    
    	CString	strTemp;
    
    	if ((phdn->iButton == 0) && (nStatusDatensatz != 0))
        {
    
            if (phdn->iItem == nSortedColumn)
    		{
    			bSortAscending = !bSortAscending;
    		}
            else
    		{
    			bSortAscending = FALSE;
    		}
    
            // die Spalte holen, nach der sortiert werden soll.
            nSortedColumn = phdn->iItem;
    
    		pList = (CListCtrlEx*) GetDlgItem(IDC_ST_SCHLUESSELTABELLE);
    
    		SetHeaderBitmap(pList, nSortedColumn, bSortAscending);
    
    		// Itemdatas mit Text versehen.
    		for (int i = 0; i < m_Schluesseltabelle.GetItemCount(); ++i)
    		{
    			strTemp = m_Schluesseltabelle.GetItemText(i, nSortedColumn);
    
    			if (nSortedColumn == 0)
    			{
    				while (strTemp.GetLength() < 8)
    				{
    					strTemp = _T("0") + strTemp;
    				}
    			}
    
    			m_Schluesseltabelle.SetItemData(i, (DWORD)(new CString(strTemp)));
    		}
    
    		if (bSortAscending)
    		{
    			m_Schluesseltabelle.SortItems(ST_SORTUP, 0);
    		}
    		else
    		{
    			m_Schluesseltabelle.SortItems(ST_SORTDOWN, 0);
    		}
    
    		// Itemdatas wieder freigeben.
    		for (int i = 0; i < m_Schluesseltabelle.GetItemCount(); ++i)
    		{
    			CString* pA = (CString*) m_Schluesseltabelle.GetItemData(i); 
    			delete pA;
    			m_Schluesseltabelle.SetItemData(i, 0);
    		}
    	}
    
    	*pResult = 0;
    }
    

    Turmfalke64



  • Hallo Turmfalke.

    Erstmal vielen Dank für deine Hilfe. Wo aber immer noch mein Problem liegt ist darin wie die Daten in das ListCtrl eingefügt werden müssen. Da ich wie gesagt nicht alle Daten einer Zeile auf einmal einfügen kann.



  • Ist denn kein einfaches Beispiel drin, dass ich weiß wie ich die Daten zu meinem ListCtrl hinzufüge so dass ich diese dann auch sortieren kann. Bitte.


  • Mod

    Atomi schrieb:

    Ist denn kein einfaches Beispiel drin, dass ich weiß wie ich die Daten zu meinem ListCtrl hinzufüge so dass ich diese dann auch sortieren kann. Bitte.

    Liest Du eigentlich was man Dir schreibt.
    Ich habe Dir ziemlich am Anfang genau dieses komplette Sample genannt:
    http://www.codeproject.com/KB/list/clistctrl_sort.aspx

    👎 Für mich war dies das letzte Posting zu diesem Thema ... und Tschüss.



  • Liest Du eigentlich was man Dir schreibt.
    Ich habe Dir ziemlich am Anfang genau dieses komplette Sample genannt:

    Super. Und ich schrieb, dass das Beipiel bei mir nicht funktioniert, da die Werte alle am Anfang beim initialisieren gefüllt werden. Und alle am Stück hinzugefügt werden. Statt das hier einem einfach ein kurzes Codestück gegeben wird das einem zeigt wie man Daten hinzufügt wird auf ein riesen großes Beispiel verwiesen wo 100 Ausnahmen drin sind und man dann erst nicht recht weiß was man nun genau machen muss.

    Danke.



  • Hallo Turmfalke64

    Du hast mir doch ein einfaches Beispiel genannt zur Sortierung. Kannst du mir nicht auch sagen wie ich Daten zu meinem ListCtrl hinzufüge, so dass ich nach einzelnen Spalten sortieren kann.



  • Wie soll ich das nun verstehen, willst mir jetzt damit sagen, das Du ein
    leeres CListCtrl hast,in dem noch keine Daten vorhanden sind.

    Sollte das der Fall sein, schaue mal in die MSDN Schlagwort CListCtrl und schaue
    Dir unter members mal die Funktionen InsertItem und SetItemText an.

    Sollte es jedoch mit Daten gefüllt sein, funktioniert der oben gepostet Code,
    nach Anpassung.

    Wenn man programmieren lernen will, so macht es keinen Sinn, einem alles
    vorzukauen, da dies zu keinem Erfolg führt und man es auch nicht versteht,
    warum das ganze nun funktioniert oder auch nicht.

    Turmfalke64



  • Doch die Liste habe ich gefüllt. Nur anscheinend nicht so wie mans zum sortieren benötigt. Habe InsertItem mit den Parametern int nItem und LPCTSTR lpszItem und SetItemText verwendet.

    In den Beispielen habe ich gelesen, dass man den Parameter LPARAM lParam auch füllen muss. In den Beispielen wurde dieser mit einem String aller Werte einer Zeile, durch Komma getrennt, gefüllt. Ich habe aber nicht alle Werte auf einmal zu Verfügung.

    Und das steht nicht in der MSDN wie das gehen soll.



  • Kann mir denn echt keiner sagen wie man die Daten hinzufügt?



  • Also doch überfragt!


Log in to reply