Oddity with WH_KEYBOARD_LL in VB.NET 2005

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

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.

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
 
Hello "Draiko",

i had the same problem...but after some Experiments i've found a Solution:
If you disable the "Enable the Visual Studio hosting process"-Option in your
Debug-Project-Settings you get some "real" Keyboardhandles from
SetWindowsHookEx. :)

Regards Lars
 
Back
Top