Listenelement sortieren

MAN

Erfahrenes Mitglied
Blöde Frage, aber: wie kann man jetzt eigentlich Absteigend sortieren? habe schon überall mal probiert ein kleines >!< davor zusetzen :) aber bringt dann nur schmarn raus. Wie ich abfrag, in welche Richtung er zuletzt sortiert hat, ist mir klar. Jedoch nicht, WIE ich dann absteigend sortiere!

Bestimmt wieder ein kleines Flag, welches ich in der MSDn nich finde :)


mfg

MAN
 

Kachelator

Peter Jerz
Die Antwort darauf ist so simpel, dass du dir gleich vor die Stirne klatschen wirst. ;) Du verwendest einfach eine andere Vergleichsfunktion oder baust die Vergleichsfunktion so, dass sie den übergebenen letzten Parameter auswerten kann und dann bei Bedarf andersrum sortiert.

Code:
 int CALLBACK SortItemsWithString( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort )
{
  //- irgendwas 0?
  if ( lParam1 == 0 || lParam2 == 0 ) return 0;

  //-die Strings rausholen
  CString* pA = (CString*)lParam1;  
  CString* pB = (CString*)lParam2;
  //- vergleichen und Resultat zurückgeben
  return pA->Compare( LPCTSTR( *pB ) );
}

int CALLBACK SortItemsWithStringAndersrum( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort )
{
  //- irgendwas 0?
  if ( lParam1 == 0 || lParam2 == 0 ) return 0;

  //-die Strings rausholen
  CString* pA = (CString*)lParam1;  
  CString* pB = (CString*)lParam2;
  //- vergleichen und Resultat zurückgeben
  return -pA->Compare( LPCTSTR( *pB ) ); (Ergebnis mal -1 für Umkehrung)
}
 

MAN

Erfahrenes Mitglied
*batsch* :)

lol..... wie gesagt, mit einem kleinen >!< war ich gar nicht so schlecht *gg*

Vielen Dank nochmal für das kleine "-" ;)


mfG

MAN
 
B

ByeBye 31659

Hallo,

ich bin es nach fast 2 wöchiger Abstinenz mal wieder.

Also ich habe nun verstanden wie das funktioniert, das es andersherum sortiert.
Allerdings weiß ich leider noch nicht, wie cih mir für jede Spalte merke in welche Richtung zuletzt sortiert wurde.

Es wurde etwas von Itemdata für Spalten erwähnt, was bzw. wie kann ich das machen?

Oder wie könnte ich das sonst abfragen?


Vielen Dank,

habs schon selber rausgefunden, habs nun mit einem Array gemacht und zwei Funktionen eine für Sortieren und eien fürs Reverse Sortieren....
 
Zuletzt bearbeitet von einem Moderator:

Ravebaby

Erfahrenes Mitglied
Kachelator hat gesagt.:
Das darf keine Memberfunktion sein. Richtig ist
Code:
int CALLBACK sortitems(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
heißt das dann, dass ich die im header - file gar nich definieren darf?!

Ich möchte auch mein CListCtrl nach Größe, Name und Erstellungsdatum sortieren lassen können.

Bisher habe ich dafür erstmal folgenden Code geschrieben, um nur einmal diese Callbackfunktion in den Code zu bekommen:

Code:
void CColumnLevelView::OnRButtonDown(UINT nFlags, CPoint point)
{
	CListCtrl m_ctlListResult;
	m_ctlListResult.SortItems( sortitems, 0 );

	CFileExplorerLevelView::OnRButtonDown(nFlags, point);
}

int CALLBACK sortitems( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort )
{
  TRACE( "%d, %d\n", lParam1, lParam2 );
  
  if ( lParam1 < lParam2 ) return +1;
  if ( lParam1 > lParam2 ) return -1;
  return 0;
}

und in meinem header - file habe ich die callback - Funktion folgendermaßen definiert:
Code:
int CALLBACK sortitems( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort );

Sollte ich das besser lassen?!

Was ich vielleicht auch noch dazu sagen sollte:
Ich nutze die CListCtrl wohl nicht so, wie man sie normalerweise nutzt...
Ich habe einen kleinen FileExplorer programmiert.
Wann immer ich mir den Inhalt eines Ordners anzeigen lassen möchte, wird eine neue Spalte mit dem Inhalt erzeugt. Und auch jedesmal ein neues CListCtrl, mit lediglich dem Inhalt des einen Ordners. Somit habe ich in meinem ListCtrl nicht verschiedene Spalten, oder solche Scherze. Ich weiß, dass ich besser eine andere Datenstruktur benutzt hätte, um den ganzen overhead zu sparen, aber das is nun n bißchen zu spät.
Auf jeden Fall soll nun jede Spalte / also jeder Ordnerinhalt einzeln sortierbar sein. Und zwar nicht, indem man auf das oberste Element der ListCtrl klickt, sondern durch einen Klick auf einen Button, oder Rechtsklick, oder sonstwas.
Wie kann ich das in diesem Fall lösen?!

Was auch noch zu erwähnen ist, ist das ich in das ListCtrl einfach nur Zeiger auf Instanzen meiner Klasse FileItem speichere, ich also nach Attributren des Zeigers sortieren möchte.
Also im ListCtrl werden die Zeiger auf die FileItem Objekte gespeichert. Ein FileItem hat die Attribute: Name, Größe, Erstellungsdatum, nach denen ja nacher die Elemente der ListCtrl sortiert werden sollen.
Und irgendwie steig ich bei der ListCtrl::SortItems nicht wirklich durch.
Gibt es für meinen Einsatz dieser Datenstruktur eine möglichkeit die Einträge nach meinen Wünschen zu sortieren? :(

Danke für jede Hilfe
 
Zuletzt bearbeitet:

Kachelator

Peter Jerz
Code:
int CALLBACK sortitems( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort );
Das ist keine Definition, sondern eine Deklaration. Das heisst, die "Signatur" der Funktion wird bekanntgegeben, aber nicht die Implementierung, also der Funktionsrumpf. Das ist vollkommen okay in einer Headerdatei.

Was du da mit mehreren Listcontrols machst, habe ich allerdings nicht vollständig verstanden.

Und so was geht zum Beispiel natürlich auch:
Code:
struct FileItem
{
  int Size;
  // .. usw.
};

int CALLBACK sortFileItemsNachSize( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort )
{
  TRACE( "%d, %d\n", lParam1, lParam2 );
  FileItem* pItem1 = (FileItem) lParam1;
  FileItem* pItem2 = (FileItem) lParam2;

  if ( pItem1->Size < pItem2->Size ) return +1;
  if ( pItem1->Size > pItem2->Size ) return -1;

  return 0;
}

Ich hoffe, das hilft dir weiter.
 

Endurion

Erfahrenes Mitglied
Kleine Anmerkung zur Sicherheit:

Die Sortierroutine kannst du im Header deklarieren, allerdings NICHT innerhalb der Klassendeklaration. Sonst denkt der Compiler, das wäre eine Memberfunktion.
 

Ravebaby

Erfahrenes Mitglied
Das mit dem Sortieren hört sich ja recht krampfig an... Ich habe schon bei der Implementierung der Grundfunktionalität einen Fehler drin...
Verwende folgende Funktion:
Code:
int CALLBACK sortitems(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
  TRACE("%d, %d\n", lParam1, lParam2);
  
  if (lParam1 < lParam2) return +1;
  if (lParam1 > lParam2) return -1;
  return 0;
}
und diesen Aufruf:
Code:
m_listCtrl.SortItems(sortitems, 0);
und bekomme diesen Fehler:
"Cannot convert parameter 1 from 'int(LPARAM; LPARAM; LPARAM)' to 'PFNLCOMPARE'

In einem der ersten Beiträge steht, dass es daran liegt, dass man die CALLBACK Funktion als Member-Funktion verwendet, aber das tu ich ja gar nicht... :(