Results 1 to 17 of 17

Thread: Keyboard Hook

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2003
    Location
    Greece, Salonica
    Posts
    473

    Post Keyboard Hook

    Hello.

    I was wondering, how can I hook the keyboard and wait for "Enter" key presses?
    The hook must be system wide, not just for my application!

    Also, I need to be able to cancel the "Enter" keypresses.

    Thanks!

  2. #2
    Super Moderator manavo11's Avatar
    Join Date
    Nov 2002
    Location
    Around the corner from si_the_geek
    Posts
    7,171

    Re: Keyboard Hook

    Have a look at this : http://www.vbaccelerator.com/home/VB...ks/article.asp

    I don't know if you can cancel the keypress but it's a start


    Has someone helped you? Then you can Rate their helpful post.

  3. #3
    Old Member moeur's Avatar
    Join Date
    Nov 2004
    Location
    Wait'n for Free Stuff
    Posts
    2,712

    Re: Keyboard Hook

    Here is an example of discarding the return key with a system-wide low level keyboard hook.
    Note, system-wide hooks are, in general, not a good idea because they can slow down your system if not properly used.
    in a module
    VB Code:
    1. Option Explicit
    2.  
    3. Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" ( _
    4.     ByVal idHook As Long, _
    5.     ByVal lpfn As Long, _
    6.     ByVal hmod As Long, _
    7.     ByVal dwThreadId As Long _
    8. ) As Long
    9.  
    10. Private Declare Function UnhookWindowsHookEx Lib "user32" ( _
    11.     ByVal hHook As Long _
    12. ) As Long
    13.  
    14. Private Declare Function CallNextHookEx Lib "user32" ( _
    15.     ByVal hHook As Long, _
    16.     ByVal ncode As Long, _
    17.     ByVal wParam As Long, _
    18.     lParam As Any _
    19. ) As Long
    20.  
    21. Public Const WH_KEYBOARD_LL = 13
    22. Private Const HC_ACTION = 0
    23. Private Const HC_NOREMOVE = 3
    24.  
    25. Public Type KBDLLHOOKSTRUCT
    26.     vkCode As Long
    27.     scanCode As Long
    28.     flags As Long
    29.     time As Long
    30.     dwExtraInfo As Long
    31. End Type
    32.  
    33. Private hHook As Long
    34. Public IsHooked As Boolean
    35.  
    36. Public Sub SetKeyboardHook()
    37.     If IsHooked Then
    38.         MsgBox "Don't hook WH_KEYBOARD_LL twice or you will be unable to unhook it."
    39.     Else
    40.         hHook = SetWindowsHookEx(WH_KEYBOARD_LL, AddressOf LowLevelKeyboardProc, App.hInstance, 0)
    41.         IsHooked = True
    42.     End If
    43. End Sub
    44.  
    45. Public Sub RemoveKeyboardHook()
    46.     UnhookWindowsHookEx hHook
    47.     IsHooked = False
    48. End Sub
    49.  
    50. Public Function LowLevelKeyboardProc(ByVal uCode As Long, ByVal wParam As Long, lParam As KBDLLHOOKSTRUCT) As Long
    51.    
    52.     If uCode >= 0 Then
    53.         Select Case uCode
    54.             Case HC_ACTION
    55.             'Debug.Print Hex(lParam.vkCode)
    56.                 'If a RETURN key is pulled from the queue then discard it.
    57.                 If lParam.vkCode = &HD Then
    58.                     LowLevelKeyboardProc = 1
    59.                     Exit Function
    60.                 End If
    61.  
    62.             Case HC_NOREMOVE
    63.                 'The message has not been removed from the message queue
    64.         End Select
    65.     End If
    66.        
    67.     LowLevelKeyboardProc = CallNextHookEx(hHook, uCode, wParam, lParam)
    68. End Function

    In your form
    VB Code:
    1. Option Explicit
    2.  
    3. Private Sub Command1_Click()
    4.     SetKeyboardHook
    5. End Sub
    6.  
    7. Private Sub Form_Unload(Cancel As Integer)
    8.     RemoveKeyboardHook
    9. End Sub

  4. #4
    Addicted Member
    Join Date
    Jul 2006
    Location
    Adelaide, Australia
    Posts
    204

    Re: Keyboard Hook

    i want to get a lowlevel hook of another program (Counter-Strike actually) so under certain conditions keypresses get detected by my program and not allowed to pass to CS, but im not sure how to get the "hInstance" of Counter-Strike.

    Is "hInstance" the same as hwnd? or is there some other identifier i need?

  5. #5

  6. #6
    Addicted Member
    Join Date
    Jul 2006
    Location
    Adelaide, Australia
    Posts
    204

    Re: Keyboard Hook

    The admin (one of my friends) keeps reading the "team_say" messages and so he knows what we are doing, so im making a chat program that ill give to my other friends so we can talk and he cant read what we are saying.

  7. #7
    Oi, fat-rag! bushmobile's Avatar
    Join Date
    Mar 2004
    Location
    on the poop deck
    Posts
    5,592

    Re: Keyboard Hook

    just use the system-wide hook in post #3.

    just make sure you turn it on before playing and off after playing.

  8. #8
    Addicted Member
    Join Date
    Jul 2006
    Location
    Adelaide, Australia
    Posts
    204

    Re: Keyboard Hook

    Well, thats what i setup (because i couldnt get low-level hooking to work), but then i couldnt find anything that will block the keystrokes from being picked up by CS.

    Any ideas?
    Last edited by Macka007; Jul 14th, 2006 at 09:04 AM.

  9. #9
    Oi, fat-rag! bushmobile's Avatar
    Join Date
    Mar 2004
    Location
    on the poop deck
    Posts
    5,592

    Re: Keyboard Hook

    what do you mean you could find anything that will block the keystrokes from being picked up by CS.

    I used the hook above, changed this line:
    VB Code:
    1. If lParam.vkCode = [B]vbKeyA [/B]Then
    and not able to press the A key when I tried to change my name in CS:S (wasn't able to test it in a game cos it failed to load - but i think that's just my computer not being able to handle it)

    what's happening in your case?

  10. #10
    Addicted Member
    Join Date
    Jul 2006
    Location
    Adelaide, Australia
    Posts
    204

    Talking Re: Keyboard Hook

    I Should have read through the code properly, i failed to notice the hook is only set by
    VB Code:
    1. Command1_Click()


    Thanks for your help, it works really well now that i know how to initialize the hook

  11. #11
    Addicted Member
    Join Date
    Jul 2006
    Location
    Adelaide, Australia
    Posts
    204

    Re: Keyboard Hook

    Ok, it doesnt work as well as it should. I intergrated the Key Hook into my chat program.

    To activate the hook you press ALT+Z, that does the following procedure.
    When you press the Return key it Unhooks and the CS continues to work normally.

    The first time it is activated it works fine, the second time however it allows keys to pass to CS and then CS starts getting erratic behavior and doesnt respond properly to key strokes (its hard to describe the symptoms as they seem to change each time).

    Just thought of something.... i could keep the hook active but bypass the filtering and cancellation routines unless ALT+Z is pressed...
    Might work, Ill keep you posted.

    VB Code:
    1. 'Some other code to deal with shortcuts
    2.  
    3.             If Message.wParam = &HBFF1& Then
    4.                 SetKeyboardHook
    5.                 frmChatInjection.Shape2.BackStyle = 0
    6.                 MakeTransparent frmChatInjection
    7.             End If
    8.  
    9. 'Some other code to deal with shortcuts
    10.  
    11. '***********************************************
    12. '*********** Module to do with Hooks*****************
    13. '***********************************************
    14.  
    15. Option Explicit
    16.  
    17. Private Declare Function SetWindowsHookEx Lib "user32" _
    18. Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, _
    19.  ByVal hmod As Long, ByVal dwThreadId As Long) As Long
    20.  
    21. Private Declare Function UnhookWindowsHookEx Lib "user32" _
    22. (ByVal hHook As Long) As Long
    23.  
    24. Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _
    25. ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
    26.  
    27. Public Const WH_KEYBOARD_LL = 13
    28. Private Const HC_ACTION = 0
    29. Private Const HC_NOREMOVE = 3
    30.  
    31. Public Type KBDLLHOOKSTRUCT
    32.     vkCode As Long
    33.     scanCode As Long
    34.     flags As Long
    35.     time As Long
    36.     dwExtraInfo As Long
    37. End Type
    38.  
    39. Const SW_SHOWNORMAL = 1
    40. Private hHook As Long
    41. Public IsHooked As Boolean
    42.  
    43. Public Sub SetKeyboardHook()
    44.     ShowWindow frmChatInjection.Hwndno, SW_SHOWNORMAL
    45.     If IsHooked = False Then
    46.         hHook = SetWindowsHookEx(WH_KEYBOARD_LL, AddressOf LowLevelKeyboardProc, App.hInstance, 0)
    47.         IsHooked = True
    48.     End If
    49. End Sub
    50.  
    51. Public Sub RemoveKeyboardHook()
    52.    
    53.    ret = (UnhookWindowsHookEx(hHook))
    54.     IsHooked = False
    55. End Sub
    56.  
    57. Public Function LowLevelKeyboardProc(ByVal uCode As Long, ByVal wParam As Long, lParam As KBDLLHOOKSTRUCT) As Long
    58. Dim Cnt As Integer
    59. Static Counter As Integer
    60.  
    61.     If uCode >= 0 Then
    62.         Select Case uCode
    63.             Case HC_ACTION
    64.             'Debug.Print Hex(lParam.vkCode)
    65.                 'If a RETURN key is pulled from the queue then discard it.
    66.                 Counter = Counter + 1
    67.                 If Counter = 2 Then
    68.                     Counter = 0
    69.                     lParam.vkCode = lParam.vkCode
    70.                     GoTo FilterKeyUp
    71.                 End If
    72.                 Cnt = lParam.vkCode
    73.                     If lParam.vkCode = lParam.vkCode Then
    74.                         FilterKeys (Cnt)
    75.                         LowLevelKeyboardProc = 1
    76.                         Exit Function
    77.                     End If
    78.  
    79.             Case HC_NOREMOVE
    80.                 'The message has not been removed from the message queue
    81.         End Select
    82.     End If
    83. FilterKeyUp:
    84.     LowLevelKeyboardProc = CallNextHookEx(hHook, uCode, wParam, lParam)
    85. End Function
    86.  
    87. Public Function FilterKeys(ByVal Cnt As Integer)
    88. If Cnt = 13 Then
    89.     DoEvents
    90.     frmChatInjection.Text2.SelStart = Len(frmChatInjection.Text2.Text)
    91.     frmChatInjection.Text2.Text = frmChatInjection.Text2.Text & vbNewLine & frmChatInjection.Text1.Text
    92.     frmChatInjection.Text2.SelStart = Len(frmChatInjection.Text2.Text)
    93.     frmChatInjection.Text2.Locked = True
    94.     frmChatInjection.Text2.Locked = False
    95.     frmChatInjection.Text1.Text = ""
    96.     frmChatInjection.Text1.Locked = True
    97.     frmChatInjection.Text1.Locked = False
    98.     RemoveKeyboardHook
    99.     DoEvents
    100.     frmChatInjection.Shape2.BackStyle = 1
    101.     MakeTransparent frmChatInjection
    102.     Exit Function
    103. End If
    104. On Error Resume Next
    105. If Cnt = 8 Then
    106.     frmChatInjection.Text1.Text = Left(frmChatInjection.Text1.Text, Len(frmChatInjection.Text1.Text) - 1)
    107.     Exit Function
    108. End If
    109. If Cnt = 162 Then Exit Function
    110. If Cnt = 160 Then Exit Function
    111. If Cnt = 164 Then Exit Function
    112. If Cnt = 9 Then Exit Function
    113. If Cnt = 93 Then Exit Function
    114. If Cnt = 20 Then Exit Function
    115. If Cnt = 32 Then GoTo JumpCaseChange
    116. If Cnt >= 48 And Cnt <= 57 Then GoTo JumpCaseChange
    117. If Not Cnt <= 90 Then Exit Function
    118. If Not Cnt >= 65 Then Exit Function
    119. 'If (GetKeyState(VK_SHIFT) And &HF0000000) = 0 Then
    120. 'Change the case from Upper to Lower
    121. Cnt = Cnt + 32
    122.  
    123. JumpCaseChange:
    124. frmChatInjection.Text1.Text = frmChatInjection.Text1.Text & Chr(Cnt)
    125.  
    126. End Function

  12. #12
    Oi, fat-rag! bushmobile's Avatar
    Join Date
    Mar 2004
    Location
    on the poop deck
    Posts
    5,592

    Re: Keyboard Hook

    Quote Originally Posted by Macka007
    Just thought of something.... i could keep the hook active but bypass the filtering and cancellation routines unless ALT+Z is pressed...
    that was my initial thought. Try something like the below.

    When the form loads you can type normally into textbox. Press Alt+T and then anything you type won't be passed to the textbox. Press Enter to see what you typed or press Esc to discard it. After pressing Return or Esc you can type in the textbox again:

    VB Code:
    1. Public Function LowLevelKeyboardProc(ByVal uCode As Long, ByVal wParam As Long, lParam As KBDLLHOOKSTRUCT) As Long
    2.    
    3.     If uCode >= 0 And uCode = HC_ACTION Then
    4.         Select Case lParam.vkCode
    5.             Case &HA4
    6.                 If wParam = WM_KEYUP And bLog Then
    7.                     LowLevelKeyboardProc = CallNextHookEx(hHook, uCode, wParam, lParam)
    8.                     Exit Function
    9.                 End If
    10.             Case &HA0, &HA1 'Shift
    11.                 bShift = wParam = WM_KEYDOWN
    12.             Case vbKeyA To vbKeyZ
    13.                 If bLog Then
    14.                     If wParam = WM_KEYUP Then sText = sText & Chr$(lParam.vkCode + (Not bShift) * -32)
    15.                 Else
    16.                     bLog = (((lParam.flags And LLKHF_ALTDOWN) = LLKHF_ALTDOWN) And (lParam.vkCode = vbKeyT))
    17.                 End If
    18.             Case vbKeySpace
    19.                 sText = sText & Chr$(lParam.vkCode)
    20.             Case vbKeyBack
    21.                 If bLog And wParam = WM_KEYUP Then sText = Left$(sText, Len(sText) - 1)
    22.             Case vbKeyReturn
    23.                 If bLog And wParam = WM_KEYUP Then
    24.                     SendText sText
    25.                     sText = vbNullString
    26.                     bLog = False
    27.                 End If
    28.             Case vbKeyEscape
    29.                 If bLog And wParam = WM_KEYUP Then
    30.                     sText = vbNullString: bLog = False
    31.                     LowLevelKeyboardProc = 1: Exit Function
    32.                 End If
    33.         End Select
    34.         If bLog Then LowLevelKeyboardProc = 1: Exit Function
    35.     End If
    36.        
    37.     LowLevelKeyboardProc = CallNextHookEx(hHook, uCode, wParam, lParam)
    38. End Function
    I've attached an example:

    Attached Files Attached Files

  13. #13
    Addicted Member
    Join Date
    Jul 2006
    Location
    Adelaide, Australia
    Posts
    204

    Re: Keyboard Hook

    That is amazing, how did you know to do it like that?

    Im guessing the .Flags parameter tells you if ctrl, alt, shift are pressed.

    What is the bLog Var for?

    And what is the wParam for?

    i looked in the API guide for wParam and lParam but all it said was

    wParam
    Specifies the wParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain.

    lParam
    Specifies the lParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain.
    This is the code I have been using (its got a couple of patches here and there because I was trying to get capitals and '!' through ')' to work, but now I have decided they are not as important.

    To run the code you may need Microsoft Direct Text-To-Speech and a L&H TTS engine installed.
    Attached Files Attached Files

  14. #14
    Oi, fat-rag! bushmobile's Avatar
    Join Date
    Mar 2004
    Location
    on the poop deck
    Posts
    5,592

    Re: Keyboard Hook

    bLog is just a boolean that distinguishes whether we're recording the text or not.

    for the other questions, take a look at the MSDN articles: LowLevelKeyboardProc Function, KBDLLHOOKSTRUCT Structure

  15. #15
    Addicted Member
    Join Date
    Jul 2006
    Location
    Adelaide, Australia
    Posts
    204

    Re: Keyboard Hook

    The code you used to select case didnt work for me, so i changed it from this:

    VB Code:
    1. Case vbKeyA To vbKeyZ
    2.                 If bLog Then
    3.                     If wParam = WM_KEYUP Then sText = sText & Chr$(lParam.vkCode + (Not bShift) * -32)
    4.                 Else
    5.                     bLog = (((lParam.flags And LLKHF_ALTDOWN) = LLKHF_ALTDOWN) And (lParam.vkCode = vbKeyT))
    6.                 End If

    To This:

    VB Code:
    1. Case vbKeyA To vbKeyZ
    2.                 If bLog Then
    3.                     If wParam = WM_KEYUP Then sText = sText & Chr$((lParam.vkCode + IIf(bShift, 0, 32)))
    4.                 Else
    5.                     bLog = (((lParam.flags And LLKHF_ALTDOWN) = LLKHF_ALTDOWN) And (lParam.vkCode = vbKeyT))
    6.                 End If




    To detect numbers and their corresponding char's i added this code:

    VB Code:
    1. Case vbKey0 To vbKey9
    2.                 If bLog Then
    3.                     If wParam = WM_KEYUP Then
    4.                         If bShift Then
    5.                             If lParam.vkCode = 48 Then Cnt = lParam.vkCode - 7
    6.                             If lParam.vkCode = 49 Then Cnt = lParam.vkCode - 16
    7.                             If lParam.vkCode = 50 Then Cnt = lParam.vkCode + 14
    8.                             If lParam.vkCode = 51 Then Cnt = lParam.vkCode - 16
    9.                             If lParam.vkCode = 52 Then Cnt = lParam.vkCode - 16
    10.                             If lParam.vkCode = 53 Then Cnt = lParam.vkCode - 16
    11.                             If lParam.vkCode = 54 Then Cnt = lParam.vkCode + 40
    12.                             If lParam.vkCode = 55 Then Cnt = lParam.vkCode - 17
    13.                             If lParam.vkCode = 56 Then Cnt = lParam.vkCode - 14
    14.                             If lParam.vkCode = 57 Then Cnt = lParam.vkCode - 17
    15.                             sText = sText & Chr$(Cnt)
    16.                         Else
    17.                             If wParam = WM_KEYUP Then sText = sText & Chr$(lParam.vkCode)
    18.                         End If
    19.                     End If
    20.                 End If
    Last edited by Macka007; Jul 16th, 2006 at 08:01 AM.

  16. #16
    Oi, fat-rag! bushmobile's Avatar
    Join Date
    Mar 2004
    Location
    on the poop deck
    Posts
    5,592

    Re: Keyboard Hook

    hmmm, strange.

    (Not bShift) * -32 and IIf(bShift, 0, 32) should have the same outcome. Does my example project work correctly for you (it does for me).

    anyhow, be aware that using IIf is significantly slower than using the If Then construct, and since speed is important here - if you can't get the method i suggested to work then you should use an If...Then block.

    Regarding your number coding you have to think about how many operations you're performing each time. Let's take an example - say the lParam.vkCode is for vbKey0.

    your code matches on the first line after "If bShift Then", but it then still has to check for the other 9 numbers - all of those operations are wasting time. Also if there is a match then you know Cnt has an absolute value it's being assigned, yet for each one you're performing a unnecessary operation:
    VB Code:
    1. Case vbKey0 To vbKey9
    2.                 If bLog Then
    3.                     If wParam = WM_KEYUP Then
    4.                         If bShift Then
    5.                             Select Case lParam.vkCode
    6.                                 Case vbKey0
    7.                                     cnt = 41
    8.                                 Case vbKey1, vbKey3 To vbKey5
    9.                                     cnt = lParam.vkCode - 16
    10.                                 Case vbKey2
    11.                                     cnt = 64
    12.                                 Case vbKey6
    13.                                     cnt = 94
    14.                                 Case vbKey7, vbKey9
    15.                                     cnt = lParam.vkCode - 17
    16.                                 Case vbKey8
    17.                                     cnt = 42
    18.                             End Select
    19.                             sText = sText & Chr$(cnt)
    20.                         Else
    21.                             If wParam = WM_KEYUP Then sText = sText & Chr$(lParam.vkCode)
    22.                         End If
    23.                     End If
    24.                 End If
    I make no guarentees those numbers are correct!

  17. #17
    New Member
    Join Date
    Dec 2011
    Posts
    1

    Arrow Re: Keyboard Hook

    Contrary to what the script says, if you hook it twice. It only hooks it until Windows restarts, otherwise it stays hooked even after application termination.

    It isn't writing any settings, it's just hooking that keystroke, thus it is only a change of a low-level setting without saving.

    Also, I have a question regarding more advanced key hooking.

    I'm trying to make a password application that runs through svchost.exe as a secondary to Windows logon. Requires the user to use Safe-Mode to bypass it, but using Safe-Mode will prevent any third party software from initializing which in turn will make the system more secure as I have the hidden Administrator account disabled and the guest account disabled as well.

    By making a full-screened application that key hooks the following:
    Ctrl + Alt + Del
    Ctrl + Shift + Esc
    Alt + F4
    Alt + Tab
    Ctrl + Esc
    Alt + Esc
    Left Win Key + D
    Left Win Key + E
    Right Win Key + D
    Right Win Key + E
    Left Win Key
    Right Win Key
    Open Context Menu Key
    Alt Tab (Lock) Key (AKA Window Panes Key)



    Edit:

    Sorry for reviving an ancient thread, but this could be elaborated on further.
    Last edited by Aleoss; Dec 6th, 2011 at 12:03 AM. Reason: Editing reason described in post.

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