Vb6 使用VBAccelerator Win32钩子使应用程序与VB IDE一起崩溃

Vb6 使用VBAccelerator Win32钩子使应用程序与VB IDE一起崩溃,vb6,keyboard-hook,crash,Vb6,Keyboard Hook,Crash,我在VB6项目中工作,我需要为工具栏控件上的按钮提供键盘快捷方式。为了实现这一点,我使用了库中的Win32钩子。这是我的IWindowsHook\u HookProc函数,我使用它来检索按键并根据按下的快捷键执行操作(Ctrl+N表示新建,Ctrl+O表示打开,Ctrl+s表示保存),但我不知道代码有什么问题,导致我的应用程序与VB6 IDE一起崩溃。该函数目前不完整,因为我只是尝试识别Ctrl+N组合键来测试该功能。请帮帮我-| Private Function IWindowsHook_Ho

我在VB6项目中工作,我需要为工具栏控件上的按钮提供键盘快捷方式。为了实现这一点,我使用了库中的Win32钩子。这是我的
IWindowsHook\u HookProc
函数,我使用它来检索按键并根据按下的快捷键执行操作(Ctrl+N表示新建,Ctrl+O表示打开,Ctrl+s表示保存),但我不知道代码有什么问题,导致我的应用程序与VB6 IDE一起崩溃。该函数目前不完整,因为我只是尝试识别Ctrl+N组合键来测试该功能。请帮帮我-|

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

我没有使用hooks库的经验,但我猜您应该在
HookProc
过程本身中做很少的工作。将直接从Windows API而不是通过VB6运行时调用您。正如您所描述的,显示表单会使所有内容崩溃,对此我并不感到惊讶。在vbAccelerator网站上有没有关于将什么类型的代码放入
HookProc
的建议?顺便说一下,vbAccelerator是一个很好的站点


我建议您在某个地方设置一个标志变量,以指示应该显示frmNewReport。您应该有一个
计时器
以短时间间隔运行,例如100毫秒,它检查标志变量:如果设置了标志,则清除标志并显示表格

我没有使用hooks库的经验,但我猜您应该在
HookProc
过程本身中做很少的工作。将直接从Windows API而不是通过VB6运行时调用您。正如您所描述的,显示表单会使所有内容崩溃,对此我并不感到惊讶。在vbAccelerator网站上有没有关于将什么类型的代码放入
HookProc
的建议?顺便说一下,vbAccelerator是一个很好的站点


我建议您在某个地方设置一个标志变量,以指示应该显示frmNewReport。您应该有一个
计时器
以短时间间隔运行,例如100毫秒,它检查标志变量:如果设置了标志,则清除标志并显示表格

在IDE中使用钩子会导致大量崩溃,如果不完全理解您正在做的事情,那么使用钩子会导致大量崩溃


Mark对show表单的计时器的看法是正确的,因为Hook函数应该尽可能快地返回(<50毫秒),否则很快就会导致死锁(以及崩溃的应用程序)。不要在钩子过程中设置断点,否则您将杀死您的IDE(可能会崩溃,可能会挂起,可能会出现一些wierd状态,因为您永远不能离开断点,并且无法停止调试)。如果您有大量长时间运行的函数想要基于按键运行,那么设置一组要在计时器中执行的操作。使用钩子库功能非常强大,但强大的功能会带来巨大的崩溃…

在IDE中使用钩子可能会导致大量崩溃,如果不完全了解您正在做的事情,使用钩子会导致大量崩溃


Mark对show表单的计时器的看法是正确的,因为Hook函数应该尽可能快地返回(<50毫秒),否则很快就会导致死锁(以及崩溃的应用程序)。不要在钩子过程中设置断点,否则您将杀死您的IDE(可能会崩溃,可能会挂起,可能会出现一些wierd状态,因为您永远不能离开断点,并且无法停止调试)。如果您有大量长时间运行的函数想要基于按键运行,那么设置一组要在计时器中执行的操作。使用钩子库非常强大,但强大的功能会带来巨大的崩溃…

我找到了解决我自己问题的方法,如果不小心处理,它仍然容易崩溃,但现在我的应用程序实际上响应了我想要的组合键,Ctrl+N、Ctrl+O等等。 以下是我的修正代码,工作良好,据我所知。如果您发现任何导致我的应用程序崩溃的bug,请务必提出建议

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
Private将函数GetAsyncKeyState Lib“user32”(ByVal vKey长度)声明为整数
私有属性Get CtrlPressed()为布尔值
CtrlPressed=(GetAsyncKeyState(vbKeyControl)0)
端属性
私有函数IWindowsHook_HookProc(ByVal eType作为EHTHookTypeConstants,ByVal nCode作为Long,ByVal wParam作为Long,ByVal lParam作为Long,bConsume作为Boolean)作为Long
如果wParam=vbKeyN,则
如果按CTRL键,则
LoadFormNewReport方法,用于打开子窗体“新建报告”
如果结束
bConsume=True
ElseIf wParam=vbKeyS然后
如果按CTRL键,则
保存新报告的“SaveNewReport”方法
如果结束
bConsume=True
ElseIf wParam=vbKeyF5然后
如果不加压,则
frmSettings.Show“此表单需要以模式显示,但如果尝试这样做,则会使应用程序与VB IDE一起崩溃,其他快捷方式也可以。
bConsume=True
如果结束
如果结束
端函数

我已经找到了自己问题的解决方案,如果不小心处理,它仍然容易崩溃,但现在我的应用程序实际上响应了我想要的组合键,Ctrl+N、Ctrl+O等等。 以下是我的修正代码,工作良好,据我所知。如果您发现任何导致我的应用程序崩溃的bug,请务必提出建议

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
Private将函数GetAsyncKeyState Lib“user32”(ByVal vKey长度)声明为整数
私有属性Get CtrlPressed()为布尔值
CtrlPressed=(GetAsyncKeyState(vbKeyControl)0)
端属性
私有函数IWindowsHook_HookProc(ByVal eType作为EHTHookTypeConstants,ByVal nCode作为Long,ByVal wParam作为Long,ByVal lParam作为Long,bConsume作为Boolean)作为Long
如果wParam=vbKeyN,则
如果按CTRL键,则
LoadFormNewReport方法,用于打开子窗体“新建报告”
如果结束
bConsume=True
ElseIf wParam=vbKeyS然后
如果按CTRL键,则
保存新报告的“SaveNewReport”方法
如果结束
bConsume=True
ElseIf wParam=vbKeyF5