Atlanta Custom Software Development 

 
   Search        Code/Page
 

User Login
Email

Password

 

Forgot the Password?
Services
» Web Development
» Maintenance
» Data Integration/BI
» Information Management
Programming
  Database
Automation
OS/Networking
Graphics
Links
Tools
» Regular Expr Tester
» Free Tools


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

Click here to copy the following block
Public Function LowLevelKeyboardProc(...)
   If (Key is to be blocked or processed by your application) Then
       LowLevelKeyboardProc=1 '//Let your application to handle
   Else
       LowLevelKeyboardProc=CallNextHookEx(...) '//Let OS to handle
   End If
End Function

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()
  'set a keyboard hook
  m_hDllKbdHook = HookKeyboard
  If m_hDllKbdHook <> 0 Then
    'MsgBox "Hooked"
    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
    'MsgBox "UnHooked"
    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
    'MsgBox "UnHooked"
    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
'
'Note: If you want to trap keystrock then return 1 and dont call CallNextHookEx
'
Public Function LowLevelKeyboardProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  Static kbdllhs As KBDLLHOOKSTRUCT

  'When the HC_ACTION msg is received, the value from lParam is copied into a KBDLLHOOKSTRUCT type
  If nCode = HC_ACTION Then
    Call CopyMemory(kbdllhs, ByVal lParam, Len(kbdllhs))
    'Right Shift + Right Arrow
    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
    'Right Shift + Left Arrow
    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
    'CTL + ESC
    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
    'ALT + ESC
    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
    'ALT + TAB
    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 we dont block then must goto CallNextHookEx for further processing by OS
    If (kbdllhs.vkCode = VK_CAPITAL) Then
      Form1.List1.AddItem "CAPSLOCK : Not Blocked", 0
      LowLevelKeyboardProc = CallNextHookEx(m_hDllKbdHook, nCode, wParam, lParam)
    End If

    '//If we dont block then must goto CallNextHookEx for further processing by OS
    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


Submitted By : Nayan Patel  (Member Since : 5/26/2004 12:23:06 PM)

Job Description : He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting.
View all (893) submissions by this author  (Birth Date : 7/14/1981 )


Home   |  Comment   |  Contact Us   |  Privacy Policy   |  Terms & Conditions   |  BlogsZappySys

© 2008 BinaryWorld LLC. All rights reserved.