Ob der Anwender eine Taste gedrückt hat, oder ob bei Mausbewegungen eine Maustaste niedergedrückt ist, erfahren Sie in der Regel über die Key- oder Mouse-Ereignisse. Dort können Sie die übergebenen Tasten-Informationen verarbeiten. Außerhalb dieser Ereignisse bietet Visual Basic jedoch keine Möglichkeit, Informationen über den Status einzelner Tasten einzuholen, etwa während der Abarbeitung von Schleifen in anderen Teilen Ihrer Programme.
Die API-Funktion GetAsyncKeyState liefert Ihnen in ihrem Rückgabewert (Datentyp Integer, in C: SHORT[-Integer]) zu jeder beliebigen Taste jederzeit die Information, ob sie niedergedrückt ist. Als Parameter übergeben Sie die gewünschte Tasten-Konstante (im Objekt-Katalog finden Sie diese unter VBRUN/KeyCodeConstants). Ist das höchste Bit des Rückgabewerts gesetzt, ist die Taste zum Zeitpunkt des Aufrufs der niedergedrückt gewesen.
Allerdings können Sie den Rückgabewert nicht direkt als absoluten Wert prüfen. Denn die Funktion liefert im Rückgabewert auch die Information darüber, ob die betreffende Taste auch in der Zeit zwischen dem aktuellen und einem vorangegangenen Aufruf niedergedrückt (und eventuell wieder losgelassen) worden ist. Dann ist das niederwertigste Bit gesetzt. Diese Information wird jedoch nur noch aus Kompatibilitätsgründen zum 16-Bit-Windows (Windows 3.x) geliefert. Unter den Windows-Versionen Windows 9x, NT, 2000 (und spätere) mit präemptiven Multitasking ist diese Information nicht mehr zuverlässig. Denn eine andere Anwendung, die zwischenzeitlich zum Zuge gekommen ist, kann die Funktion ebenfalls aufgerufen und dabei die Information schon "abgeräumt" haben.
Sie müssen also prüfen, ob im Rückgabewert das höchste Bit gesetzt ist. Dies geschieht mittels einer so genannten "Maske", also einer Zahl, in dem genau das zu prüfende Bit, bzw. die zu prüfenden Bits, falls mehrere betroffen sein sollten, gesetzt ist bzw. sind. Diese Maske wird mittels des And-Operators mit dem zu prüfenden Wert (bitweise) verknüpft. Im Ergebnis sind nur noch die Bits gesetzt, die sowohl im zu prüfenden Wert als auch in der Maske gesetzt waren. War das zu prüfende Bit bzw. waren die zu prüfenden Bits im Ausgangswert gesetzt, entspricht das Ergebnis genau der Maske.
Beispiel:
1000000000000001 - zu prüfender Wert
And
1000000000000000 - Maske
----------------
1000000000000000 - Ergebnis stimmt mit der Maske überein
oder:
0000000000000001 - zu prüfender Wert
And
1000000000000000 - Maske
----------------
0000000000000000 - Ergebnis stimmt nicht mit der Maske überein
oder:
1000000000000000 - zu prüfender Wert
And
1000000000000000 - Maske
----------------
1000000000000000 - Ergebnis stimmt mit der Maske überein
oder:
0000000000000000 - zu prüfender Wert
And
1000000000000000 - Maske
----------------
0000000000000000 - Ergebnis stimmt nicht mit der Maske überein
Diese vier Beispiele stellen auch zugleich die Prüfung des Rückgabewerts von GetAsyncKeyState dar. Uns interessiert nur das höchste Bit, egal ob aus Kompatibilitätsgründen das niederwertigste ("letzte") Bit gesetzt ist oder nicht.
Der Wert für die Maske lautet -32768, oder einfacher als hexadezimale Zahl ausgedrückt: &H8000. Der Aufruf der Funktion GetAsyncKeyState sieht danach so aus:
If (GetAsyncKeyState(KeyCode) And &H8000) = &H8000 Then
' Taste gedrückt...
Else
' Taste nicht gedrückt...
End If
Oder praktischerweise in eine Funktion etwa in einem Standard-Modul verpackt:
Private Declare Function GetAsyncKeyState Lib "user32" _
(ByVal vKey As Long) As Integer
Public Function KeyPressed(ByVal Key As Long) As Boolean
KeyPressed = CBool((GetAsyncKeyState(Key) And &H8000) = &H8000)
End Function
Sie können diese Funktion auch für Maustasten aufrufen, für die ebenfalls KeyCode-Konstanten definiert sind - vbKeyLButton, vbKeyRButton und vbKeyMButton. Allerdings ist die Prüfung hierbei wortwörtlich zu nehmen: So wird bei vbKeyLButton geprüft, ob tatsächlich die linke, physische Maustaste niedergedrückt ist - unabhängig davon, ob der Anwender die Zuordnung der linken und der rechten Maustaste hat (wie es etwa Linkshänder gerne tun). Für vbKeyRButton verhält sich das dann genau umgekehrt. Um die logische Zuordnung abweichend von den tatsächlichen, physikalischen der Maustasten zu berücksichtigen, können Sie über die API-Funktion GetSystemMetrics mit der Index-Konstanten SM_SWAPBUTTON erfahren, ob der Anwender die Maustasten vertauscht hat. Ist das der Fall, rufen Sie GetAsyncKeyState eben mit dem KeyCode der entgegengesetzten Maustaste auf.
Der Einfachheit halber verpacken wir auch diese Aktion wieder ein eine Funktion, bei der Sie neben der Tasten-Konstante für die betreffenden Maustaste auch angeben können, ob die logische Zuordnung (optionaler Parameter "Logical", Voreinstellung True) oder ob die physische Zuordnung geprüft werden soll (ausdrückliche Übergabe von False).
Private Declare Function GetAsyncKeyState Lib "user32" _
(ByVal vKey As Long) As Integer
Private Declare Function GetSystemMetrics Lib "user32" _
(ByVal nIndex As Long) As Long
Public Function MouseButtonPressed(ByVal MouseKey As Long, _
Optional ByVal Logical As Boolean) As Boolean
Dim nMouseKey As Long
Const SM_SWAPBUTTON = 23
Select Case MouseKey
Case vbKeyLButton, vbKeyRButton, vbKeyMButton
If Logical Then
If GetSystemMetrics(SM_SWAPBUTTON) Then
Select Case MouseKey
Case vbKeyLButton
nMouseKey = vbKeyRButton
Case vbKeyRButton
nMouseKey = vbKeyLButton
Case vbKeyMButton
nMouseKey = MouseKey
End Select
Else
nMouseKey = MouseKey
End If
Else
nMouseKey = MouseKey
End If
Case Else
Err.Raise 380
End Select
MouseButtonPressed = _
CBool((GetAsyncKeyState(nMouseKey) And &H8000) = &H8000)
End Function
Die Liste der Tasten-Konstanten in Visual Basic ist allerdings nicht vollständig. Abgesehen davon, dass schon immer einige der im API definierten "Virtual-Key"-Konstanten gefehlt haben, sind vor im Laufe der Zeit weitere Tasten-Codes hinzu gekommen, etwa für die speziellen Windows-Tasten und viele weitere Tasten seit Windows 2000.
Die unten stehende Enumeration KeyCodeExConstants enthält die fehlenden und die neueren Codes, im gleichen Stil wie die VB-eigenen Konstanten beginnend mit "vbKey..." deklariert. Sie enthält auch zwei etwas leichter als die VB-Originale merkbare Konstanten für die Alt-Taste und die Druck-Taste. Da unter NT und ab Windows 2000 auch die linken und rechten Umschalt-, Strg- und Alt-Tasten (letztere nur auf Tastaturen, bei denen die rechte Alt-Taste nicht zur AltGr-Taste umgewidmet ist) unterschieden werden können, gibt es nun auch dafür spezielle Konstanten.
Für den Sonderfall der AltGr-Taste, die ein gleichzeitiges Niederdrücken von Alt- und Strg-Taste ergibt, steht die Funktion AltGrPressed zur Verfügung. Diese Funktion braucht natürlich keine Parameter. In ihr werden einfach mit zwei aufeinanderfolgenden Aufrufen die beiden einzelnen Tasten-Codes vbKeyControl und vbKeyAlt geprüft:
Public Function AltGrPressed() As Boolean
AltGrPressed = _
CBool((GetAsyncKeyState(vbKeyControl) And &H8000) = &H8000) _
And CBool((GetAsyncKeyState(vbKeyAlt) And &H8000) = &H8000)
End Function
Nun noch zum Abschluss die zusätzlichen Tasten-Konstanten:
Public Enum KeyCodeExConstants
' leichter merkbar
vbKeyAlt = vbKeyMenu
vbKeyPrintScreen = vbKeySnapshot
' Windows-Tasten
vbKeyLWin = &H5B 'Linke Windows-Taste
vbKeyRWin = &H5C 'Rechte Windows-Taste
vbKeyApps = &H5D 'Anwendungen-Taste
' Nur unter NT/Windows 2000 und später
vbKeyLShift = &HA0
vbKeyRShift = &HA1
vbKeyLControl = &HA2
vbKeyRControl = &HA3
vbKeyLAlt = &HA4
vbKeyRAlt = &HA5
' bzw. im Original
vbKeyLMenu = &HA4
vbKeyRMenu = &HA5
' ab Windows 2000
vbKeyXButton1 = &H5 'X1-Maus-Taste
vbKeyXButton2 = &H6 'X2-Maus-Taste
vbKeyBrowserBack = &HA6
vbKeyBrowserForward = &HA7
vbKeyBrowserRefresh = &HA8
vbKeyBrowserStop = &HA9
vbKeyBrowserSearch = &HAA
vbKeyBrowserFavorites = &HAB
vbKeyBrowserHome = &HAC
vbKeyVolumeMute = &HAD
vbKeyVolumeDown = &HAE
vbKeyVolumeUp = &HAF
vbKeyMediaNextTrack = &HB0
vbKeyMediaPrevTrack = &HB1
vbKeyMediaStop = &HB2
vbKeyMediaPlayPause = &HB3
vbKeyLaunchMail = &HB4
vbKeyLaunchMediaSelect = &HB5
vbKeyLaunchApp1 = &HB6
vbKeyLaunchApp2 = &HB7
' IME
vbKeyKANA = &H15
vbKeyHANGUL = &H15
vbKeyJUNJA = &H17
vbKeyFINAL = &H18
vbKeyHANJA = &H19
vbKeyKANJI = &H19
vbKeyConvert = &H1C
vbKeyNonConvert = &H1D
vbKeyAccept = &H1E
vbKeyModeChange = &H1F
vbKeyProcessKey = &HE5
' weitere Funktionstasten
vbKeyF17 = &H80
vbKeyF18 = &H81
vbKeyF19 = &H82
vbKeyF20 = &H83
vbKeyF21 = &H84
vbKeyF22 = &H85
vbKeyF23 = &H86
vbKeyF24 = &H87
' OEM-Zuordnungen, ab Windows 2000 - international
vbKeyOEMPlus = &HBB
vbKeyOEMComma = &HBC
vbKeyOEMMinus = &HBD
vbKeyOEMPeriod = &HBE
' OEM-Zuordnungen, ab Windows 2000 - US-Keyboards
vbKeyOEM_1 = &HBA ' Taste ;:
vbKeyOEM_2 = &HBF ' Taste /?
vbKeyOEM_3 = &HC0 ' Taste `~
vbKeyOEM_4 = &HDB ' Taste [{
vbKeyOEM_5 = &HDC ' Taste \|
vbKeyOEM_6 = &HDD ' Taste ]}
vbKeyOEM_7 = &HDE ' Taste '"
' Sonstige Sondertasten
vbKeySleep = &H5F
vbKeyATTN = &HF6
vbKeyCRSEL = &HF7
vbKeyEXSEL = &HF8
vbKeyEREOF = &HF9
vbKeyPlay = &HFA
vbKeyZoom = &HFB
vbKeyPA1 = &HFD
vbKeyOEMClear = &HFE
End Enum
|