Was soll das denn Steuerelemente verschieben – zur Laufzeit Soll der Benutzer nun aktiv in die Gestaltung der Benutzeroberfläche eingreifen Mitnichten: Es gibt jedoch eine Reihe ernsthafter Anwendungsfälle, bei denen das Verschieben von Steuerelementen Sinn macht. Einen haben wir im Beitrag €Splitter für Formulare€ bereits vorgestellt, aber es gibt noch mehr Gelegenheiten zum Einsatz dieser Technik, die wir hier grundlegend darstellen.
Während der selbst programmierte Splitter aus dem Artikel Splitter für Formulare (Shortlink 397) rein der Optimierung der Benutzeroberfläche dient, gibt es auch Möglichkeiten, verschiebbare Steuerelemente zur Darstellung von Daten einzusetzen.
Wie wäre es etwa mit einem Terminkalender, dessen Termine Sie nach Lust und Laune mit der Maus bewegen können – oder einer Raumplanung, die das Platzieren von Tischen und Stühlen erlaubt Davon sind wir jedoch noch ein Stück entfernt, denn zunächst ist ein Blick auf die grundlegende Technik nötig.
Für den Start verwenden wir einfach ein Rechteck-Steuerelement, das Sie durch Anpassen einiger Eigenschaften ein wenig verschönern (siehe Bild 1). Der Schlüssel zum Bewegen eines Steuerelements ist ein VBA-Ereignis, das immer dann ausgelöst wird, wenn sich der Mauszeiger über dem Steuerelement befindet, dem das Ereignis zugeordnet ist. Es heißt Bei Mausbewegung und löst die folgende Prozedur aus, die bereits mit einer Anweisung zum Ausgeben der durch die Parameter gelieferten Werte gefüllt ist:
Bild 1: Dieses Rechteck-Steuerelement soll gleich in der Formularansicht durch die Gegend geschoben werden.
Private Sub rctBeispiel_MouseMove(Button As _ Integer, Shift As Integer, X As Single, _ Y As Single) Debug.Print Button, Shift, X, Y End Sub
Diese Routine ist auch der erste Schritt auf dem Weg zum Verschieben eines Steuerelements: Wenn Sie nun das Access-Fenster und das VBA-Fenster so nebeneinander positionieren, dass Sie das Direktfenster sehen, können Sie einfach einmal mit der Maus mit und ohne gedrückte Maustasten über das Steuerelement fahren. Die Parameter lesen sich dabei wie folgt:
- Button liefert einen Zahlenwert, der die aktuell betätigte Maustaste repräsentiert. 1 entspricht der linken, 2 der rechten und der Wert 3 zeigt an, dass beide Maustasten zugleich gedrückt werden. Diese Zahlenwerte entsprechen den Konstanten acLeftButton (1), acRightButton (2) und acMiddleButton (4).
- Shift zeigt an, ob der Benutzer während der Mausbewegung eine oder mehrere der Tasten Shift (1), Strg (2) oder Alt (4) gedrückt hält. Es sind auch Kombinationen möglich, die sich in der Summe der Zahlenwerte widerspiegeln: 7 entspricht beispielsweise der Tastenkombination Shift + Strg + Alt (auch hier gibt es passende Konstanten: acShiftMask (1), acCtrlMask (2) und acAltMask (4)).
- X und Y entsprechen der horizontalen und der vertikalen Entfernung von der linken oberen Ecke des Steuerelements.
X und Y werden in Twips geliefert.
Steuerelement verschieben
Das Steuerelement soll nur verschoben werden, wenn der Benutzer die typische Drag-and-Drop-Mimik ausführt, also die Maustaste anklickt, während sich der Mauszeiger über dem Steuerelement befindet, und das Steuerelement verschiebt, wenn der Benutzer die Maus bei gedrückter Maustaste bewegt. Das lässt sich theoretisch einfach nachbilden: Sie brauchen sich nur einmal zu Beginn des Drag-and-Drop-Vorgangs die Position des Mauszeigers zu merken und passen dann bei jedem Aufruf von Bei Mausbewegung die Position des Steuerelements über die durch die Maus zurückgelegte Strecke an.
Für die X-Komponenten bedeutet dies: X-Position des Mauszeigers merken, X-Position des Formulars ermitteln, alte X-Position des Mauszeigers von der neuen X-Position abziehen und X-Position des Formulars um diese Differenz ändern. Sie brauchen also zunächst zwei modulweit deklarierte Variablen zum Speichern der Startposition des Mauszeigers:
Dim lngXStart As Long Dim lngYStart As Long
Diese ermitteln Sie einmalig beim Herunterdrücken der linken Maustaste:
Private Sub rctBeispiel_MouseDown(Button As _ Integer, Shift As Integer, X As Single, _ Y As Single) If Button = 1 Then lngXStart = X lngYStart = Y End If End Sub
Die folgende Routine wird nicht etwa in festen zeitlichen Intervallen, sondern beim Verschieben des Mauszeigers um eine bestimmte Entfernung in eine der beiden Richtungen ausgelöst. Sie prüft, ob die linke Maustaste gedrückt ist, und stellt die Top– und die Left-Eigenschaften des Steuerelements ein, die für seine Position verantwortlich sind.
Private Sub rctBeispiel_MouseMove(Button As _ Integer, Shift As Integer, X As Single, _ Y As Single) If Button = 1 Then With rctBeispiel .Top = .Top + Y - lngYStart .Left = .Left + X - lngXStart End With End If End Sub
Beim Ausprobieren dieser Technik werden Sie schnell an deren Grenzen stoßen – genau dann nämlich, wenn das Steuerelement an die Grenzen des Formulars stößt. Wenn die Routine versucht, das Steuerelement aus dem Formular herauszubewegen, löst dies eine Fehlermeldung aus. Dies umgehen Sie durch aufwändige Prüfungen oder durch Hinzufügen der folgenden Zeile in den Kopf der Routine:
On Error Resume Next
Größe des Steuerelements verändern
Wenn Sie ein Steuerelement schon zur Laufzeit verschieben, können Sie auch seine Größe anpassen.
Das soll aus Gründen der Einfachheit nur funktionieren, wenn der Benutzer das Steuerelement mit dem Mauszeiger an der rechten oder unteren Kante €anfasst€.
Das Wichtigste ist, dass der Benutzer weiß, dass er das Steuerelement nun nicht verschiebt, sondern vergrößert oder verkleinert. Und dazu ändern Sie den Mauszeiger in eine entsprechende Linie mit zwei Pfeilspitzen – genau so wie in Bild 2.
Bild 2: Anzeigen eines alternativen Mauszeigers beim Óndern der Größe eines Steuerelements
Das Óndern des Mauszeigers ist relativ einfach: Sie erreichen dies durch den Befehl Screen.MousePointer = 9, für den gleichen Pfeil in vertikaler Ausrichtung geben Sie den Wert 11 an.
Damit der jeweilige Mauszeiger nur am rechten beziehungsweise unteren Rand erscheint, fügen Sie eine kleine If…Then-Bedingung ein, die prüft, ob sich der Pfeil innerhalb eines Bereichs von 100 Twips links vom rechten Rand oder oberhalb vom unteren Rand befindet. Falls dies der Fall ist, müssen Sie noch prüfen, ob der Benutzer bei der Mausbewegung auch noch die linke Maustaste geklickt hat: Dann ändern Sie den Wert der Eigenschaften Width beziehungsweise Height des Steuerelements entsprechend.
Das folgende Listing zeigt die Ereignisprozedur, die beim Bewegen der Maus ausgelöst wird, im Zusammenhang:
Private Sub rctBeispiel_MouseMove(Button As _ Integer, Shift As Integer, X As Single, _ Y As Single) On Error Resume Next With rctBeispiel If X > .Width - 100 Then If Button = 1 Then .Width = .Width + X - lngXStart lngXStart = X End If Screen.MousePointer = 9 ElseIf Y > .Height - 100 Then Screen.MousePointer = 7 If Button = 1 Then .Height = .Height + Y - lngYStart lngYStart = Y End If Else Screen.MousePointer = 1 If Button = 1 Then .Top = .Top + Y - lngYStart .Left = .Left + X - lngXStart End If End If End With End Sub
Bei schnellen Bewegungen kann es passieren, dass die Maus den Steuerelementrand €loslässt€. Dieses kleine Problem beheben Sie durch einige weitere Codezeilen, die prüfen, ob seit dem letzten Verändern der Größe der Mauszeiger losgelassen wurde. Falls nicht, verändert die Routine weiterhin die Größe des Steuerelements und nicht die Größe. Die fertige Routine finden Sie im Formular frmSteuerelementeVerschieben in der Beispieldatenbank. Damit der Mauszeiger beim Verlassen des Steuerelements wieder wie üblich aussieht, legen Sie noch die folgende Prozedur für das Ereignis Bei Mausbewegung des Detailbereichs an:
Private Sub Detailbereich_MouseMove(Button _ As Integer, Shift As Integer, X As _ Single, Y As Single) Screen.MousePointer = 1 End Sub
Viele veränderbare Steuerelemente
Wenn Sie mehrere solcher Steuerelemente in einem Formular unterbringen möchten, macht es wenig Spaß, alle von Hand anzulegen.
Stattdessen verwenden Sie eine kleine Hilfsroutine, die wie in Listing 1 aussieht. Die Routine erstellt eine Reihe Rectangle-Elemente und fügt diese einfach links oben in das Formular ein. Die Steuerelemente werden von rct01 bis rctxx benannt.
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
den kompletten Artikel im PDF-Format mit Beispieldatenbank
diesen und alle anderen Artikel mit dem Jahresabo