Most of time KeyPress or KeyDown events of VB will be fine for your application requirement but what if you want to process the same event even your application is minimized or is not active or amy be you want to block certain key combination system wide.... This article will show you how to do that using SetWindowsHookEx API. You can hook keyboard related events globally by calling SetWindowsHookEx api. SetWindowsHookEx requires Keyboard Handler as a parameter. System will call this keyboard handler function every time when keyboard is pressed and here is your chance to process that keystrock or pass to system for default processing. Here is basic code inside keyboard handler |
Ok now lets see the actual implementation of the code
Step-By-Step Example - Create a standard exe project - Add one ListBox and 2 command button controls on the form1 - Add one module to the project - Add the following code in form1
Form1.frm |
Click here to copy the following block | Private Sub Command1_Click() m_hDllKbdHook = HookKeyboard If m_hDllKbdHook <> 0 Then Command1.Enabled = False Command2.Enabled = True Else MsgBox "Failed to install low-level keyboard hook - " & Err.LastDllError End If End Sub
Private Sub Command2_Click() If m_hDllKbdHook <> 0 Then Command1.Enabled = True Command2.Enabled = False UnHookKeyboard End If End Sub
Private Sub Form_Load() Command1.Caption = "Disable Keys" Command2.Caption = "Enable Keys" Command2.Enabled = False End Sub
Private Sub Form_Unload(Cancel As Integer) If m_hDllKbdHook <> 0 Then UnHookKeyboard End If End Sub |
- Add the following code in module1
Module1.bas |
Click here to copy the following block | Option Explicit Private Const WH_KEYBOARD_LL = 13& Private Const HC_ACTION = 0& Private Const LLKHF_EXTENDED = &H1& Private Const LLKHF_INJECTED = &H10& Private Const LLKHF_ALTDOWN = &H20& Private Const LLKHF_UP = &H80&
Public Const WM_KEYDOWN = &H100 Public Const WM_KEYUP = &H101 Public Const WM_SYSKEYDOWN = &H104 Public Const WM_SYSKEYUP = &H105
Public Const VK_CAPITAL = &H14 Public Const VK_NUMLOCK = &H90 Public Const VK_SCROLL = &H91 Public Const VK_USED = VK_SCROLL Public Const VK_RIGHT = &H27 Public Const VK_LEFT = &H25 Public Const VK_RSHIFT = &HA1 Public Const VK_TAB = &H9 Public Const VK_CONTROL = &H11 Public Const VK_ESCAPE = &H1B Public Const VK_DELETE = &H2E
Private Type KBDLLHOOKSTRUCT vkCode As Long scanCode As Long flags As Long time As Long dwExtraInfo As Long End Type
Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal cb As Long) Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Public m_hDllKbdHook As Long
Public Function HookKeyboard() As Long On Error GoTo ErrorHookKeyboard m_hDllKbdHook = SetWindowsHookEx(WH_KEYBOARD_LL, AddressOf LowLevelKeyboardProc, App.hInstance, 0&) HookKeyboard = m_hDllKbdHook Exit Function ErrorHookKeyboard: MsgBox Err & ":Error in call to HookKeyboard()." _ & vbCrLf & vbCrLf & "Error Description: " & Err.Description, vbCritical, "Warning" Exit Function End Function
Public Sub UnHookKeyboard() On Error GoTo ErrorUnHookKeyboard UnhookWindowsHookEx (m_hDllKbdHook) Exit Sub ErrorUnHookKeyboard: MsgBox Err & ":Error in call to UnHookKeyboard()." _ & vbCrLf & vbCrLf & "Error Description: " & Err.Description, vbCritical, "Warning" Exit Sub End Sub
Public Function LowLevelKeyboardProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Static kbdllhs As KBDLLHOOKSTRUCT
If nCode = HC_ACTION Then Call CopyMemory(kbdllhs, ByVal lParam, Len(kbdllhs)) If (kbdllhs.vkCode = VK_RIGHT) And CBool(GetAsyncKeyState(VK_RSHIFT) And &H8000) Then Beep LowLevelKeyboardProc = 1 Form1.List1.AddItem "Right Shift + Right Arrow : Blocked", 0 Exit Function End If If (kbdllhs.vkCode = VK_LEFT) And CBool(GetAsyncKeyState(VK_RSHIFT) And &H8000) Then Beep LowLevelKeyboardProc = 1 Form1.List1.AddItem "Right Shift + Left Arrow : Blocked", 0 Exit Function End If If (kbdllhs.vkCode = VK_ESCAPE) And CBool(GetAsyncKeyState(VK_CONTROL) And &H8000) Then Beep LowLevelKeyboardProc = 1 Form1.List1.AddItem "CTL + ESC : Blocked", 0 Exit Function End If If (kbdllhs.vkCode = VK_ESCAPE) And ((kbdllhs.flags And LLKHF_ALTDOWN) <> 0) Then Beep LowLevelKeyboardProc = 1 Form1.List1.AddItem "ALT + ESC : Blocked", 0 Exit Function End If If (kbdllhs.vkCode = VK_TAB) And ((kbdllhs.flags And LLKHF_ALTDOWN) <> 0) Then Beep LowLevelKeyboardProc = 1 Form1.List1.AddItem "ALT + TAB : Blocked", 0 Exit Function End If
If (kbdllhs.vkCode = VK_CAPITAL) Then Form1.List1.AddItem "CAPSLOCK : Not Blocked", 0 LowLevelKeyboardProc = CallNextHookEx(m_hDllKbdHook, nCode, wParam, lParam) End If
If (kbdllhs.vkCode = VK_SCROLL) Then Form1.List1.AddItem "SCROLL LOCK : Not Blocked", 0 LowLevelKeyboardProc = CallNextHookEx(m_hDllKbdHook, nCode, wParam, lParam) End If Else LowLevelKeyboardProc = CallNextHookEx(m_hDllKbdHook, nCode, wParam, lParam) End If End Function |
- Press F5 to run the project. - Press Disable Keys and try some key strocks like ALT+TAB, CTL+ESC and check the List1 output |
|