Results 1 to 6 of 6

Thread: keyboard hooking reporting twice!

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Feb 2005
    Posts
    28

    keyboard hooking reporting twice!

    I found some code which shows the keys that have been hooked. I have simplified the code alot from the example, but it seems to report the hooked keys twice and I need this only to happen once. I am have been looking at it for sometime but I can't see what is making it report the hook twice and not once.

    The best way to see this happening is by pressing a key and the output message will be displayed twice.

    I thought perhaps its reporting the keydown and keyup events maybe not sure whats going on.

    Also can anyone explain to me why WH_KEYBOARD_LL has to = 13? How do you know it's 13 and not some other number, can't seem to find a referance to this anywhere.

    VB Code:
    1. Imports System.Runtime.InteropServices
    2. Imports System.Reflection
    3. Imports System.Drawing
    4. Imports System.Threading
    5.  
    6. Module Keyboard
    7.  
    8.     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
    9.     Public Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Integer) As Integer
    10.     Declare Function keybd_event Lib "user32" Alias "keybd_event" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long) As Long
    11.  
    12.     Public Structure keyboardStructure
    13.         Public vkCode As Integer
    14.         Public scanCode As Integer
    15.         Public flags As Integer
    16.         Public time As Integer
    17.         Public dwExtraInfo As Integer
    18.     End Structure
    19.  
    20.  
    21.  
    22.  
    23.  
    24.     Private Const WH_KEYBOARD_LL As Integer = 13&
    25.     Public KeyboardHandle As Integer
    26.  
    27.  
    28.     Public Sub checkKeys(ByRef Hookstruct As keyboardStructure)
    29.  
    30.         Debug.WriteLine("Hookstruct.vkCode: " & Hookstruct.vkCode)
    31.  
    32.         If (Hookstruct.vkCode = 49) Then
    33.             keybd_event(50, 0, 0, 0)
    34.         End If
    35.  
    36.     End Sub
    37.  
    38.  
    39.     Private Sub hookOutput(ByVal Text As String)
    40.         Debug.WriteLine(Text)
    41.  
    42.     End Sub
    43.  
    44.  
    45.     Public Function keyboardCallback(ByVal Code As Integer, ByVal wParam As Integer, ByRef lParam As keyboardStructure) As Integer
    46.         checkKeys(lParam)
    47.     End Function
    48.  
    49.  
    50.     Public Delegate Function KeyboardHookDelegate(ByVal Code As Integer, ByVal wParam As Integer, ByRef lParam As keyboardStructure) As Integer
    51.  
    52.     <MarshalAs(UnmanagedType.FunctionPtr)> Private callback As KeyboardHookDelegate
    53.  
    54.     Public Sub HookKeyboard()
    55.         callback = New KeyboardHookDelegate(AddressOf keyboardCallback)
    56.  
    57.         KeyboardHandle = SetWindowsHookEx(WH_KEYBOARD_LL, callback, Marshal.GetHINSTANCE([Assembly].GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
    58.  
    59.         Call CheckHooked()
    60.     End Sub
    61.  
    62.     Public Sub CheckHooked()
    63.         If (Hooked()) Then
    64.             '' Debug.WriteLine("Keyboard hooked")
    65.             MessageBox.Show("Keyboard hooked")
    66.         Else
    67.             ''Debug.WriteLine("Keyboard hook failed: " & Err.LastDllError)
    68.             MessageBox.Show("Keyboard hook failed: " & Err.LastDllError)
    69.         End If
    70.     End Sub
    71.  
    72.     Private Function Hooked()
    73.         Hooked = KeyboardHandle <> 0
    74.     End Function
    75.  
    76.     Public Sub UnhookKeyboard()
    77.         If (Hooked()) Then
    78.             Call UnhookWindowsHookEx(KeyboardHandle)
    79.         End If
    80.     End Sub
    81.  
    82. End Module

  2. #2
    PowerPoster
    Join Date
    Jul 2002
    Location
    Dublin, Ireland
    Posts
    2,148

    Re: keyboard hooking reporting twice!

    Once for key down, and once for key up again.
    The flags can tell you which is which.

  3. #3
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: keyboard hooking reporting twice!

    WH_KEYBOARD_LL is a constant declared in one of the header files in the Windows API. You have to use a value that matches that constant. It must be 13 because that's what it has been declared as, but it doesn't have to be named WH_KEYBOARD_LL. It's just a convention to name your API constants the same as they have been named in the Windows API header files, but it's just an identifier in your code so you could call it anything you want. As to how you know that it's that value, those who've been programming with the Windows API have posted that it's so on the Web. If you ever need to know the value of a Windows API constant you should just Google it and others will have posted something about it on the Web. There have been some relatively definitive compilations of Windos API documentation made. You could check out gigemboy's signature for some tools. I believe that the API Viewer has all the constant values but I don't know for sure because it refuses to run on my machine.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  4. #4

    Thread Starter
    Junior Member
    Join Date
    Feb 2005
    Posts
    28

    Re: keyboard hooking reporting twice!

    well i got it to only fire once with each key is used. however it will simulate the key press before the actual key press is it possible to get this to be after.

    As far as im aware it intercepts the key being used, checks it, simulates a key, and then continues with the original key press. Is it possible to tell it to continue with the physical key press then do the simulated press?

  5. #5
    New Member
    Join Date
    Aug 2006
    Posts
    6

    Re: keyboard hooking reporting twice!

    What you could do is instead of telling it to continue with the physical keypress, then do what you want, do this:

    Simulate the key they want to press
    Simulate the key you want afterwards
    Then block the physical key by returning 1 inside the keyboard callback function

  6. #6
    New Member
    Join Date
    Aug 2006
    Posts
    6

    Re: keyboard hooking reporting twice!

    Okay i wrote an example of how to do it. I couldn't get my head around it last time :P

    The difficulties with my solution is your own simulated keypresses are hooked. So if they press "1", instead of letting the physical keypress go through then press yours, it's possible to simulate "1" then "2", then block the physical "1" that they pressed. But you're "1" is hooked and will just do the same thing all over again.

    But here's an example that will sort it out.
    First add a variable at the top
    VB Code:
    1. Private Simulating As Boolean = False

    Next change your keyboardCallback function to this
    VB Code:
    1. Public Function keyboardCallback(ByVal Code As Integer, ByVal wParam As Integer, ByRef lParam As keyboardStructure) As Integer
    2.         If checkKeys(lParam) = True Then Return 1
    3.     End Function

    And finally make your checkKeys sub a function that returns a boolean, with the following code inside
    VB Code:
    1. Public Function checkKeys(ByRef Hookstruct As keyboardStructure) As Boolean
    2.  
    3.         If Hookstruct.vkCode = 49 Then
    4.             If Simulating = False And Hookstruct.flags = 0 Then
    5.                 Simulating = True
    6.                 keybd_event(49, 0, 0, 0)
    7.                 keybd_event(50, 0, 0, 0)
    8.                 Simulating = False
    9.             Else
    10.                 Return False
    11.             End If
    12.  
    13.             Return True
    14.         End If
    15.  
    16.         Return False
    17.     End Function

    And that's it so now checkKeys is a function that tells keyboardCallback when to block and when not to.

    I hope that does exactly what you wanted

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width