die Positionen der TCoolbar-Bands speichern/laden?
Vor einigen Monaten hatte wulfskin gefragt, wie man die Position der Bänder (Bands) in einer TCoolBar speichern kann. (
ToolBar speichern?.) Da er damals den Tipp bekam, bessere Komponenten zu benutzen, habe ich meinen Vorschlag, den ich vorbereitet hatte, wieder gelöscht.
Erinnert habe ich mich daran, weil ich momentan an der NonVCL-Version (Rebar genannt; s. PSDK) sitze und den Beitrag für Luckies Tutorials eigentlich fertig habe. Aber Luckies Reaktion auf meine Demo war:
Zitat: |
Jetzt fehlt eigentlich nur noch, wie man das abspeichert, damit beim nächsten Start alles wieder so ist, wie man es sich zurecht gelegt hat. |
Darum habe ich den VCL-Code rekonstruiert und würde ihn hier gern als Idee vorstellen und zeigen, wie man es mit der normalen TCoolbar machen
könnte. Da ich nicht weiß, wie das in neueren Delphi-Versionen aussieht, gilt dieser Vorschlag erst mal nur bis Delphi 5, wo die TCoolbar keine eingebaute Speichermöglichkeit hat.
Als Speicherort habe ich mich für die Registry entschieden. Das kann zwar jeder von euch anders machen, aber da bei der Toolbar die Einstellungen auch in der Registry gesichert werden (s. Toolbarbeitrag in Luckies Tutorials), bietet sich das hier natürlich auch an. Daher die Grundlagen, einzufügen im Interface-Teil der Form-Unit:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| uses Registry;
const szRegKey = 'Software\CoolbarDemo\CoolbarPos'; szValName = 'BandLayout'; type rbBandArray = packed record Index, ID, Width : integer; end; |
Die Idee ist folgende: jedes Band besitzt eine einzigartige ID, die bei der VCL-Version auch nur lesbar ist. Diese ID entspricht typischerweise dem Index des Bandes (quasi der Reihenfolge, in der sie erzeugt werden). Aber wenn man die Bänder verschiebt, dann ändert sich nur der Index - die ID dagegen bleibt unverändert!
Daher interessieren uns eben der Index, die ID und natürlich die Breite des Bandes. Auch von Interesse dürfte die Frage sein, ob so ein Band in einer neuen Zeile steckt oder an einem anderen Band dran hängt. Aber dazu gleich.
Zum Speichern benötigen eine Schleifenvariable (i), eine Registry-Variable (reg) und ein dynamisches Array des Typs "rbBandArray":
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| var i : integer; reg : TRegistry; fba : array of rbBandArray; begin SetLength(fba,0); |
Dann legen wir zunächst die Größe dieses Arrays fest, wobei wir die Anzahl der Bänder als Basis nehmen:
Delphi-Quelltext
1: 2: 3:
| with Coolbar1 do begin SetLength(fba,Bands.Count); |
In einer Schleife merken wir uns dann die o.g. Werte:
Delphi-Quelltext
1: 2: 3: 4: 5:
| for i := 0 to Bands.Count - 1 do begin fba[i].Index := Bands[i].Index; fba[i].ID := Bands[i].ID; fba[i].Width := Bands[i].Width; |
Jetzt die Sache, die jeder von euch nach eigenem Gutdünken handhaben kann: Wenn ein Band in einer neuen Zeile ist, dann ist seine Eigenschaft "Break" üblicherweise
true. Ich habe mich dafür entschieden, in so einem Fall, den Index als negativen Wert anzugeben:
Delphi-Quelltext
1: 2: 3: 4:
| if(Bands[i].Break) then fba[i].Index := 0 - fba[i].Index; end; end; |
Das heißt, aus dem Bandindex 2 wird bspw. -2. Wie gesagt, das kann jeder anders machen. Ich hätte auch eine vierte Membervariable in mein rbBandArray-Record einbauen können. Aber ich wollte die Anzahl der Bytes in der Registry möglichst klein halten, und dieser Wert hier ist der einzige, den man auch mit anderen Werten verbinden kann. Index, ID und Breite dagegen
sollten in separaten Variablen gespeichert werden.
Die so gesicherten Daten werden nun in der Registry abgelegt. Ich habe den Schlüssel HKEY_CURRENT_USER benutzt, was natürlich einen Sinn hat: a) es gibt keine Rechteprobleme unter NT, b) jeder User hat sein eigenes Layout:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| if(length(fba) > 0) then begin reg := TRegistry.Create; with reg do try RootKey := HKEY_CURRENT_USER;
if(OpenKey(szRegKey,true)) then try |
Hervorzuheben ist die folgende Zeile:
Delphi-Quelltext
1:
| WriteBinaryData(szValName,fba[0],length(fba) * sizeof(rbBandArray)); |
Da das dynamische Array bei Null beginnt, müssen wir das auch angeben. Sonst speichern wir alles mögliche, nicht aber die uns interessierenden Werte.
Und der Rest noch:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| finally CloseKey; end; finally Free; end; end;
SetLength(fba,0); end; |
Voilà. Idealerweise ist dieser Code im "OnClose"-Ereignis einzufügen, bzw. über dieses aufzurufen, damit beim Beenden des Programms die aktuellen Band-Positionen gesichert werden.
Moderiert von jasocul: Sourcen an Style-Guide angepasst
Moderiert von jasocul: Beitrag geprüft am 16.05.2006