Moin!
Es gibt sicher einige Ansätze, wie man eine Bestenliste umsetzen kann, ich persönlich finde dafür aber die VCL-Komponente
TListView ausgesprochen gut geeignet. Unter anderem deshalb, weil sie benutzerdefinierte Sortierungen relativ leicht ermöglicht.
Wir erzeugen ein neues Projekt und legen ein ListView (aus dem Reiter "Win32") auf das Formular. Anschließend müssen wir die Komponente noch unseren Bedürfnissen entsprechend anpassen:
Delphi-Quelltext
Delphi-Quelltext
Delphi-Quelltext
Delphi-Quelltext
Delphi-Quelltext
Delphi-Quelltext
Delphi-Quelltext
- Doppelklick auf der Eigenschaft Columns im ObjectInspector, um den Eigenschaftseditor zu öffnen
- Auf das Blattsymbol mit dem Sternchen klicken, um eine neue Spalte im ListView anzulegen
- Dann im ObjectInspector die folgenden Eigenschaften setzen: Caption := 'Name', MinWidth := 16, Width := 144
- Noch eine Spalte anlegen, Werte: Alignment := taRightJustify, Caption := 'Punkte', MinWidth := 16, Width := 56
- Und noch eine, Werte: Alignment := taRightJustify, Caption := 'Datum', MinWidth := 16, Width := 120
Damit ist die Komponente schon fast fertig konfiguriert. Da wir aber noch eine Vergleichsprozedur zur Verfügung stellen müssen (die größte Punktzahl soll ja oben stehen), wechseln wir im ObjectInspector auf die Seite "Ereignisse" und machen einen Doppelklick beim Ereignis
OnCompare. Es wird ein Ereignishandler angelegt, den wir mit folgendem Code füllen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| uses ..., Math; procedure TForm1.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); begin Compare := CompareValue(Integer(Item2.Data),Integer(Item1.Data)); end; |
Man kann jetzt darüber streiten, ob die Unit
Math für die Vergleichsoperation unbedingt nötig ist. Sicher ist es für diesen kleinen Anwendungsfall etwas überzogen, aber es gibt eine Menge überladener Varianten von
CompareValue für eine Vielzahl von Datentypen, die auch gleich das erwartete Vergleichsergebnis für den Ereignishandler liefern, so dass ein Blick in diese Unit sicher nicht schaden kann.
Wer die Unit Math nicht hat bzw. verwenden möchte oder mit einer Delphi-Version kleiner 6 arbeitet (CompareValue gibt es erst seit D6), kann den Vergleich auch alternativ so durchführen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TForm1.lvHighscoreCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); begin if (Integer(Item2.Data) < Integer(Item1.Data)) then Compare := -1 else if (Item2.Data = Item1.Data) then Compare := 0 else Compare := 1; end; |
Der Witz dieses Ereignishandlers ist nun, dass damit die Komponente in der Lage ist (und zwar selbstständig!), die Einträge sortiert zu halten.
Wie kommen wir nun zu den Einträgen? Dazu legen wir noch einen Button auf das Formular und erstellen einen
OnClick-Handler, den wir mit folgendem Code füllen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TForm1.Button1Click(Sender: TObject); begin with lvHighscore.Items.Add do begin Caption := 'Narses'; Data := Pointer(Random(100)); SubItems.Add(IntToStr(Integer(Data))); SubItems.Add(DateTimeToStr(Now)); end; end; |
Was hat es mit dem
Pointer() für den Punktestand auf sich?
Jeder Listeneintrag (vom Typ
TListItem) bietet in der Eigenschaft
.Data die Möglichkeit, eine Referenz auf ein beliebiges, anderes Objekt zu speichern. Deshalb ist der Datentyp allgemein
Pointer. Wir wollen aber nur einen
Integer speichern, was zwar vom Speicherplatz her das gleiche ist, aber für den Compiler nicht. Deshalb müssen wir diesem mit der Typumwandlung ("typecast") klar machen, dass er ruhig den
Integer als
Pointer betrachten darf, wenn er dann glücklicher ist...
Wir starten das Projekt und testen mit dem Button die Funktion. Es sollten jetzt Einträge mit zufälliger Punktzahl angelegt werden - und zwar automatisch sortiert!
In Anhang befindet sich ein Demo-Projekt, in dem auch das Laden und Speichern dieser Bestenliste behandelt ist, um den Beitrag hier nicht unnötig aufzublähen.
Viel Erfolg!
cu
Narses
There are 10 types of people - those who understand binary and those who don´t.