Also was das gdSelected in State angeht, so hat das was mit sets zu tun.
Du kannst in Delphi verschiedene Typen anlegen, eine Möglichkeit sind einfache Datentypen TDeinTyp = (dt1, dt2, ...), diesen wird dann intern ein Ordinaler Wert zugeordnet (explizit mit TDeinTyp = (dt1 = 1038) => ord(dt1) = 1038).
Genau so kannst du dir z.B. auch ein Char vorstellen. Eine Variable von einem solchen Typ kann natürlich nur genau einen Wert speichern.
Alternativ gibt es noch Klassen (gehe ich jetzt nicht näher drauf ein) und Verbundstypen (Records). Ein Record speichert nun eine Kombination von Werten, z.B.
Delphi-Quellcode:
TPunkt = record
x : Integer;
y : Integer;
end;
Das ist schön, aber du kannst auch hier wieder nur einen Wert zuweisen (in dem Fall allerdings ein x und ein y).
Desweiteren gibt es halt noch Bitfelder. Diese sind intern auch nur eine Zahl, bei der man nur prüft ob ein gewisses Bit gesetzt ist. Dies bietet dir den Vorteil, dass du mehrere Dinge gleichzeitig markieren kannst. Klingt alles ein wenig kompliziert, aber nimm zum Beispiel die Key-Events.
Wenn du eine Taste drückst, willst du vielleicht auf anders reagieren wenn
- Alt gedrückt ist
- Shift gedrückt ist
- Strg gedrückt ist
- Alt + Shift gedrückt ist
- Strg + Shift gedrückt ist
- ..
Du siehst, es gibt eine Menge Möglichkeiten. Dabei ist wichtig, dass keine oder alle Tasten genauso gedrückt sein können wie eine beliebige Kombination. Weißt du nun einfach jeder Taste ein Festes Bit zu und kodierst es, kämst du vielleicht auf (000 <- Nichts gedrückt, 001 <- Shift gedrückt, 010 <- Alt gedrückt, 011 <- Shift und Alt gedrückt, ...)
Wichtig ist, dass Delphi dass alles automatisch macht (und sicherlich nicht in 3 Bits kodiert, sondern sinnvoller und effizienter). Dazu verwendet man das Schlüsselwort set.
Ja und mit in prüfst du dann eigentlich nur ob eine Taste auch gedrückt war (also ob das Bit gesetzt ist).
Im Beispiel mit den Tasten kennt Delphi den TShiftstate, du kannst dann gucken ob
Delphi-Quellcode:
state : TShiftState;
begin
...
// nur Shift gedrückt ist
if state [ssShift] then
begin
...
end
// genau Shift und Alt gedrückt sind
else if state = [ssShift, ssAlt] then
begin
...
end
// Auch Shift gedrückt ist
else if ssShift in State then
begin
...
end;
Was das zeichnen mit dem roten Kasten angeht, so wußte ich halt nicht, wie der sich etwas als markiert merkt. Am einfachsten (da hast du Recht) ist es ein Feld zu benutzen. Nimm einfach ein zwei Dimensionales Array of Boolean und merk dir welche Zellen markiert sind (wenn die Anzahl der Zellen fest ist und nicht zu groß). Dann kannst du leicht in der Methode anhand von Row und Column prüfen ob eine Zelle markiert ist oder nicht.
Sollte die Anzahl der Zellen hingegen Variabel sein bietet sich eher eine Liste an. Diese wachsen dynamisch mit der Anzahl der enthaltenen Elemente (und du musst dich nicht drum kümmern, dass macht Delphi). Allerdings musst du dann auch immer über alle Elemente iterieren und schauen ob du eine Zelle hier findest oder nicht.