Symbolleisten
Bei diesem Tutorial geht es darum, Symbolleisten zu erstellen, die der Windows-Taskleiste im Verhalten gleichen.
Die Symbolleiste soll verschiebbar sein und Maximierte Fenster sollen die Symbolleiste nicht verdecken. Wenn man jedoch das Fenster einfach per "Align"-Eigenschaft an eine Seite zwingt, überdeckt es eventuell Desktopsymbole. Deshalb muss der Arbeitsbereich angepasst werden. Beim beenden der Leiste soll der alte Bereich wiederhergestellt werden.
Um den Aktuellen Arbeitsbereich zu lesen verwenden wir die Funktion SystemParametersInfo:
Delphi Hilfe hat folgendes geschrieben: |
BOOL SystemParametersInfo(
UINT uiAction, // system parameter to query or set
UINT uiParam, // depends on action to be taken
PVOID pvParam, // depends on action to be taken
UINT fWinIni // user profile update flag
);
|
Da wir den Arbeitsbereich lesen/schreiben wollen, ist für uns als Wert für uiAction nur "SPI_SetWorkArea" und "SPI_GetWorkArea" interessant.
Um den Arbeitsbereich in OnCreate zu lesen, deklarieren wir erst eine Variable "WorkArea" vom Typ "TRect" und schreiben anschließend folgendes in OnCreate:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| procedure TForm1.FormCreate(Sender: TObject); begin SystemParametersInfo(SPI_GETWorkArea, 0, @WorkArea, SPIF_SENDCHANGE); DockAt(alBottom); end; |
Der dritte Parameter von SystemParametersInfo gibt in diesem Fall an, wo der Arbeitsbereich gespeichert werden soll.
Zu der Methode DockAt kommen wir gleich.
Zuerst müssen wir noch sicherstellen, dass auch wieder der alte Arbeitsbereich hergestellt wird. Dazu schreiben wir in OnDestroy:
Delphi-Quelltext
1: 2: 3: 4: 5:
| procedure TForm1.FormDestroy(Sender: TObject); begin SystemParametersInfo(SPI_SetWorkArea, 0, @WorkArea, SPIF_SENDCHANGE); end; |
Hier gibt der dritte Parameter an, woraus der Arbeitsbereich gelesen werden soll.
Die Methode, die für das eigentliche Docken zuständig ist, heißt DockAt. Sie ist folgendermaßen implementiert:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47:
| const defaultWidth = 28; defaultHeight = 28;
var calign: TAlign = alnone;
procedure TForm1.DockAt(Align: TAlign); var TempRect: TRect; begin if calign = align then exit; calign := align;
TempRect := WorkArea; FormStyle := fsStayOnTop; BorderStyle := bsNone; SetBounds(WorkArea.Left, WorkArea.Top, defaultWidth, defaultHeight); case Align of alTop: begin width := WorkArea.Right-WorkArea.Left; TempRect.Top := height+WorkArea.Top; end; alBottom: begin Width := WorkArea.right - WorkArea.left; Top := WorkArea.Bottom - height; TempRect.Bottom := WorkArea.Bottom-height; end; alLeft: begin height := WorkArea.Bottom-WorkArea.Top; TempRect.Left := width+Workarea.Left; end; alright: begin Height := WorkArea.bottom - WorkArea.top; Left := WorkArea.Right - width; TempRect.Right := WorkArea.Right-Width; end; end; SystemParametersInfo(SPI_SetWorkArea, 0, @TempRect, SPIF_SENDCHANGE); end; |
Zuerst überprüft DockAt, ob sich die Ausrichtung überhaupt ändert. Wenn nicht, wird sofot aus der Prozedur gesprungen.
Je nach neuer Ausrichtung wird der Arbeitsbereich verkleinert und die Position des Fensters angepasst.
Wenn das Programm jetzt ausgeführt wird, erscheint unten eine Symbolleiste. Maximierte Anwendungen sollten sie nicht überdecken.
Allerdings soll sich die Symbolleiste noch verschieben lassen. Dazu definieren wir eine Variable "MouseDown" vom Typ "Boolean", die anfangs False sein sollte, in MouseDown auf true und in MouseUp wieder auf false gesetzt wird. Da die Symbolleiste auch immer an die richtige Seite des Bildschirms gedockt werden soll, muss die Position des Mauscursors in Prozentwerte relativ zur Höhe und Breite der Blidschirmauflösung umgerechnet werden. Die Prozentwerte für die Position von links, rechts, oben und unten können dann verglichen werden, woraus sich die richtige Seite ergibt.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
| procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var oben, unten, links, rechts: real; mpos: TPoint; begin if not fMouseDown then exit; GetCursorPos(mpos); with mpos do begin unten := y/screen.height; oben := 1-unten; rechts := x/screen.width; links := 1-rechts;
if (oben > unten) and (oben > links) and (oben > rechts) then DockAt(alTop) else if (unten > links) and (unten > rechts) then DockAt(alBottom) else if (rechts > links) then DockAt(alRight) else DockAt(alLeft); end; end; |
Ich hoffe es war nicht zu unverständlich und ich habe nichts vergessen.
Selbstverständlich sind alle Rechtschreibfehler beabsichtigt.