Den Mauszeiger können Sie mittels der API-Funktion SetCursorPos an jede beliebige Stelle des Bildschirms setzen. Sie übergeben ihr dazu einfach die gewünschten Koordinaten in Pixels.
Private Declare Function SetCursorPos Lib "user32" _
(ByVal X As Long, ByVal Y As Long) As Long
SetCursorPos X, Y
Da Sie in Visual Basic Koordinaten meistens in der Maßeinheit TWIPS verwenden dürften, müssen Sie diese erst mittels der TwipsPerPixel...-Methoden des Screen-Objekts in Pixels umrechnen. Die folgende Hilfsprozedur SetMousePos erledigt dies automatisch, solange Sie den optionalen Parameter Twips auf True (Voreinstellung) gesetzt lassen. Liegen die Koordinaten bereits in einer anderen Maßeinheit vor (etwa vbCentimeter usw.), müssen Sie sie zuerst selbst in Pixels umrechnen. In diesem Fall können Sie nun sowohl die API-Funktion SetCursorPos direkt aufrufen, als auch, falls Ihnen die Einheitlichkeit lieber ist, die Hilfsprozedur SetMousePos, wobei Sie den optionalen Parameter TWIPS auf False setzen müssen.
Public Sub SetMousePos(ByVal X As Single, ByVal Y As Single, _
Optional ByVal Twips As Boolean = True)
Dim nX As Long
Dim nY As Long
If Twips Then
nX = X \ Screen.TwipsPerPixelX
nY = Y \ Screen.TwipsPerPixelX
Else
nX = X
nY = Y
End If
SetCursorPos nX, nY
End Sub
Wollen Sie jedoch den Mauszeiger an eine bestimmte Position innerhalb eines Forms oder eines Steuerelements bringen, müssen Sie die Lage des Forms oder Steuerelements auf dem Bildschirm berücksichtigen. Hinzu kommt, dass Sie die Koordinaten gegebenenfalls noch nicht in der Maßeinheit Pixels vorliegen haben, sondern zumeist in TWIPS, oder aber in der jeweils in der ScaleMode-Eigenschaft eines Forms oder einer PictureBox eingestellten Maßeinheit. Sie haben also sicherzustellen, dass die Koordinaten in Pixels umgerechnet und relativ vom betreffenden Form oder Steuerelement ausgehend in Bildschirmkoordinaten umgesetzt werden.
Die Umrechnung in Pixels lassen Sie am besten von den Scale...-Methoden (ScaleX und ScaleY) des Forms bzw. einer PictureBox erledigen. Während ein Form und eine PictureBox selbst diese Methoden zur Verfügung stellen, können Sie bei allen anderen Steuerelemente auf das Form zurückgreifen, auf dem das Steuerelement platziert ist. Unhabhängig davon, ob das Steuerelement eventuell auf einem anderen Steuerelement (Container) platziert ist, gelangen Sie an das Eltern-Form über die Parent-Eigenschaft des Steuerelements.
Die Umsetzung der nun in der Maßeinheit Pixels vorliegenden Steuerelement-Koordinaten in Bildschirm-Koordinaten erledigt die API-Funktion ClientToScreen. Sie deklarieren dazu eine benutzerdefinierte Variable des Typs POINTAPI und weisen deren Elementen X und Y die vorliegenden Steuerelement-Koordinaten zu. Beim Aufruf von ClientToScreen rechnet diese Funktion die Koordinaten anhand des ihr übergebenen Fenster-Handles (hWnd-Eigenschaft des Steuerelements) in Bildschirm-Koordinaten um, die Sie nach dem Aufruf aus der benutzerdefinierten Variablen auslesen und an nunmehr die API-Funktion SetCursorPos zur Positionierung des Mauszeigers übergeben können.
Im folgenden sehen Sie die entsprechend angepassten Hilfsprozeduren FormSetMousePos, PictureSetMousePos, ControlSetMousePos und SimpleControlSetMousePos. Die beiden letzteren unterscheiden sich dadurch, dass Sie ControlSetMousePos Steuerelemente übergeben, die über die Eigenschaft hWnd verfügen müssen. SimpleControlSetMousePos verarbeitet dagegen alle Steuerelemente, vor allem solche wie Image, Label und Shape, die eben nicht über eine hWnd-Eigenschaft verfügen.
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Declare Function ClientToScreen Lib "user32" _
(ByVal hWnd As Long, Point As POINTAPI) As Long
Private Declare Function SetCursorPos Lib "user32" _
(ByVal X As Long, ByVal Y As Long) As Long
Public Sub FormSetMousePos(Form As Form, ByVal X As Single, _
ByVal Y As Single)
Dim nPoint As POINTAPI
With Form
nPoint.X = .ScaleX(X, .ScaleMode, vbPixels)
nPoint.Y = .ScaleY(Y, .ScaleMode, vbPixels)
ClientToScreen .hWnd, nPoint
End With
With nPoint
SetCursorPos .X, .Y
End With
End Sub
Public Sub PictureSetMousePos(Picture As PictureBox, _
ByVal X As Single, ByVal Y As Single)
Dim nPoint As POINTAPI
With Picture
nPoint.X = .ScaleX(X, .ScaleMode, vbPixels)
nPoint.Y = .ScaleY(Y, .ScaleMode, vbPixels)
ClientToScreen .hWnd, nPoint
End With
With nPoint
SetCursorPos .X, .Y
End With
End Sub
Public Sub ControlSetMousePos(Control As Control, _
ByVal X As Single, ByVal Y As Single)
Dim nPoint As POINTAPI
With Control.Parent
nPoint.X = .ScaleX(X, vbTwips, vbPixels)
nPoint.Y = .ScaleY(Y, vbTwips, vbPixels)
ClientToScreen .hWnd, nPoint
End With
With nPoint
SetCursorPos .X, .Y
End With
End Sub
Public Sub SimpleControlSetMousePos(Control As Control, _
ByVal X As Single, ByVal Y As Single)
Dim nPoint As POINTAPI
Dim nScaleMode As Integer
With Control
On Error Resume Next
nScaleMode = .Container.ScaleMode
If Err.Number Then
nScaleMode = vbTwips
End If
With .Parent
nPoint.X = .ScaleX(X, vbTwips, vbPixels) + _
.ScaleX(Image.Left, nScaleMode, vbPixels)
nPoint.Y = .ScaleY(Y, vbTwips, vbPixels) + _
.ScaleX(Image.Top, nScaleMode, vbPixels)
End With
ClientToScreen .Container.hWnd, nPoint
End With
With nPoint
SetCursorPos .X, .Y
End With
End Sub
Neben der freien Positionierung des Mauszeigers bietet es sich an, den Mauszeiger genau mittig auf ein Steuerelement setzen zu können. Im Prinzip funktioniert das auf ähnliche Weise. Da Sie hierbei jedoch keine Koordinaten vorgeben, erübrigt sich auch jegliche Umrechnung. Jedoch müssen Sie die Position des Steuerelements und dessen Größe ermitteln. Dies erledigt die API-Funktion GetWindowRect bei Steuerelementen, die über eine hWnd-Eigenschaft verfügen, in der Hilfsprozedur ControlCenterMouse. Bei PictureBoxen können Sie deren spezialisierte Variante PictureCenterMouse verwenden.
Private Type Rect
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function GetWindowRect Lib "user32" _
(ByVal hWnd As Long, Rect As Rect) As Long
Public Sub ControlCenterMouse(Control As Control)
Dim nX As Long
Dim nY As Long
Dim nRect As Rect
With Control
GetWindowRect .hWnd, nRect
With nRect
nX = .Left + ((.Right - .Left) \ 2)
nY = .Top + ((.Bottom - .Top) \ 2)
End With
End With
SetCursorPos nX, nY
End Sub
Public Sub PictureCenterMouse(Picture As PictureBox)
Dim nPoint As POINTAPI
Dim nRect As Rect
With Picture
GetWindowRect .hWnd, nRect
With nRect
nPoint.X = .Left + ((.Right - .Left) \ 2)
nPoint.Y = .Top + ((.Bottom - .Top) \ 2)
End With
End With
With nPoint
SetCursorPos .X, .Y
End With
End Sub
Bei den anderen Steuerelementen, die nicht über eine hWnd-Eigenschaft verfügen, erfolgt die relative Umsetzung in Bildschirm-Koordinaten über ClientToScreen, nachdem die relative mittige Position im Steuerelement in Bezug auf dessen Container ermittelt worden ist.
Public Sub SimpleControlCenterMouse(Control As Control)
Dim nPoint As POINTAPI
Dim nScaleMode As Integer
With Control
On Error Resume Next
nScaleMode = .Container.ScaleMode
If Err.Number Then
nScaleMode = vbTwips
End If
nPoint.X = .Parent.ScaleX(.Left + (.Width \ 2), _
nScaleMode, vbPixels)
nPoint.Y = .Parent.ScaleY(.Top + (.Height \ 2), _
nScaleMode, vbPixels)
ClientToScreen .Container.hWnd, nPoint
End With
With nPoint
SetCursorPos .X, .Y
End With
End Sub
Genauso können Sie auch den Mauszeiger mittig im Bildschirm positionieren. In der Hilfsprozedur ScreenCenterMouse werden dazu die Höhe und Breite des Bildschirms halbiert und die resultierenden Werte in Pixels umgerechnet an die API-Funktion SetCursorPos übergeben.
Public Sub ScreenCenterMouse()
Dim nX As Long
Dim nY As Long
nX = Screen.Width \ 2 \ Screen.TwipsPerPixelX
nY = Screen.Height \ 2 \ Screen.TwipsPerPixelY
SetCursorPos nX, nY
End Sub
Beachten Sie, dass bei allen Divisionen die Integer-Division verwendet wird, damit sich überall ganzzahlige Ergebnisse ergeben. Das ist notwendig, da API-Funktion, die mit Pixels arbeiten, auch nur ganzzahlige Werte verarbeiten können.
Zum Schluss möchte ich Ihnen allerdings nicht meine starken Bedenken gegen eine Positionierung des Mauszeigers durch eine Anwendung verhehlen.
Besonders bei hohen Bildschirmauflösungen nutzt der Anwender die Fläche seines Mauspads meistens voll aus. Befindet sich nun der Mauszeiger irgendwo in der Nähe des rechten Bildschirmrands, befindet sich dementsprechend auch die Maus weit rechts in der Nähe der rechten Kante des Mauspads. Angenommen, Sie positionieren Sie nun den Mauszeiger weit nach links, im Extremfall etwa in die Nähe der linken Bildschirmkante. Dann muss der Anwender, um den Mauszeiger wieder nach rechts bewegen zu können, die Maus erst einmal abheben und auf seinem Mauspad versetzen, damit die Maus nicht nach rechts vom Mauspad herunter rutscht. Wird dem Anwender diese Mühe zu oft aufgebürdet, dürfte er sicher nicht sehr glücklich darüber sein. Insofern halte ich auch das Windows- bzw. Maustreiber-Feature der Positionierung des Mauszeigers über Dialog-Schaltflächen eher für einen Spielzeug-Gimmick (glücklicherweise ist braucht man dieses Feature ja gar nicht erst zu aktivieren). Mir persönlich ist es jedenfalls lieber, wenn ich nicht von einer Anwendung bei der Positionierung des Mauszeigers bevormundet werde, und ich selber die Kontrolle über den Mauszeiger behalte.
Somit sollten Sie diese Technik eher mit Bedacht einsetzen und, wenn schon, dann unbedingt auch als Option abschaltbar machen.
|