Detect modifier keys from VBA?

A

automandc

I want to control the behavior of a macro based on whether a modifier like
"Ctrl" or "Alt" is held down when the macro is run. I know you can detect
the state of CapsLock and NumLock, but is there any way to detect the current
state of the other keys on the keyboard? (Note, I am not using a form).

Ideally, I'd like this to work from a toolbar button -- i.e., clicking the
button runs the macro one way, clicking the button while holding shift or
ctrl runs it a different way.
 
H

Helmut Weber

Hi automandc,

I did it once, but can't find it anymore.
You need API-function GetKeyState()
or related functions.

--
Greetings from Bavaria, Germany

Helmut Weber, MVP WordVBA

Win XP, Office 2003
"red.sys" & Chr$(64) & "t-online.de"
 
H

Helmut Weber

If you want to know it all,
from Thomas Gahler, MVP:

There is some german in the text,
but you'll make it.


' ---------- Start Modul1 ----------
Option Explicit


'API zum feststellen des Keyboard-Status deklarieren.
Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As
Integer


'Konstanten zum feststellen des Keyboard-Status definieren.
Public Const VK_LBUTTON As Integer = &H1
Public Const VK_RBUTTON As Integer = &H2
Public Const VK_CANCEL As Integer = &H3
Public Const VK_MBUTTON As Integer = &H4 ' NOT
contiguous
with L RBUTTON


Public Const VK_BACK As Integer = &H8
Public Const VK_TAB As Integer = &H9


Public Const VK_CLEAR As Integer = &HC
Public Const VK_RETURN As Integer = &HD


Public Const VK_SHIFT As Integer = &H10
Public Const VK_CONTROL As Integer = &H11
Public Const VK_MENU As Integer = &H12
Public Const VK_PAUSE As Integer = &H13
Public Const VK_CAPITAL As Integer = &H14


Public Const VK_ESCAPE As Integer = &H1B


Public Const VK_SPACE As Integer = &H20
Public Const VK_PRIOR As Integer = &H21
Public Const VK_NEXT As Integer = &H22
Public Const VK_END As Integer = &H23
Public Const VK_HOME As Integer = &H24
Public Const VK_LEFT As Integer = &H25
Public Const VK_UP As Integer = &H26
Public Const VK_RIGHT As Integer = &H27
Public Const VK_DOWN As Integer = &H28
Public Const VK_SELECT As Integer = &H29
Public Const VK_PRINT As Integer = &H2A
Public Const VK_EXECUTE As Integer = &H2B
Public Const VK_SNAPSHOT As Integer = &H2C
Public Const VK_INSERT As Integer = &H2D
Public Const VK_DELETE As Integer = &H2E
Public Const VK_HELP As Integer = &H2F


' VK_A thru VK_Z are the same as their ASCII equivalents: 'A' thru 'Z'
' VK_0 thru VK_9 are the same as their ASCII equivalents: '0' thru '9'


Public Const VK_NUMPAD0 As Integer = &H60
Public Const VK_NUMPAD1 As Integer = &H61
Public Const VK_NUMPAD2 As Integer = &H62
Public Const VK_NUMPAD3 As Integer = &H63
Public Const VK_NUMPAD4 As Integer = &H64
Public Const VK_NUMPAD5 As Integer = &H65
Public Const VK_NUMPAD6 As Integer = &H66
Public Const VK_NUMPAD7 As Integer = &H67
Public Const VK_NUMPAD8 As Integer = &H68
Public Const VK_NUMPAD9 As Integer = &H69
Public Const VK_MULTIPLY As Integer = &H6A
Public Const VK_ADD As Integer = &H6B
Public Const VK_SEPARATOR As Integer = &H6C
Public Const VK_SUBTRACT As Integer = &H6D
Public Const VK_DECIMAL As Integer = &H6E
Public Const VK_DIVIDE As Integer = &H6F
Public Const VK_F1 As Integer = &H70
Public Const VK_F2 As Integer = &H71
Public Const VK_F3 As Integer = &H72
Public Const VK_F4 As Integer = &H73
Public Const VK_F5 As Integer = &H74
Public Const VK_F6 As Integer = &H75
Public Const VK_F7 As Integer = &H76
Public Const VK_F8 As Integer = &H77
Public Const VK_F9 As Integer = &H78
Public Const VK_F10 As Integer = &H79
Public Const VK_F11 As Integer = &H7A
Public Const VK_F12 As Integer = &H7B
Public Const VK_F13 As Integer = &H7C
Public Const VK_F14 As Integer = &H7D
Public Const VK_F15 As Integer = &H7E
Public Const VK_F16 As Integer = &H7F
Public Const VK_F17 As Integer = &H80
Public Const VK_F18 As Integer = &H81
Public Const VK_F19 As Integer = &H82
Public Const VK_F20 As Integer = &H83
Public Const VK_F21 As Integer = &H84
Public Const VK_F22 As Integer = &H85
Public Const VK_F23 As Integer = &H86
Public Const VK_F24 As Integer = &H87


Public Const VK_NUMLOCK As Integer = &H90
Public Const VK_SCROLL As Integer = &H91


'
' VK_L VK_R - left and right Alt, Ctrl and Shift virtual keys.
' Used only as parameters to GetAsyncKeyState() and GetKeyState().
' No other API or message will distinguish left and right keys in
this
way.
' /
Public Const VK_LSHIFT As Integer = &HA0
Public Const VK_RSHIFT As Integer = &HA1
Public Const VK_LCONTROL As Integer = &HA2
Public Const VK_RCONTROL As Integer = &HA3
Public Const VK_LMENU As Integer = &HA4
Public Const VK_RMENU As Integer = &HA5


Public Const VK_ATTN As Integer = &HF6
Public Const VK_CRSEL As Integer = &HF7
Public Const VK_EXSEL As Integer = &HF8
Public Const VK_EREOF As Integer = &HF9
Public Const VK_PLAY As Integer = &HFA
Public Const VK_ZOOM As Integer = &HFB
Public Const VK_NONAME As Integer = &HFC
Public Const VK_PA1 As Integer = &HFD
Public Const VK_OEM_CLEAR As Integer = &HFE


Public Function funcIsTasteGedrückt(iTastenCode As Integer) As Boolean
If Abs(GetKeyState(iTastenCode) < 0) Then
funcIsTasteGedrückt = True
End If
End Function
' ---------- Ende Modul1 ----------


Hier das Demobeispiel, die Funktion liefert eine Boolean-Wert zurück

Sub Demo()
MsgBox funcIsTasteGedrückt(VK_SHIFT)
End Sub

HTH
 
P

Peter T

Along the lines Helmut suggests -

Public Declare Function GetAsyncKeyState _
Lib "user32" (ByVal vKey As Long) As Integer

Function IsKeyDown(key As Long) As Boolean
If GetAsyncKeyState(key) Then
If GetAsyncKeyState(key) Then
IsKeyDown = True
End If
End If
End Function

Sub test()
Dim bShift As Boolean
Dim bCtrl As Boolean

' hold shift or ctrl or both or neither and run
bShift = IsKeyDown(vbKeyShift)
bCtrl = IsKeyDown(vbKeyControl)

Debug.Print bShift, bCtrl

'If bShift And bCtrl Then
' MsgBox "don't press Shift & Ctrl together"
'ElseIf bShift Then
' MsgBox "Shift code"
'ElseIf bCtrl Then
' MsgBox "Ctrl code"
'Else
' MsgBox "other code"
'End If

End Sub

It might seem odd to test key twice but I've found doing that can't prevent
detecting a false positive, which for some reason can occur (eg,
occasionally first time key is tested just after releasing the key).

Regards,
Peter T
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top