2008-10-14

Simulate key strokes like CAPS LOCK, NUM LOCK, SCROLL LOCK, etc

There are situation when we need to turn on/off or check the status of CAPS LOCK, NUM LOCK and SCROLL LOCK keys. The simplest way to accomplish this is to use SendKeys, but it has it's own disadvantages. So I am using keybd_event API instead. If offers two advantages over SendKeys. First, it doesn't cause the NUM LOCK light to flicker unless you specifically press the NUM LOCK key. Secondly, it's possible to press and hold a key. So it does like this:
Imports System.Runtime.InteropServices

Public Class Form2

Private Declare Sub keybd_event Lib "user32" ( _
ByVal bVk As Byte, _
ByVal bScan As Byte, _
ByVal dwFlags As Integer, _
ByVal dwExtraInfo As Integer _
)

Private Const VK_CAPITAL As Integer = 20
Private Const VK_NUMLOCK As Integer = 144
Private Const VK_SCROLL As Integer = 145
Private Const KEYEVENTF_EXTENDEDKEY As Integer = &H1
Private Const KEYEVENTF_KEYUP As Integer = &H2

Private Sub Button1_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs _
) Handles Button1.Click

' Toggle CapsLock

' Simulate the Key Press
keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or 0, 0)

' Simulate the Key Release
keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
End Sub

End Class
To toggle NUM LOCK and SCROLL LOCK keys, you just need to replace VK_CAPITAL with appropriate constant variables of NUM LOCK and SCROLL LOCK keys.

Actually speaking, above code can be used to simulate any key. We just need to replace VK_ constants with the appropriate variables of desired keys.

Here I am listing down the virtual keys standard set for your reference.

VK_LBUTTON = 1
VK_RBUTTON = 2
VK_CANCEL = 3
VK_MBUTTON = 4
VK_BACK = 8
VK_TAB = 9
VK_CLEAR = 12
VK_RETURN = 13
VK_SHIFT = &H10
VK_CONTROL = 17
VK_MENU = 18
VK_PAUSE = 19
VK_CAPITAL = 20
VK_ESCAPE = 27
VK_SPACE = &H20
VK_PRIOR = 33
VK_NEXT = 34
VK_END = 35
VK_HOME = 36
VK_LEFT = 37
VK_UP = 38
VK_RIGHT = 39
VK_DOWN = 40
VK_SELECT = 41
VK_PRINT = 42
VK_EXECUTE = 43
VK_SNAPSHOT = 44
VK_INSERT = 45
VK_DELETE = 46
VK_HELP = 47
VK_LWIN = 91
VK_RWIN = 92
VK_APPS = 93
VK_NUMPAD0 = 96
VK_NUMPAD1 = 97
VK_NUMPAD2 = 98
VK_NUMPAD3 = 99
VK_NUMPAD4 = 100
VK_NUMPAD5 = 101
VK_NUMPAD6 = 102
VK_NUMPAD7 = 103
VK_NUMPAD8 = 104
VK_NUMPAD9 = 105
VK_MULTIPLY = 106
VK_ADD = 107
VK_SEPARATOR = 108
VK_SUBTRACT = 109
VK_DECIMAL = 110
VK_DIVIDE = 111
VK_F1 = 112
VK_F2 = 113
VK_F3 = 114
VK_F4 = 115
VK_F5 = 116
VK_F6 = 117
VK_F7 = 118
VK_F8 = 119
VK_F9 = 120
VK_F10 = 121
VK_F11 = 122
VK_F12 = 123
VK_F13 = 124
VK_F14 = 125
VK_F15 = 126
VK_F16 = 127
VK_F17 = 128
VK_F18 = 129
VK_F19 = 130
VK_F20 = 131
VK_F21 = 132
VK_F22 = 133
VK_F23 = 134
VK_F24 = 135
VK_NUMLOCK = 144
VK_SCROLL = 145
VK_LSHIFT = 160
VK_RSHIFT = 161
VK_LCONTROL = 162
VK_RCONTROL = 163
VK_LMENU = 164
VK_RMENU = 165
VK_PROCESSKEY = 229
VK_ATTN = 246
VK_CRSEL = 247
VK_EXSEL = 248
VK_EREOF = 249
VK_PLAY = 250
VK_ZOOM = 251
VK_NONAME = 252
VK_PA1 = 253
VK_OEM_CLEAR = 254

VK_0 thru VK_9 are the same as ASCII '0' thru '9' (&H30 - &H39)
VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (&H41 - &H5A)

5 comments:

scalpa said...
This comment has been removed by the author.
scalpa said...

hello
How to test if capslock is on and then put it off only in this case?
thanks
pascal

Deepak Sakpal said...

The code that I posted above just toggles the state of CAPS LOCK key i.e. if the CAPS LOCK key ON then the code turns it OFF or if the CAPS LOCK key OFF then code makes it OFF.

If you want to just check the state of the CAPS LOCK then use the following code:

If Control.IsKeyLocked(Keys.CapsLock) Then
MessageBox.Show("Caps Lock is ON")
Else
MessageBox.Show("Caps Lock is OFF")
End If

scalpa said...

Hi again
No I don't want to just check the state of the CAPS.
I would like to turn it off only if it is a this time ON.

Deepak Sakpal said...

OK, in that case this is the code you need:

If Control.IsKeyLocked(Keys.CapsLock) Then

keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or 0, 0)

keybd_event(VK_CAPITAL, &H45, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)

End If