Kontakt
DSVGO
Bei grafisch anspruchvollen Benutzer-Oberflächen hat man oft das Problem zuverlässig bestimmen zu müssen, ob der Mauscursor ein Control gerade betreten oder - was weit schwieriger festzustellen ist - gerade verlassen hat. Dies wird z.B. bei der Reproduktion des beliebten Hover-Effekts (ein optischer Feedback) benötigt oder bei der Aktualisierung der Statuszeile (als Kontext-sensitive ToolTips-Ergänzung bzw. Kurz-Hilfe).
Als ersten Lösungs-Ansatz wird man sicher auf das MouseMove-Ereignis zurückgreifen wollen, welches immer dann ausgelöst wird, wenn die Maus über ein Control fährt. Doch wie soll dann festgestellt werden, ob und wann die Maus das Control verläßt? Man könnte zwar auf das MouseMove-Ereignis des Formulars zurückgreifen, aber leider arbeitet diese Methode nicht zuverlässig: Wird z.B. der Mauszeiger schnell von einem Control in ein anderes gezogen (oder gar ganz aus dem Formular hinaus), so bekommt das Formular überhaupt kein Ereignis mit.
Zum Glück stellt die Windows-API Hilfsmittel zur Verfügung, um ein Control zu "verfolgen" (engl. "to capture"). Damit werden alle MouseMove-Ereignisse immer an dieses eine Control gesendet, egal wo die Maus gerade steht.
Mit der unten vorgestellten MouseOverState-Funktion wird für ein gegebenes Control ctl überprüft, ob die Maus gerade darüber "schwebt". Falls nein, so gibt die Funktion vbLeave zurück. Wird das Control bereits verfolgt, so gibt die Funktion vbOver zurück, ansonsten wird die Verfolgung iniziiert und ein vbEnter zurückgegeben (s.a. Online-Hilfe zum DragOver-Ereignis).
Im diesem Beispiel wechselt die Beschriftung des CommandButtons cmdTest folgendermaßen: Fährt die Maus in die Schaltfläche rein, so erscheint "in"; Wird die Maus innerhalb des Buttons bewegt, so ertönt (zu Testzwecken) ein akustisches Signal; Verläßt der Mauscursor die Schaltfläche, so erscheint "out".
Private Sub cmdTest_MouseMove(Button As Integer, _ Shift As Integer, X As Single, Y As Single) Select Case MouseOverState(cmdTest) Case vbEnter cmdTest.Caption = "in" Case vbOver Beep 'Test Case vbLeave cmdTest.Caption = "out" End Select End Sub
Im Deklarationsteil eines Moduls oder Formulars müssen folgende API-Routinen zur Verfügung gestellt werden:
Private Type POINTAPI X As Long Y As Long End Type Private Declare Function GetCursorPos Lib "user32" ( _ lpPoint As POINTAPI) As Long Private Declare Function WindowFromPoint Lib "user32" ( _ ByVal xPoint As Long, ByVal yPoint As Long) As Long Private Declare Function GetCapture Lib "user32" ( _ ) As Long Private Declare Function SetCapture Lib "user32" ( _ ByVal hWnd As Long) As Long Private Declare Function ReleaseCapture Lib "user32" ( _ ) As Long
Die eigentliche Funktion sieht dann folgendermaßen aus:
Public Function MouseOverState( _ ByRef ctl As Control _ ) As DragOverConstants 'Deklarationen: Dim Point As POINTAPI Dim Window As Long 'hWnd des Controls unter der Maus bestimmen: GetCursorPos Point Window = WindowFromPoint(Point.X, Point.Y) 'Handles vergleichen: If ctl.hWnd = Window Then 'Feststellen, ob Control gewechselt hat: If GetCapture() <> Window Then 'Verfolgung starten: SetCapture Window MouseOverState = vbEnter Else 'Verfolgung fortsetzen: MouseOverState = vbOver End If Else 'Verfolgung stoppen: ReleaseCapture MouseOverState = vbLeave End If 'ctl.hWnd = Window End Function
© Jost Schwider, 31.03.2001-31.03.2001 - http://vb-tec.de/mausover.htm