Oddity with WH_KEYBOARD_LL hook, anyone know why?

Draiko

New member
Joined
Nov 17, 2005
Messages
4
Programming Experience
1-3
[FONT=Verdana, Arial, Helvetica]I have been working a program that uses a keyboard hook to trigger several different actions based on the key that is pressed. The code that I use (simplified and provided below) works perfectly in VB.Net 2003, but in VB.Net 2005 Pro, my keyboardhandle always equals 0, so the hook never gets set. Would anyone know why on the same computer, the same working code in 2003 would not work in 2005? Thanks in advance for any advice you might have.

[/FONT]
VB.NET:
Imports System.Runtime.InteropServices  
Imports System.Reflection  
Imports System.Drawing  
Imports System.Threading  
  
    Public Declare Function UnhookWindowsHookEx Lib "user32" _  
      (ByVal hHook As Integer) As Integer  
  
    Public Declare Function SetWindowsHookEx Lib "user32" _  
      Alias "SetWindowsHookExA" (ByVal idHook As Integer, _  
      ByVal lpfn As KeyboardHookDelegate, ByVal hmod As Integer, _  
      ByVal dwThreadId As Integer) As Integer  
  
    Private Declare Function GetAsyncKeyState Lib "user32" _  
      (ByVal vKey As Integer) As Integer  
  
    Private Declare Function CallNextHookEx Lib "user32" _  
      (ByVal hHook As Integer, _  
      ByVal nCode As Integer, _  
      ByVal wParam As Integer, _  
      ByVal lParam As KBDLLHOOKSTRUCT) As Integer  
  
    Public Structure KBDLLHOOKSTRUCT  
        Public vkCode As Integer  
        Public scanCode As Integer  
        Public flags As Integer  
        Public time As Integer  
        Public dwExtraInfo As Integer  
    End Structure  
  
    ' Low-Level Keyboard Constants  
    Private Const HC_ACTION As Integer = 0  
    Private Const LLKHF_EXTENDED As Integer = &H1  
    Private Const LLKHF_INJECTED As Integer = &H10  
    Private Const LLKHF_ALTDOWN As Integer = &H20  
    Private Const LLKHF_UP As Integer = &H80  
  
    ' Virtual Keys  
    Public Const VK_TAB = &H9  
    Public Const VK_CONTROL = &H11  
    Public Const VK_ESCAPE = &H1B  
    Public Const VK_DELETE = &H2E  
  
    Private Const WH_KEYBOARD_LL As Integer = 13&  
    Public KeyboardHandle As Integer  
  
    Public Function IsHooked( _  
      ByRef Hookstruct As KBDLLHOOKSTRUCT) As Boolean  
  
        Debug.WriteLine("Hookstruct.vkCode: " & Hookstruct.vkCode)  
  
        If (Hookstruct.vkCode = VK_ESCAPE) And _  
          CBool(Hookstruct.flags And _  
            LLKHF_ALTDOWN) Then  
  
            Call HookedState("Alt + Escape blocked")  
            Return True  
        End If  
  
        Return False  
    End Function  
  
    Private Sub HookedState(ByVal Text As String)  
        Debug.WriteLine(Text & " HookedState")  
    End Sub  
  
    Public Function KeyboardCallback(ByVal Code As Integer, _  
      ByVal wParam As Integer, _  
      ByRef lParam As KBDLLHOOKSTRUCT) As Integer  
  
            Debug.WriteLine("Calling IsHooked")  
  
            If (IsHooked(lParam)) Then  
                Return 1  
            End If  
  
        Return CallNextHookEx(KeyboardHandle, _  
          Code, wParam, lParam)  
  
    End Function  
  
  
    Public Delegate Function KeyboardHookDelegate( _  
      ByVal Code As Integer, _  
      ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) _  
                   As Integer  
  
    <MarshalAs(UnmanagedType.FunctionPtr)> Private callback As   
KeyboardHookDelegate  
  
    Public Sub HookKeyboard()  
        callback = New KeyboardHookDelegate(AddressOf KeyboardCallback)  
        KeyboardHandle = SetWindowsHookEx( _  
          WH_KEYBOARD_LL, callback, _  
          Marshal.GetHINSTANCE( _  
          [Assembly].GetExecutingAssembly.GetModules()(0)).ToInt32, 0)  
  
        Call CheckHooked()  
    End Sub  
  
    Public Sub CheckHooked()  
        If (Hooked()) Then  
            Debug.WriteLine("Keyboard hooked CheckHooked")  
        Else  
            Debug.WriteLine("Keyboard hook failed: " & Err.LastDllError)  
        End If  
    End Sub  
  
    Private Function Hooked()  
        Hooked = KeyboardHandle <> 0  
    End Function  
  
    Public Sub UnhookKeyboard()  
        If (Hooked()) Then  
            Call UnhookWindowsHookEx(KeyboardHandle)  
        End If  
    End Sub  
  
  
    Private Sub initLoad(ByVal sender As System.Object, ByVal e As   
System.EventArgs) Handles MyBase.Load  
        Call HookKeyboard()  
    End Sub  
  
    Private Sub closeOnExit(ByVal sender As Object, ByVal e As   
System.ComponentModel.CancelEventArgs) Handles MyBase.Closing  
        Call UnhookKeyboard()  
    End Sub
 
Kind of a fix, but not really...

I did get around this issue, but not in the way that I would have liked. I actually ported my program back to VB.Net 2003 to get the hook to work properly. Luckily, all of my code was compatible (with some minor adjustments) with 2003. It's not a good solution, but it worked in my case.
 
Me too...

I completely agree with you. I would much rather make the complete switch to VS 2005, but I have run across several features (almost all having to do with API's) that no longer seem to work correctly, so I will continue to use 2003 for those projects, and use 2005 for all my new ones that don't use API calls.
 
I dont know if this applies to all instances but running an app through VS2005 prevents you from hooking some things. If you run that same app outisde VS2005 (by executing the executable itself) the hook works fine. *shrugs* It is mentioned in another thread here about keyboard hooks.
 
Back
Top