Lack of Information – Programmatically Toggling the LOCK keys from VB.NET
As usual my blog entries arise from questions I’ve looked into for people. Today someone asked me how to toggle the NUMLOCK key from VB.NET. I thought to myself that surely there must be a sample somewhere?
There was none…(at least nothing I could find within 5 minutes searching both our knowledgebase and googling for it.). Astonishing isn’t it!
So, below is a sample that shows you how to toggle the NUMLOCK and CAPSLOCK keys. What I did to get this was I took Q177674 HOWTO: Toggle the NUM LOCK, CAPS LOCK, and SCROLL LOCK Keys, created the VB6 project. I then used the VS.NET 2003 upgrade wizard to convert this project to VB.NET. The KB article only has code to turn on the LOCK keys if they are off so I modified the code to actually toggle the keys. All you have to do is create a new winforms app, add a button to the form and paste the code below into the form’s class.
Of course with the advent of Visual Studio .NET 2005 you can simply use the My classes to access a managed way to do this…it’s much, much simpler. J
' Declare Type for API call:
Private Structure OSVERSIONINFO
Dim dwOSVersionInfoSize As Integer
Dim dwMajorVersion As Integer
Dim dwMinorVersion As Integer
Dim dwBuildNumber As Integer
Dim dwPlatformId As Integer
<VBFixedString(128), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=128)> Public szCSDVersion As String ' Maintenance string for PSS usage
End Structure
' API declarations:
'UPGRADE_WARNING: Structure OSVERSIONINFO may require marshalling attributes to be passed as an argument in this Declare statement. Click for more: 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="vbup1050"'
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (ByRef lpVersionInformation As OSVERSIONINFO) As Integer
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)
Private Declare Function GetKeyboardState Lib "user32" (ByRef pbKeyState As Byte) As Integer
Private Declare Function SetKeyboardState Lib "user32" (ByRef lppbKeyState As Byte) As Integer
' Constant declarations:
Const VK_NUMLOCK As Short = &H90S
Const VK_SCROLL As Short = &H91S
Const VK_CAPITAL As Short = &H14S
Const KEYEVENTF_EXTENDEDKEY As Short = &H1S
Const KEYEVENTF_KEYUP As Short = &H2S
Const VER_PLATFORM_WIN32_NT As Short = 2
Const VER_PLATFORM_WIN32_WINDOWS As Short = 1
Private Sub Button1_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Button1.Click
Dim o As OSVERSIONINFO
Dim NumLockState As Boolean
Dim ScrollLockState As Boolean
Dim CapsLockState As Boolean
o.dwOSVersionInfoSize = Len(o)
GetVersionEx(o)
Dim keys(255) As Byte
GetKeyboardState(keys(0))
' NumLock handling:
NumLockState = keys(VK_NUMLOCK)
If NumLockState <> True Then 'Turn numlock on
If o.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS Then '=== Win95/98
keys(VK_NUMLOCK) = 1
SetKeyboardState(keys(0))
ElseIf o.dwPlatformId = VER_PLATFORM_WIN32_NT Then '=== WinNT
'Simulate Key Press
keybd_event(VK_NUMLOCK, &H45S, KEYEVENTF_EXTENDEDKEY Or 0, 0)
'Simulate Key Release
keybd_event(VK_NUMLOCK, &H45S, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
End If
Else
If o.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS Then '=== Win95/98
keys(VK_NUMLOCK) = 0
SetKeyboardState(keys(0))
ElseIf o.dwPlatformId = VER_PLATFORM_WIN32_NT Then '=== WinNT
'Simulate Key Press
keybd_event(VK_NUMLOCK, &H45S, KEYEVENTF_EXTENDEDKEY Or 0, 0)
'Simulate Key Release
keybd_event(VK_NUMLOCK, &H45S, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
End If
End If
' CapsLock handling:
CapsLockState = keys(VK_CAPITAL)
If CapsLockState <> True Then 'Turn capslock on
If o.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS Then '=== Win95/98
keys(VK_CAPITAL) = 1
SetKeyboardState(keys(0))
ElseIf o.dwPlatformId = VER_PLATFORM_WIN32_NT Then '=== WinNT
'Simulate Key Press
keybd_event(VK_CAPITAL, &H45S, KEYEVENTF_EXTENDEDKEY Or 0, 0)
'Simulate Key Release
keybd_event(VK_CAPITAL, &H45S, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
End If
Else
If o.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS Then '=== Win95/98
keys(VK_CAPITAL) = 0
SetKeyboardState(keys(0))
ElseIf o.dwPlatformId = VER_PLATFORM_WIN32_NT Then '=== WinNT
'Simulate Key Press
keybd_event(VK_CAPITAL, &H45S, KEYEVENTF_EXTENDEDKEY Or 0, 0)
'Simulate Key Release
keybd_event(VK_CAPITAL, &H45S, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
End If
End If
' ScrollLock handling:
ScrollLockState = keys(VK_SCROLL)
If ScrollLockState <> True Then 'Turn Scroll lock on
If o.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS Then '=== Win95/98
keys(VK_SCROLL) = 1
SetKeyboardState(keys(0))
ElseIf o.dwPlatformId = VER_PLATFORM_WIN32_NT Then '=== WinNT
'Simulate Key Press
keybd_event(VK_SCROLL, &H45S, KEYEVENTF_EXTENDEDKEY Or 0, 0)
'Simulate Key Release
keybd_event(VK_SCROLL, &H45S, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
End If
End If
End Sub