views:

25

answers:

3

Hello everyone,

I'm working on VB6 project where I need to have keyboard short-cuts for Buttons on Toolbar Control. To accomplish this, I have used Win32 Hooks library from vbAccelerator. Here's my IWindowsHook_HookProc function, that I use to retrieve Key strokes & perform action based on pressed short-cut (Ctrl+N for New, Ctrl+O for Open and Ctrl+S for Save) , but the I don't know what's wrong with the code that crashes my application along with VB6 IDE. The function is currently incomplete as I just tried to identify "Ctrl+N" key combination to test this feature. Please help me out.... :-|

Private Function IWindowsHook_HookProc(ByVal eType As EHTHookTypeConstants, ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long, bConsume As Boolean) As Long
If KeyboardlParam(lParam).KeyDown Then
     Select Case True
           Case Me.ActiveControl = Me
                 If wParam = vbKeyControl + vbKeyN Then
                        frmNewReport.show
                        bConsume = True
                 End If
     End Select
End If
+1  A: 

I have no experience with that hooks library, but my guess is that you should do very little in the HookProc procedure itself. You are being called directly from the Windows API, rather than via the VB6 runtime. I'm not surprised that showing forms crashes everything out as you describe. Was there any advice on the vbAccelerator site about what sort of code to put in HookProc? vbAccelerator is an excellent site by the way.

I suggest you just set a flag variable somewhere to indicate that frmNewReport should be shown. You should have a Timer running with a short tick interval, say 100 milliseconds, which checks the flag variable: if the flag is set, clear the flag and show the form.

MarkJ
Thanks for reply, I have download full source from vbAccerator that demonstrates use of Keyboard Hooks, in that project Hooks are demonstrated with the help of standard controls. Eg; A textbox is given on the form, as a normal behavior, pressing a tab after focusing the control will take focus to next control, but with the help of Hook, when Tab is pressed, Text of the textbox is tabbed like any word processor. I used similar logic, but with Toolbar control, and as my main MDI form doesn't need Menu bar, I need to have short-cuts for Toolbar buttons only.
Kush
+2  A: 

Using a hook in the IDE can lead to lots of crashes, heck using a hook without fully understanding what you are doing is going to lead to a lot of crashes period...

Mark is correct about the Timer with the show form, as the Hook function should return as fast possible (< 50 ms) or your will end up with deadlock (and a crashed app) very quickly. Never set a breakpoint inside the Hook procedure, or you will kill your IDE (maybe crash, maybe hung, maybe some wierd state were you can never leave a breakpoint and you can't stop debugging). If you have a ton of long running functions you want to run based on a keypress, then set up a stack of actions to perform in the timer. Using a hook library is very powerful, but with great power comes great crashes...

Kris Erickson
I shall use timer to call HookProc method periodically, but currently my code (HookProc method as shown in my question) is unable to identify any key events, and I can't understand how to get keyboard short-cuts for Toolbar control (The only control I want in my Main MDI From) buttons in a more pragmatic way using Hooks.
Kush
A: 

Hi, I've found a solution to my own question, its still crash-prone if not handled carefully, but now my application actually responds to key combinations that I wanted, Ctrl+N, Ctrl+O, etc. Following is my rectified code that works fine as far as I know. Do suggest if you find any bug in it that lead to crash my application.

Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer

Private Property Get CtrlPressed() As Boolean
   CtrlPressed = (GetAsyncKeyState(vbKeyControl) <> 0)
End Property

Private Function IWindowsHook_HookProc(ByVal eType As EHTHookTypeConstants, ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long, bConsume As Boolean) As Long

If wParam = vbKeyN Then
    If CtrlPressed Then
        LoadFormNewReport 'Method that opens Child Form 'New Report'
    End If
    bConsume = True

ElseIf wParam = vbKeyS Then
    If CtrlPressed Then
        SaveNewReport 'Method that saves new Report
    End If
    bConsume = True

ElseIf wParam = vbKeyF5 Then
    If Not CtrlPressed Then
        frmSettings.Show 'This form needs to be displayed Modally but if tried so then crashes application along with VB  IDE, other short-cuts work fine.
        bConsume = True
    End If

End If

End Function
Kush