Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Помогите с ошибкой в коде...

81K
11 мая 2012 года
merkurj
7 / / 11.05.2012
Ребят, помогите а...
При нажатии кливиши "Тильда"
Все идет отлично до Воспроизведения клавиш Ctrl + V:


 
Код:
keybd_event(8, 0, 0, 0)
                keybd_event(&H11, 86, 0, 0)
почему-то проискодит "Зажим" клавиши Ctrl а не ее однократное нажатие...
Пробовал делать дубль этого кода, думал может как включает - так и отключать будет - ничего не вышло, получилось так, что клавиша вообще зависала...
Где я накосячил?
Вод код всей программы:


Код:
' Импорт для "маршала"
Imports System.Runtime.InteropServices

' контроль нажатий клавиш в активном  пассивном режиме
Public Class Form1
    Private Sub Form1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    End Sub
    Private Const WH_KEYBOARD_LL As Integer = 13
    Private Const WM_KEYUP As Integer = &H101
    Private Shared _proc As LowLevelKeyboardProc = AddressOf HookCallback
    Private Shared _hookID As IntPtr = IntPtr.Zero

    Public Declare Auto Function SetWindowsHookEx Lib "user32.dll" ( _
         ByVal idHook As Integer, ByVal lpfn As LowLevelKeyboardProc, ByVal hMod As IntPtr, ByVal dwThreadId As UInteger) As IntPtr

    Public Declare Auto Function UnhookWindowsHookEx Lib "user32.dll" (ByVal hhk As IntPtr) As IntPtr

    Public Declare Auto Function CallNextHookEx _
     Lib "user32.dll" (ByVal hhk As IntPtr, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr

    Public Declare Auto Function GetModuleHandle Lib "kernel32.dll" (ByVal lpModuleName As String) As IntPtr

    Private Shared Function SetHook(ByVal proc As LowLevelKeyboardProc) As IntPtr
        Dim curProcess As Process = Process.GetCurrentProcess()
        Dim curModule As ProcessModule = curProcess.MainModule
        Return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0)
    End Function
    ' а это уже к эмулятору нажатий клавиш...
   Public Delegate Function LowLevelKeyboardProc( _
         ByVal nCode As Integer, ByVal wParam As IntPtr, _
         ByVal lParam As IntPtr) As IntPtr
    Private Declare Sub keybd_event Lib "user32.dll" _
                   (ByVal bVk As Byte, ByVal bScan As Byte, _
               ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)
    '
   Public Shared Function HookCallback(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
        If nCode >= 0 And wParam = CType(WM_KEYUP, IntPtr) Then
            Dim vkCode As Keys = CType(Marshal.ReadInt32(lParam), Keys)
            ' клавиша, посе нажатия которой происходит событие
           If vkCode = Keys.Oemtilde Or vkCode = Keys.Oemtilde Then
                ' а здесь собственно происходит реакция после нажатия определенной клавиши
               Clipboard.SetText("test text, в дальнейшем скорее всего будет переменная типа String")
                ' эмулируется клавиша Back для стирания одного символа, поскольку реакция идет на "символьную" клавишу
               ' это событие проходит на ура: нажимаем "~", происходит перехват события
               ' keybd_event(8, 0, 0, 0) "стирает" тильду..., и вот дальше проблема...
               keybd_event(8, 0, 0, 0)
                ' это должно по идеии эмулировать нажатие клавиш Ctrl + V, но вместо этого происходит "Зажим" клавиши Ctrl
               ' тоесть происходит "нажатие" Ctrl а V почему-то нет....
               ' и вот эта Ctrl так и остаеться "нажатой", пока ее не отожмешь вручную....
               keybd_event(17, 86, 0, 0)
                ' эта строчка эмулирует нажатие V , текст вставляется в онкно но отжатие Ctrl не происходит..
               'SendKeys.SendWait("{V}")
               ' а вот если дописть
               ' keybd_event(17, 86, 86, 86)
               ' то вставка данных происходит и отжатие тоже, но вместо текста получаеться всякая тарабаршина

            End If
        End If
        Return CallNextHookEx(_hookID, nCode, wParam, lParam)
    End Function

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        _hookID = SetHook(_proc)
    End Sub
    Declare Auto Function FindWindow Lib "USER32.DLL" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    Declare Auto Function SetForegroundWindow Lib "USER32.DLL" (ByVal hWnd As IntPtr) As Boolean
End Class
327
12 мая 2012 года
UserNet2008
748 / / 03.04.2010
Я не совсем разобрался как работать с флагами. Примерно так:
 
Код:
Public Const KEYEVENTF_EXTENDEDKEY = &H1
Public Const KEYEVENTF_KEYUP = &H2
 
Код:
'нажали и держим Ctrl
keybd_event(17, 0, 0 , 0)
'нажали на "V"
'здесь может понадобиться пауза
keybd_event(86, 0, 0 , 0)
' отпускаем Ctrl и "V"
keybd_event(17, 0, KEYEVENTF_KEYUP , 0)
keybd_event(86, 0, KEYEVENTF_KEYUP , 0)
Или так

Код:
'нажали и держим Ctrl
keybd_event(17, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP , 0)
keybd_event(17, 0, KEYEVENTF_EXTENDEDKEY , 0)
'нажали на "V"
'здесь может понадобиться пауза
keybd_event(86, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP , 0)
keybd_event(86, 0, KEYEVENTF_EXTENDEDKEY , 0)

' отпускаем Ctrl и "V"
keybd_event(17, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP , 0)
keybd_event(86, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP , 0)
Или

 
Код:
keybd_event(&H11, 42, 0, 0)
Скан-коды клавиш
327
11 мая 2012 года
UserNet2008
748 / / 03.04.2010
Для начало надо проверить работают ли правильно функции. Long - не нулевое значение "Успех", ноль "Неудача" доп. инфа GetLastError
Где нормально работали API функции так это VB-6.
Можно написать и без API функций
81K
12 мая 2012 года
merkurj
7 / / 11.05.2012
Цитата: UserNet2008
Для начало надо проверить работают ли правильно функции. Long - не нулевое значение "Успех", ноль "Неудача" доп. инфа GetLastError
Где нормально работали API функции так это VB-6.
Можно написать и без API функций



Как бз API, чттобы был перехват клавиш?!!!!
я не смог:(

327
12 мая 2012 года
UserNet2008
748 / / 03.04.2010
Цитата:
был перехват клавиш?


Что вы имеете ввиду Ctrl + V или Ctrl +С ?

На сколько я понял вы хотите программно создать Ctrl + V

 
Код:
keybd_event(8, 0, 0, 0)
'здесь надо сделать паузу
'for i% = 1 то 1000: Next   может и меньше
'в VB2010 я не нашел Sleep()              

keybd_event(&H11, 86, 0, 0)
81K
12 мая 2012 года
merkurj
7 / / 11.05.2012
Едет перехват клавиши в данном случае Oemtilde :
 
Код:
If nCode >= 0 And wParam = CType(WM_KEYUP, IntPtr) Then
            Dim vkCode As Keys = CType(Marshal.ReadInt32(lParam), Keys)
            If vkCode = Keys.LWin Or vkCode = Keys.Oemtilde Then
Далее событие :

 
Код:
Clipboard.SetText("тут, например, текст или переменные")
               
                keybd_event(8, 0, 0, 0)
                keybd_event(&H11, 86, 0, 0)
                'SendKeys.SendWait("&{V}")
&H11 - Ctrl
86 - V
или напутал?
Я исправил ранее написанный код - добавил к нему коментарии...., простите, что сразу этого не сделал...
81K
12 мая 2012 года
merkurj
7 / / 11.05.2012
UserNet2008 , спасибо большое я уже сам понял свою ошибку)))

можно просто так:

 
Код:
keybd_event(17, 0, 0, 0)
                keybd_event(86, 0, 0, 0)
                keybd_event(17, 86, 86, 86)
тоже в принципе работает...
Но сейчас тогда поменяю на ваш второй код)
кстати, V у меня почему-то сама отпускается...
327
12 мая 2012 года
UserNet2008
748 / / 03.04.2010
 
Код:
'Вот это не есть правильно:
keybd_event(17, 0, 0, 0)
                keybd_event(86, 0, 0, 0)
                keybd_event(17, 86, 86, 86)
Что значит чаменю?
Если, проблемы пишите!!!
81K
12 мая 2012 года
merkurj
7 / / 11.05.2012
Правильно - неправильно, но главное работает))) и без вылетов! что кстати удивительно....
а "чаменяю" - это поменяю)))
да я уже поменял....
только без таймера толку нету - реакция происходит ровно через раз, тоесть после двойного нажатия тильды, а это утомляет...., сейчас вот его ставить буду...
327
12 мая 2012 года
UserNet2008
748 / / 03.04.2010
Поставьте цикл For Next
keybd_event(17, Скан-код,

Ссылка выше.
81K
12 мая 2012 года
merkurj
7 / / 11.05.2012
К сожалению цикл "фор некст " здесь не помог, куда я его только не ставил....и какие только значения не ставил. В текстовых редакторах, интернет браузерах все идет на "Ура!" а вот с флеш играми и приложениями возникают проблемы, сново почему-то приходиться два раза клавишу "тыкать":((
Но эту проблему я решил с помощью простого таймера:
Код:
Public Shared Function HookCallback(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
        ' возможность отключения перехвата
       If Form1.Tilde.Checked = True Then
            If nCode >= 0 And wParam = CType(WM_KEYUP, IntPtr) Then
                Dim vkCode As Keys = CType(Marshal.ReadInt32(lParam), Keys)
                ' клавиша, посе нажатия которой происходит событие
               If vkCode = Keys.Oemtilde Or vkCode = Keys.Oemtilde Then
                    ' вызов функции копрования в буфер обмена
                   Call Form1.copy()
                    ' стираем один символ, поскольку реакция была на "символьную" клавишу
                   keybd_event(8, 0, 0, 0)
                    ' выжимаем Ctrl
                   keybd_event(17, 0, 0, 0)
                    ' V
                   keybd_event(86, 0, 0, 0)
                    ' активируем таймер на 0.5 с.
                   Form1.temerKeys.Enabled = True
                    Form1.temerKeys.Interval = 500
                End If
            End If
        End If
        Return CallNextHookEx(_hookID, nCode, wParam, lParam)
    End Function
    Private Sub timerKeys() Handles temerKeys.Tick
        ' после 0.5 с происходит отжатие клавиши Ctrl и выключение таймера
       keybd_event(17, 0, KEYEVENTF_KEYUP, 0)
        temerKeys.Enabled = False
    End Sub
UserNet2008, спасибо Вам большое! , особенно за Скан-коды:) без Вашей помощи я бы наверное очень долго мучался поскольку изучаю программирование всего дня 3-4...
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог