13.2 Die Mausschnittstelle
Obwohl die meisten Anwendungen auch ohne Maus bedient werden können, gehört die Maus zur Standardausrüstung jedes PC. Die Ausführungen reichen von einer Zweitasten- über eine Dreitastenmaus bis hin zur IntelliMouse, bei der anstelle einer dritten Taste ein Rädchen zu finden ist, das beim Drücken die dritte Taste ersetzt. Mit Programmen, die das Rädchen unterstützen, können Sie bequemer durch lange Dokumente scrollen.
Durch eine Mausaktion können mehrere verschiedene Ereignisse ausgelöst werden. Zwei haben wir im Verlauf der letzten Kapitel schon eingesetzt: Click und DoubleClick. Da diese Ereignisse nicht nur bei einem Mausklick, sondern auch durch die Tastatur ausgelöst werden können, sind beide durch MouseClick und MouseDoubleClick ergänzt worden, die nur auf die Maus reagieren. Darüber hinaus stehen Ihnen noch folgende Ereignisse zur Verfügung:
- MouseDown
- MouseEnter
- MouseHover
- MouseLeave
- MouseMove
- MouseUp
- MouseWheel
In einer Windows-Form kann immer nur eine Komponente Mausereignisse empfangen. Wird der Mauscursor über das Steuerelement einer Form bewegt, empfängt nicht die Form das Mausereignis, sondern das Steuerelement. Das setzt selbstverständlich voraus, dass das Steuerelement sichtbar und aktiviert ist (Enabled=True). Liegen zwei Steuerelemente übereinander, empfängt dasjenige Steuerelement Mausereignisse, das in der z-Reihenfolge an oberster Stelle liegt. Eine Form empfängt nur Mausereignisse, wenn sich der Mauszeiger über einem Teil des Clientbereichs befindet, der weder sichtbare und aktive Steuerelemente enthält noch Teil des Rahmens oder der Titelleiste ist.
13.2.1 Die Ereignisse MouseDown, MouseMove und MouseUp
Wir wollen die Ereignisse MouseDown, MouseMove und MouseUp näher betrachten, da sie in nahezu jeder Anwendung zu finden sind. Aus deren Bezeichnern kann schon entnommen werden, wann die Ereignisse ausgelöst werden: MouseDown beim Druck auf eine Maustaste und MouseUp beim Loslassen einer Maustaste. Wird die Maus über eine Komponente bewegt, werden sehr viele MouseMove-Ereignisse ausgelöst.
Alle drei Ereignisse sind vom Typ MouseEventHandler und übergeben dem Ereignishandler im zweiten Parameter ein Objekt vom Typ MouseEventArgs (siehe Tabelle 13.9).
Eigenschaft | Typ | Beschreibung (alle ReadOnly) |
Button |
MouseButtons |
Gibt an, welche Maustaste gedrückt wurde. |
Clicks |
Integer |
Gibt an, wie oft die Maustaste gedrückt wurde. |
Delta |
Integer |
Anzahl der Arretierungen, um die das Mausrad gedreht wurde. Je nach Drehrichtung ist die Zahl positiv oder negativ. |
Location |
Point |
Liefert die Mauszeigerkoordinaten x und y in Pixel. |
X |
Integer |
X-Koordinate eines Mausklicks |
Y |
Integer |
Y-Koordinate eines Mausklicks |
Da die Mausereignisse unabhängig davon sind, welche Maustaste der Anwender gedrückt hat, ist die Auswertung der Maustaste wichtig. Die Eigenschaft Button liefert uns die Taste mittels Werten der Enumeration MouseButtons (siehe Tabelle 13.10).
Konstante | Beschreibung |
None |
Keine Maustaste wurde gedrückt. |
Left |
Die linke Maustaste wurde gedrückt. |
Right |
Die rechte Maustaste wurde gedrückt. |
Middle |
Die mittlere Maustaste wurde gedrückt. |
XButton1 |
XButton eins wurde gedrückt. |
XButton2 |
XButton zwei wurde gedrückt. |
Die ersten vier Enumerationskonstanten sind selbsterklärend, da sie zum Standard gehören. Die letzten beiden, XButton1 und XButton2, beziehen sich auf die Tasten der IntelliMouse Explorer, die über fünf Tasten verfügt.
Die Auswertung der gedrückten Maustaste ist einfach. Im Ereignishandler, der mit dem Mausereignis verknüpft ist, wird die Eigenschaft Button des zweiten Parameters vom Typ MouseEventArgs abgefragt und darauf entsprechend reagiert:
' Ereignishandler eines MouseDown-Events Private Sub MouseEvent(sender As Object, e As MouseEventArgs) If e.Button = MouseButtons.Left Then _ ... ' die linke Maustaste wurde gedrückt End Sub
Die Enumeration MouseButtons hat das Flags-Attribut. Daher können die Werte bitweise miteinander kombiniert werden, um gleichzeitig gedrückte Tasten zu erfassen. Zum Beispiel kann so eine Zweitastenmaus eine mittlere Taste durch Klick auf beide Tasten simulieren.
Sollten Sie als Linkshänder in der Systemsteuerung von Windows die linke und rechte Maustaste vertauscht haben, wird Ihnen bei der Auswertung von MouseButtons trotz des Drückens der rechten Maustaste Left zurückgegeben. Sinnvoller wäre es daher gewesen, zwischen einer primären und einer sekundären Maustaste zu unterscheiden und dabei die primäre mit der gleichzusetzen, mit der standardmäßig das Click-Ereignis ausgelöst wird.
Die MouseEventsArgs-Eigenschaft Clicks liefert nur die Zahlen 1 oder 2. Damit lässt sich feststellen, ob es sich um einen einfachen Klick oder um einen Doppelklick des Anwenders handelt.
Hinweis |
Die Zeitspanne in Millisekunden, die unterschritten werden muss, um aus zwei einfachen Klicks einen Doppelklick zu machen, können Sie aus der klassengebundenen Eigenschaft DoubleClickTime der Klasse SystemInformation im Namensraum System.Windows.Forms auslesen. |
Die Eigenschaften X und Y enthalten die aktuellen Koordinaten des Mauscursors, und Location liefert beide Werte gleichzeitig über ein Point-Objekt. Die Werte in Pixel beziehen sich immer auf das Steuerelement oder die Form, über deren Bereich sich der Mauszeiger befindet. Dabei ist der Nullpunkt immer die linke obere Ecke der Komponente, die das Mausereignis ausgelöst hat.
Im folgenden Beispiel MouseMove wird in einer PictureBox an der aktuellen Mauszeigerposition ein Fadenkreuz aus einer vertikalen und einer horizontalen Linie gezeichnet, die jeweils von einem Rand bis zum gegenüberliegenden reicht (siehe Abbildung 13.1).
Abbildung 13.1 Ausgabe des Beispiels »MouseMove«
'...\TastaturMaus\Maus\MouseMove.vb |
Public Class MouseMove
Private MousePoint As Point
Private Sub Fadenkreuz_MouseMove(sender As Object, e As MouseEventArgs) _
Handles Fadenkreuz.MouseMove
X.Text = e.X.ToString()
Y.Text = e.Y.ToString()
Dim graph As Graphics = Fadenkreuz.CreateGraphics()
' altes Fadenkreuz löschen
DrawLines(graph, MousePoint, Fadenkreuz.BackColor)
' neues Fadenkreuz zeichnen
MousePoint = New Point(e.X, e.Y)
DrawLines(graph, MousePoint, Color.White)
graph.Dispose()
End Sub
Private Sub DrawLines(graph As Graphics, p As Point, c As Color)
Dim pen As New Pen(c)
Dim startHor As New Point(0, p.Y)
Dim endHor As New Point(Fadenkreuz.Width, p.Y)
Dim startVert As New Point(p.X, 0)
Dim endVert As New Point(p.X, Fadenkreuz.Height)
' Fadenkreuz zeichnen
graph.DrawLine(pen, startHor, endHor)
graph.DrawLine(pen, startVert, endVert)
End Sub
End Class
Das Fadenkreuz wird gezeichnet, sobald die Maus in den Clientbereich der Picturebox eintritt. Die Koordinaten des Mauszeigers werden in je einer Textbox ausgegeben.
Damit die Picturebox beim Ziehen der Maus nur das aktuelle Fadenkreuz anzeigt, muss zuerst das ungültige gewordene Fadenkreuz gelöscht werden. Dazu ist auf Klassenebene das Feld MousePoint deklariert, das immer die Mauskoordinaten enthält, mit denen das letzte Fadenkreuz gezeichnet worden ist. Mit diesen Punktkoordinaten wird zuerst ein Fadenkreuz in der Hintergrundfarbe der Picturebox gezeichnet. Das ungültig gewordene Fadenkreuz ist damit »gelöscht«. Die aktuellen Mauskoordinaten werden anschließend in das Feld MousePoint geschrieben, und das neue Fadenkreuz wird in weißer Farbe gezeichnet.
Das Zeichnen eines Fadenkreuzes übernimmt die Methode DrawLines der Form, die aus dem MouseMove-Ereignis heraus sowohl für das zu löschende als auch für das neu zu zeichnende Fadenkreuz aufgerufen wird. Die eigentliche Zeichenoperation übernimmt die Methode DrawLine der Klasse Graphics. Das erste Argument ist ein Pen-Objekt, das die Farbe des Fadenkreuzes beschreibt. Je zwei Point-Objekte legen den Start- und den Endpunkt jeder Linie fest.
13.2.2 Das Ereignis MouseWheel
Ohne offensichtlichen Grund wird das MouseWheel-Ereignis nicht mit den anderen Ereignissen im Eigenschaftsfenster gelistet. Dennoch unterstützen alle Steuerelemente dieses Ereignis, die sich für den Einsatz des Mausrads eignen (z. B. die Textbox), ohne dass eine Zeile Code implementiert werden muss. Ebenso können Ihre Steuerelemente das Ereignis behandeln; es fehlt lediglich der Komfort der automatischen Erstellung eines Ereignishandlers. Manuell ist die Implementierung aber auch schnell erledigt.
Private Sub MouseWheelHandler(sender As Object, e As MouseEventArgs e) _ Handles textBox1.MouseWheel ' Anweisungen End Sub
Zur Steuerung des Bildlaufs dient die Eigenschaft Delta des MouseEventArgs-Objekts. Beträgt der Wert 120, entspricht das einem Bildlauf. Der Wert 120 stammt aus den Tiefen der Win32-API. Er entspricht dem Weiterdrehen des Mausrades um ein Raster. Die Richtung der Drehung spiegelt sich im Vorzeichen von Delta wider.
Die Frage, um wie viele Zeilen der Bildlauf bei der Drehung des Mausrades um 120 Einheiten erfolgt, kann der Eigenschaft SystemInformation.MouseWheelScrollLines entnommen werden. Der Standard ist auf 3 festgelegt.
13.2.3 Weitere Mausereignisse
Die folgenden drei Mausereignissen befassen sich mit der Bewegung über ein Steuerelement:
- MouseEnter wird ausgelöst, wenn der Mauszeiger den Bereich der Komponente betritt.
- MouseHover tritt auf, wenn der Mauszeiger im Clientbereich der Komponente einen Augenblick lang bewegungslos verharrt, d. h., wenn er nicht kontinuierlich bewegt wird.
- MouseLeave ist das Gegenstück zu MouseEnter und wird ausgelöst, wenn der Mauszeiger den Clientbereich der Komponente verlässt.
Alle drei Ereignisse sind vom Typ EventHandler und stellen dem Ereignishandler somit auch keine weiteren Informationen zur Verfügung, denn das Objekt EventArgs enthält keine spezifischen Eigenschaften.
13.2.4 Click-Ereignisse
Die Ereignisse Click und DoubleClick sowie die analogen MouseClick und MouseDoubleClick sind an die primäre Maustaste gebunden. Standardmäßig ist das die linke; Linkshänder stellen in der Systemsteuerung oft die rechte Maustaste als primäre Maustaste ein. Das Click-Ereignis tritt zwischen den Ereignissen MouseDown und MouseUp auf. Ein Doppelklick wird dann erkannt, wenn kurz genug hintereinander auf die primäre Maustaste gedrückt wird. Die Zeitspanne wird in der Systemsteuerung eingestellt.
13.2.5 Verhalten der Maus
Die Eigenschaft Cursor
Die Darstellung des Mauszeigers zur Laufzeit wird durch die in der Klasse Control definierte Eigenschaft Cursor festgelegt. Ausnahmsweise sind die erlaubten Cursortypen nicht in einer Aufzählung, sondern in der Klasse Cursors enthalten. Der Mauscursor kann ein optischer Hinweis auf laufende Aktionen sein. Beispielsweise weist die in Cursors.WaitCursor beschriebene Sanduhr den Anwender auf eine länger andauernde Operation hin. Nach der Operation dürfen Sie nicht vergessen, den ursprünglichen Mauscursor wiederherzustellen:
Me.Cursor = Cursors.WaitCursor ... Me.Cursor = Cursors.Default
Sowohl das Formular als auch die Steuerelemente ermöglichen eine Anpassung des Cursors an die aktuellen Gegebenheiten. Stellen Sie diese Eigenschaft für die Form ein, gilt dies auch für die darin enthaltenen Steuerelemente, solange Sie diesen nicht ausdrücklich eine andere Einstellung zuweisen.
Die Eigenschaft Cursor.Position
Die Klasse Cursor veröffentlicht eigene Eigenschaften und Methoden. Die interessanteste ist wahrscheinlich die klassengebundene Eigenschaft Position, mit der die Position des Mauszeigers nicht nur abgerufen, sondern auch gesetzt werden kann. Die durch das Point-Objekt beschriebenen Koordinaten sind Bildschirmkoordinaten. Daher führt die Anweisung
Cursor.Position = New Point(0, 0)
dazu, dass der Mauszeiger in die obere linke Ecke des Bildschirms springt – auch wenn die neue Position außerhalb der aktuellen Form liegt.
Die Eigenschaft Control.MousePosition
Die Position des Mauszeigers relativ zum Bildschirm können Sie auch mit der klassengebundenen Eigenschaft MousePosition der Klasse Control auslesen. Die Anweisung
Me.Text = Control.MousePosition.ToString()
gibt die Positionskoordinaten in der Titelleiste des Formulars in einer gut lesbaren Form aus. Dies ist ein gutes Beispiel dafür, dass die von Object geerbte ToString-Methode immer sinnvoll überschrieben werden sollte.
Die Methode PointToClient
MousePosition liefert immer Bildschirmkoordinaten zurück. Manchmal muss man diese in Clientkoordinaten umrechnen, und am einfachsten geht dies mit der Methode PointToClient der Klasse Control. Übergeben wird zum Beispiel der Wert der Eigenschaft MousePosition:
Me.Text = Me.PointToClient(Control.MousePosition).ToString()
Das von PointToClient zurückgegebene Point-Objekt kann sogar negative Werte enthalten. Folglich bietet sich PointToClient an, um den Abstand des Mauszeigers von einem beliebigen Steuerelement in Pixel zu ermitteln.
Druck auf eine Zustandstaste
Manchmal möchte man, dass Mausaktionen nur dann ausgeführt werden, wenn eine oder mehrere der Zustandstasten , und gedrückt sind. Hier kann die oben erwähnte klassengebundene Eigenschaft ModifierKeys eingesetzt werden.
Soll das im Beispiel MouseMove gezeichnete Fadenkreuz nur dann an der aktuellen Mausposition dargestellt werden, wenn gleichzeitig die -Taste gedrückt ist, können Sie den Ereignishandler des Ereignisses MouseMove wie folgt ergänzen:
Private Sub Fadenkreuz_MouseMove(sender As Object, e As MouseEventArgs) _ Handles Fadenkreuz.MouseMove If Control.ModifierKeys <> Keys.Alt Then Return ... End Sub
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.