powered by simpleCommunicator - 2.0.54     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / VB.net keyboard hook зависает
6 сообщений из 6, страница 1 из 1
VB.net keyboard hook зависает
    #38973741
Фотография surbanec
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пытаюсь ловить нажатие клавишь через хуки.
поймав нужное событие выполняется процедура, при этом происходит зависание пк на несколько секунд. думаю что это связано с многократным вызовом процедуры, или не знаю. но это зависание меня не радует.

код класса keyboard hook

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
Imports System.Runtime.InteropServices

Public Class KeyboardHook

    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
    Private Overloads Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal HookProc As KBDLLHookProc, ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer
    End Function
    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
    Private Overloads Shared Function CallNextHookEx(ByVal idHook As Integer, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    End Function
    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
    Private Overloads Shared Function UnhookWindowsHookEx(ByVal idHook As Integer) As Boolean
    End Function

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure KBDLLHOOKSTRUCT
        Public vkCode As UInt32
        Public scanCode As UInt32
        Public flags As KBDLLHOOKSTRUCTFlags
        Public time As UInt32
        Public dwExtraInfo As UIntPtr
    End Structure

    <Flags()> _
    Private Enum KBDLLHOOKSTRUCTFlags As UInt32
        LLKHF_EXTENDED = &H1
        LLKHF_INJECTED = &H10
        LLKHF_ALTDOWN = &H20
        LLKHF_UP = &H80
    End Enum

    Public Shared Event KeyDown(ByVal Key As Keys)
    Public Shared Event KeyUp(ByVal Key As Keys)

    Private Const WH_KEYBOARD_LL As Integer = 13
    Private Const HC_ACTION As Integer = 0
    Private Const WM_KEYDOWN = &H100
    Private Const WM_KEYUP = &H101
    Private Const WM_SYSKEYDOWN = &H104
    Private Const WM_SYSKEYUP = &H105

    Private Delegate Function KBDLLHookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer

    Private KBDLLHookProcDelegate As KBDLLHookProc = New KBDLLHookProc(AddressOf KeyboardProc)
    Private HHookID As IntPtr = IntPtr.Zero
    Public block_hook As Boolean
    Private Function KeyboardProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
        If (nCode = HC_ACTION) Then
            Dim struct As KBDLLHOOKSTRUCT
            Select Case wParam
                Case WM_KEYDOWN, WM_SYSKEYDOWN
                    RaiseEvent KeyDown(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys))
                Case WM_KEYUP, WM_SYSKEYUP
                    RaiseEvent KeyUp(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys))
            End Select
        End If
        Return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam)
    End Function

    Public Sub New()
        HHookID = SetWindowsHookEx(WH_KEYBOARD_LL, KBDLLHookProcDelegate, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
        If HHookID = IntPtr.Zero Then
            Throw New Exception("Could not set keyboard hook")
        End If
    End Sub

    Protected Overrides Sub Finalize()
        If Not HHookID = IntPtr.Zero Then
            UnhookWindowsHookEx(HHookID)
        End If
        MyBase.Finalize()
    End Sub

End Class



ну и в процедуре события

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
 Private Sub kbhook_KeyUp(ByVal Key As System.Windows.Forms.Keys) Handles kbhook.KeyUp

        If is_down = True Then Exit Sub
        If My.Computer.Keyboard.AltKeyDown = True Then
            If My.Computer.Keyboard.CtrlKeyDown = True Then
                If Key = Keys.F7 Then

      'тут типо чтото выполняется. ну пускай просто msgbox
              
               msgbox("привет мопед")


                End If
            End If
        End If


    End Sub




при нажатии клавиш появляется меседж бокс и на пару секунд компьютер зависает

в чем ошибка? и как избавиться от этих весел?


IntroZorn(с)
...
Рейтинг: 0 / 0
VB.net keyboard hook зависает
    #38973900
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
surbanecв чем ошибка? и как избавиться от этих весел?
в использовании .NET в общем, и VB.NET в частности.
...
Рейтинг: 0 / 0
VB.net keyboard hook зависает
    #38973909
Фотография surbanec
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну и что теперь. изучать C и весь проект перешпехивать на другой язык и другую платформу?!. пока этого не особо хочется. конечно VB не особо хорош, но всетаки на NET он стал гараздо комфортным гибким и мощьным. чем старый Бэсик. по идее оптимальным вариантом на с++ печатать. но пока не особо получается изучением языка, в основном изза времени. вот и мучаемся с ВБ. =)

а по теме просто я не знаю, может проще таймер повесить и отлавливать через API состояние клавиш . вроде есть getKeyState или чтото в этом роде(уже забыл давно такого не делал)
...
Рейтинг: 0 / 0
VB.net keyboard hook зависает
    #38973911
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
surbanecпытаюсь ловить нажатие клавишь через хуки.
поймав нужное событие выполняется процедура, при этом происходит зависание пк на несколько секунд. думаю что это связано с многократным вызовом процедуры, или не знаю. но это зависание меня не радует.
Пиши лог того что происходит. Чтобы точно знать что и в какой последовательности отрабатывает.

И второе: обработка события должна быть быстрой, т.к. пока она идет - обработка очереди сообщений окна стоит и ждет, т.е. если долго, то выглядит как будто зависло.
...
Рейтинг: 0 / 0
VB.net keyboard hook зависает
    #38973935
Фотография surbanec
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

попробую лог сделать..

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

я еще пробовал сделать другой вариант, с помощью флагов сделал игнорирование обработки хука ( в классе). тоесть когда запускается моя процедура в классе(keybordhook) там где идет обработка хука и вызов событий игнорируется все это дело, тоеть пропускается. примерно это так выглядит

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
'отрывок из класса
    Private Function KeyboardProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
        If (nCode = HC_ACTION) Then
           If workFlag=false Then
            Dim struct As KBDLLHOOKSTRUCT
            Select Case wParam
                Case WM_KEYDOWN, WM_SYSKEYDOWN
                    RaiseEvent KeyDown(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys))
                Case WM_KEYUP, WM_SYSKEYUP
                    RaiseEvent KeyUp(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys))
            End Select
           End If
        End If
        Return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam)
    End Function



когда вызывается моя процедура, ставлю workFlag=True
думал что поможет... но нифига. такое ощущение что это не многократный вызов процедуры.

щас лог стряпать буду. может видно станет
...
Рейтинг: 0 / 0
VB.net keyboard hook зависает
    #38973997
Фотография VSVLAD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
surbanec,

Зависаний не замечено, также сначала SetWindowsHookEx возвращал 0, потом нашёл на одном из сайтов этот класс, с указанием отключить хост процесс Visual Studio. Можно было бы кстати указать это.
В лог нужно писать, как уже сказали ранее, время и метод когда начинает работу и когда заканчивает.

Для своего проекта у меня есть аналогичный по функциональности класс, попробуй его.
HotKeyClass.vb
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
Option Explicit On

Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Runtime.InteropServices

Public Class HotKeyClass
    Inherits Control

    <DllImport("user32.dll")> _
    Private Shared Function RegisterHotKey(hWnd As IntPtr, id As Integer, fsModifiers As Integer, vk As Integer) As Boolean
    End Function

    <DllImport("user32.dll")> _
    Private Shared Function UnregisterHotKey(hWnd As IntPtr, id As Integer) As Boolean
    End Function

    <DllImport("user32.dll", SetLastError:=True)> _
    Private Shared Sub keybd_event(bVk As Byte, bScan As Byte, dwFlags As UInteger, dwExtraInfo As Integer)
    End Sub

    Public Event HotKeyPressed(Key As Keys, Modifer As HotKeyModifer)

    Private Const KEYEVENTF_KEYUP = &H2
    Private Const WM_HOTKEY = &H312

    Private m_Modifer As Integer
    Private m_Key As Integer
    Private m_Id As Integer

    'Конструктор
    Sub New()
        Me.BackColor = Color.Black
        Me.Visible = False
    End Sub

    'Обработка сообщений
    Protected Overrides Sub WndProc(ByRef m As Message)
        If m.Msg = WM_HOTKEY Then
            'Dim idHotKey As Integer = CInt(m.WParam) 'Получаем идентификатор комбинации
            RaiseEvent HotKeyPressed(m_Key, m_Modifer)
        End If

        MyBase.WndProc(m)
    End Sub

    'Переопределяем, получаем уникальный ID
    Public Overrides Function GetHashCode() As Integer
        Return m_Modifer ^ m_Key ^ Me.Handle.ToInt32()
    End Function

    'Переопределяем, снять регистрацию клавиш
    Protected Overrides Sub Dispose(disposing As Boolean)
        UnregisterHotKey(Me.Handle, Me.GetType().GetHashCode())
        MyBase.Dispose(disposing)
    End Sub

    'Регистрация клавиш
    Public Function Register(Key As Keys, Modifer As HotKeyModifer) As Boolean
        m_Id = Me.GetHashCode()
        m_Modifer = Modifer
        m_Key = Key

        Return RegisterHotKey(Me.Handle, m_Id, m_Modifer, m_Key)
    End Function

    'Снять регистрацию клавиш
    Public Function Unregiser() As Boolean
        Return UnregisterHotKey(Me.Handle, m_Id)
    End Function


    'Для эмуляции нажатия Ctrl + V
    Public Shared Sub EmulateControlV()
        keybd_event(Keys.ControlKey, 0, 0, 0)
        keybd_event(Keys.V, 0,  0, 0)
        keybd_event(Keys.V, 0, KEYEVENTF_KEYUP, 0)
        keybd_event(Keys.ControlKey, 0, KEYEVENTF_KEYUP, 0)
    End Sub

End Class

<Flags> _
Public Enum HotKeyModifer As UInteger
    NO_MODIFICATION = 0
    ALT = 1
    CONTROL = 2
    SHIFT = 4
    WIN = 8
End Enum


Объявляем переменную
Код: vbnet
1.
Private WithEvents HotKeyMonitor As HotKeyClass


Создаём экземпляр и регистрируем клавиши
Код: vbnet
1.
2.
HotKeyMonitor = New HotKeyClass
HotKeyMonitor.Register(Keys.F4, HotKeyModifer.NO_MODIFICATION)


Обрабатываем событие
Код: vbnet
1.
2.
3.
Private Sub HotKeyMonitor_HotkeyPressed(Key As Keys, Modifer As HotKeyModifer) Handles HotKeyMonitor.HotKeyPressed
    ...
End Sub
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / VB.net keyboard hook зависает
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]