Results 1 to 9 of 9

Thread: Key Down Conflict

  1. #1

    Thread Starter
    New Member
    Join Date
    Aug 2006
    Posts
    5

    Key Down Conflict

    Basically I'm registering a hotkey with RegisterHotKey and then trying to make it send a numpad number with keybd_event. My hotkey and the key I'm sending I cant change this is needed for the program I'm makeing. My best guess at the problem is since Alt+Q and Numpad7 are both happening at the same time there is a conflict with it trying to send Alt+Numpad7. If I add a sleep 1000 in there it works fine. However since this is part of the user interface a 1 second delay is unacceptable.

    Please help!!!

    My goal is for Alt+Q (not q) to send Numpad7 (not 7) without a delay (sleep).

    The code below works great however I need it without the sleep delay.

    In Form1
    Code:
    Option Explicit
    
    Private Sub Form_Load()
    Dim Val1 As Boolean
    Val1 = RegisterHotKey(Me.hwnd, 0, MOD_ALT, vbKeyQ)
        If Not Val1 Then
            MsgBox "Could not register hotkey.", vbCritical
        End If
        
        Me.Visible = False
        
        glWinRet = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf CallbackMsgs)
    End Sub
    In a Module
    Code:
    Option Explicit
    
    Public Declare Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
    Public Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
    
    Public Declare Function RegisterHotKey Lib "user32" (ByVal hwnd As Long, ByVal ID As Long, ByVal fsModifiers As Long, ByVal vk As Long) As Long
    Public Declare Function UnregisterHotKey Lib "user32" (ByVal hwnd As Long, ByVal ID As Long) As Long
    
    Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    
    Public Const WM_HOTKEY = &H312
    Public Const GWL_WNDPROC = -4
    Public Const KEYEVENTF_KEYUP As Long = &H2
    Public Const KEYEVENTF_EXTENDEDKEY As Long = &H1
    Public Const VK_MENU = &H12
    Public Const VK_NUMPAD7 = &H67
    Public Const MOD_ALT = &H1
    
    Public glWinRet As Long
    
    
    Public Function CallbackMsgs(ByVal wHwnd As Long, ByVal wmsg As Long, ByVal wp_id As Long, ByVal lp_id As Long) As Long
        If wmsg = WM_HOTKEY Then
            Call DoFunctions(wp_id)
            CallbackMsgs = 1
            Exit Function
        End If
        CallbackMsgs = CallWindowProc(glWinRet, wHwnd, wmsg, wp_id, lp_id)
    End Function
    
    Public Sub DoFunctions(ByVal vKeyID As Byte)
        If vKeyID = 0 Then
            Debug.Print "Pressed Alt+Q Waiting 1 second"
    'Heres the big frickin problem!!!!!
            Sleep 1000
    'Help me get rid of the sleep and still make it work!!!!
            Debug.Print "NumPad7"
            keybd_event VK_NUMPAD7, 0, 0, 0
            keybd_event VK_NUMPAD7, 0, KEYEVENTF_KEYUP, 0
        End If
    End Sub
    This is my first post to this site. I have been working on this problem for 2 weeks. It would mean alot to me if you guys are able to show me how this can be done.

    Please Save Me!!!!

    -Sinaps

  2. #2
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Key Down Conflict

    I'm guessing that the problem occurs because the Alt+Q keys are still pressed when you're trying to send the numpad 7 key. Maybe you should try to first send KEYEVENTF_KEYUP for the pressed keys.

  3. #3

    Thread Starter
    New Member
    Join Date
    Aug 2006
    Posts
    5

    Re: Key Down Conflict

    I thought so to and tried that but it dident work for me. If anyone gets time load up the code and tinker with it if you can actualy get something to work let me know. This problem has been driveing me crazy for a wile now, if you have an awsner please test it and see if you can make it work. I apprciate your time. I may never get this working without the help of this forums users.

  4. #4
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Key Down Conflict

    I've tried a few different things, and the reason your code doesn't work is definitly since Alt+Q is still pressed when you're trying to send the new key. I've managed to get it to work (somewhat) by using a low-level keyboard and an API timer instead of a global shortcut key. It's not perfect but try it out and see if it's enough for you.
    VB Code:
    1. 'Module code
    2. Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" ( _
    3.     ByVal idHook As Long, _
    4.     ByVal lpfn As Long, _
    5.     ByVal hmod As Long, _
    6.     ByVal dwThreadId As Long _
    7. ) As Long
    8.  
    9. Private Declare Function CallNextHookEx Lib "user32" ( _
    10.     ByVal hHook As Long, _
    11.     ByVal nCode As Long, _
    12.     ByVal wParam As Long, _
    13.     ByRef lParam As KBDLLHOOKSTRUCT _
    14. ) As Long
    15.  
    16. Private Declare Function UnhookWindowsHookEx Lib "user32" ( _
    17.     ByVal hHook As Long _
    18. ) As Long
    19.  
    20. Declare Sub keybd_event Lib "user32.dll" ( _
    21.     ByVal bVk As Byte, _
    22.     ByVal bScan As Byte, _
    23.     ByVal dwFlags As Long, _
    24.     ByVal dwExtraInfo As Long _
    25. )
    26.  
    27. Private Declare Function SetTimer Lib "user32.dll" ( _
    28.     ByVal hWnd As Long, _
    29.     ByVal nIDEvent As Long, _
    30.     ByVal uElapse As Long, _
    31.     ByVal lpTimerFunc As Long _
    32. ) As Long
    33.  
    34. Private Declare Function KillTimer Lib "user32.dll" ( _
    35.     ByVal hWnd As Long, _
    36.     ByVal nIDEvent As Long _
    37. ) As Long
    38.  
    39. Private Type KBDLLHOOKSTRUCT
    40.     vkCode As Long
    41.     scanCode As Long
    42.     flags As Long
    43.     time As Long
    44.     dwExtraInfo As Long
    45. End Type
    46.  
    47. Private Const HC_ACTION = 0
    48. Private Const WH_KEYBOARD_LL = 13&
    49. Private Const LLKHF_ALTDOWN As Long = 16&
    50. Private Const LLKHF_EXTENDED As Long = 1&
    51. Private Const LLKHF_UP As Long = 128&
    52. Private Const KEYEVENTF_KEYUP As Long = &H2
    53. Private Const VK_NUMPAD7 = &H67
    54. Private Const VK_ALT = &H12
    55.  
    56. Private hKeyb As Long
    57. Private blnExit As Boolean
    58.  
    59. Private Function KeybCallback(ByVal Code As Long, ByVal wParam As Long, lParam As KBDLLHOOKSTRUCT) As Long
    60.     If blnExit Then
    61.         KeybCallback = 1
    62.         Exit Function
    63.     End If
    64.     If (Code = HC_ACTION) Then
    65.         If (lParam.vkCode = vbKeyQ) And (lParam.flags And LLKHF_ALTDOWN = LLKHF_ALTDOWN) Then
    66.             If lParam.flags And LLKHF_UP = LLKHF_UP Then
    67.                 Call SetTimer(0, 1, 1, AddressOf TimerProc)
    68.                 blnExit = True
    69.                 KeybCallback = 1
    70.                 Exit Function
    71.             End If
    72.         End If
    73.     End If
    74.     KeybCallback = CallNextHookEx(hKeyb, Code, wParam, lParam)
    75. End Function
    76.  
    77. Private Sub TimerProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal dwTime As Long)
    78.     keybd_event vbKeyQ, 0, KEYEVENTF_KEYUP, 0
    79.     keybd_event VK_ALT, 0, KEYEVENTF_KEYUP, 0
    80.     blnExit = False
    81.     keybd_event VK_NUMPAD7, 0, 0, 0
    82.     keybd_event VK_NUMPAD7, 0, KEYEVENTF_KEYUP, 0
    83.     keybd_event VK_ALT, 0, 0, 0
    84.     KillTimer hWnd, idEvent
    85. End Sub
    86.  
    87. Public Sub HookKeyboard()
    88.     UnhookKeyboard
    89.     hKeyb = SetWindowsHookEx(WH_KEYBOARD_LL, AddressOf KeybCallback, App.hInstance, 0&)
    90. End Sub
    91.  
    92. Public Sub UnhookKeyboard()
    93.     If hKeyb <> 0 Then
    94.         Call UnhookWindowsHookEx(hKeyb)
    95.         hKeyb = 0
    96.     End If
    97. End Sub
    Change your Form code to call the HookKeyboard sub instead of the call to RegisterHotkey. Also make sure you call the UnhookKeyboard sub before your Form is unloaded.
    Last edited by Joacim Andersson; Aug 21st, 2006 at 10:08 AM.

  5. #5

    Thread Starter
    New Member
    Join Date
    Aug 2006
    Posts
    5

    Re: Key Down Conflict

    Thanks for your help.

    Unfortunatly this code seems to work similarly poorly to mine. Both have the problem that you cant hold ALT and press Q twice or 3 times and send numpad7 at the same speed. This is now bothering me more because it seems so hard to get right. But yet I know people do! I have this same question posted on another programing related forum and no one seems to have a quick and easy fix. Thank for your help Joacim. I hope we figure this out!

  6. #6
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Key Down Conflict

    Hmmm... I don't have a problem with using my code and pressing Ctrl+Q more then once...

  7. #7

    Thread Starter
    New Member
    Join Date
    Aug 2006
    Posts
    5

    Re: Key Down Conflict

    Perhaps I'm doing something wrong could you post what you have in form1 to rule out any mistake I could be making. I'm very new to vb, and likely misunderstood your instructions. Making it idiot proof would be very helpful.

  8. #8
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Key Down Conflict

    I simply have this in my Form.
    VB Code:
    1. Private Sub Form_Load()
    2.     HookKeyboard
    3. End Sub
    4.  
    5. Private Sub Form_Unload(Cancel As Integer)
    6.     UnhookKeyboard
    7. End Sub
    I also had a TextBox on the Form to test the code. When the textbox had the focus I pressed Alt+Q and it would type a 7 in the textbox, just as expected.

  9. #9

    Thread Starter
    New Member
    Join Date
    Aug 2006
    Posts
    5

    Re: Key Down Conflict

    Thats exactly what I have, if I hit alt+q fast enough it works but holding alt and pressing q dosent send anything. Also if the windo does not have focus i.e. in notepad it dosent work. What could I be missing?

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