使用 vbAccelerator Win32 Hook 与 VB IDE 一起导致应用程序崩溃

发布于 2024-09-14 08:43:05 字数 988 浏览 2 评论 0原文

我正在开发 VB6 项目,我需要为工具栏控件上的按钮提供键盘快捷键。为了实现这一点,我使用了 vbAccelerator 中的 Win32 Hooks 库。这是我的 IWindowsHook_HookProc 函数,我用它来检索击键&根据按下的快捷键执行操作(Ctrl + N 用于新建,Ctrl + O 用于打开,< kbd>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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

禾厶谷欠 2024-09-21 08:43:10

我找到了自己问题的解决方案,如果处理不仔细,它仍然容易崩溃,但现在我的应用程序实际上响应了我想要的组合键, Ctrl + NCtrl + O 等。
以下是我修正后的代码,据我所知,它工作得很好。如果您发现其中有任何导致我的应用程序崩溃的错误,请提出建议。

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

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
無處可尋 2024-09-21 08:43:09

在 IDE 中使用钩子可能会导致大量崩溃,见鬼,在没有完全理解自己在做什么的情况下使用钩子会导致大量崩溃时期...

马克关于带有显示形式的计时器的说法是正确的,因为挂钩函数应尽快返回(< 50 毫秒),否则您将很快陷入死锁(和崩溃的应用程序)。切勿在 Hook 过程中设置断点,否则您将杀死您的 IDE(可能会崩溃,可能会挂起,可能会出现某种奇怪的状态,即您永远无法留下断点并且无法停止调试)。如果您有大量需要基于按键运行的长时间运行的函数,请设置一堆要在计时器中执行的操作。使用钩子库非常强大,但强大的功能也会带来严重的崩溃......

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...

小镇女孩 2024-09-21 08:43:09

我没有使用该钩子库的经验,但我的猜测是您应该在 HookProc 过程本身中做很少的事情。您将被直接从 Windows API 调用,而不是通过 VB6 运行时。正如您所描述的那样,显示表单会导致所有内容崩溃,我对此并不感到惊讶。 vbAccelerator 网站上是否有关于在 HookProc 中放入哪种代码的建议?顺便说一句,vbAccelerator 是一个很棒的网站。

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文