При использовании vbAccelarator Win32 Hook вылетает приложение вместе с VB IDE - PullRequest
0 голосов
/ 17 августа 2010

Я работаю над проектом VB6, где мне нужны сочетания клавиш для кнопок на панели управления. Для этого я использовал библиотеку Win32 Hooks из vbAccelerator . Вот моя IWindowsHook_HookProc функция, которую я использую для получения нажатий клавиш и выполнения действий на основе нажатой комбинации клавиш (Ctrl + N для New, Ctrl + O для Open и Ctrl + S для Save), но я не знаю что не так с кодом, который сбивает мое приложение вместе с 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

Ответы [ 3 ]

2 голосов
/ 17 августа 2010

Использование хука в IDE может привести к большому количеству сбоев, но использование хука без полного понимания того, что вы делаете, приведет к большому количеству сбоев ...

Марк верен в отношении таймера с формой показа, так как функция перехвата должна возвращаться как можно быстрее (<50 мс), или вы очень быстро получите тупик (и аварийное приложение). Никогда не устанавливайте точку останова внутри процедуры Hook, иначе вы убьете свою IDE (возможно, сбой, может быть завис, может быть, какое-то странное состояние, когда вы никогда не можете покинуть точку останова и не можете прекратить отладку). Если у вас есть тонна долго выполняющихся функций, которые вы хотите запускать на основе нажатия клавиш, то настройте стек действий для выполнения в таймере. Использование библиотеки ловушек очень мощно, но с большой мощью возникают большие сбои ... </p>

1 голос
/ 17 августа 2010

У меня нет опыта работы с этой библиотекой хуков, но я предполагаю, что вы должны делать очень мало в самой процедуре HookProc. Вам звонят напрямую из Windows API, а не из среды выполнения VB6. Я не удивлен, что показ форм разрушает все, как вы описываете. Был ли какой-нибудь совет на сайте vbAccelerator о том, какой код вставлять в HookProc? Кстати, vbAccelerator - отличный сайт.

Я предлагаю вам просто установить переменную флага где-нибудь, чтобы указать, что frmNewReport должен быть показан. У вас должен быть Timer, работающий с коротким интервалом, скажем, 100 миллисекунд, который проверяет переменную флага: если флаг установлен, снимите флажок и покажите форму.

0 голосов
/ 18 августа 2010

Я нашел решение для своего собственного вопроса, он все еще подвержен сбоям, если не обрабатывается осторожно, но теперь мое приложение фактически реагирует на комбинации клавиш, которые я хотел, Ctrl + N, Ctrl + 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
...