Помогите с ошибкой в коде...
При нажатии кливиши "Тильда"
Все идет отлично до Воспроизведения клавиш Ctrl + V:
Код:
keybd_event(8, 0, 0, 0)
keybd_event(&H11, 86, 0, 0)
keybd_event(&H11, 86, 0, 0)
Пробовал делать дубль этого кода, думал может как включает - так и отключать будет - ничего не вышло, получилось так, что клавиша вообще зависала...
Где я накосячил?
Вод код всей программы:
Код:
' Импорт для "маршала"
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
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
Код:
Public Const KEYEVENTF_EXTENDEDKEY = &H1
Public Const KEYEVENTF_KEYUP = &H2
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)
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(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)
Где нормально работали API функции так это VB-6.
Можно написать и без API функций
Цитата: UserNet2008
Для начало надо проверить работают ли правильно функции. Long - не нулевое значение "Успех", ноль "Неудача" доп. инфа GetLastError
Где нормально работали API функции так это VB-6.
Можно написать и без API функций
Где нормально работали API функции так это VB-6.
Можно написать и без API функций
Как бз API, чттобы был перехват клавиш?!!!!
я не смог:(
Цитата:
был перехват клавиш?
Что вы имеете ввиду Ctrl + V или Ctrl +С ?
На сколько я понял вы хотите программно создать Ctrl + V
Код:
keybd_event(8, 0, 0, 0)
'здесь надо сделать паузу
'for i% = 1 то 1000: Next может и меньше
'в VB2010 я не нашел Sleep()
keybd_event(&H11, 86, 0, 0)
'здесь надо сделать паузу
'for i% = 1 то 1000: Next может и меньше
'в VB2010 я не нашел Sleep()
keybd_event(&H11, 86, 0, 0)
Код:
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
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}")
keybd_event(8, 0, 0, 0)
keybd_event(&H11, 86, 0, 0)
'SendKeys.SendWait("&{V}")
86 - V
или напутал?
Я исправил ранее написанный код - добавил к нему коментарии...., простите, что сразу этого не сделал...
можно просто так:
Код:
keybd_event(17, 0, 0, 0)
keybd_event(86, 0, 0, 0)
keybd_event(17, 86, 86, 86)
keybd_event(86, 0, 0, 0)
keybd_event(17, 86, 86, 86)
Но сейчас тогда поменяю на ваш второй код)
кстати, V у меня почему-то сама отпускается...
Код:
'Вот это не есть правильно:
keybd_event(17, 0, 0, 0)
keybd_event(86, 0, 0, 0)
keybd_event(17, 86, 86, 86)
keybd_event(17, 0, 0, 0)
keybd_event(86, 0, 0, 0)
keybd_event(17, 86, 86, 86)
Если, проблемы пишите!!!
а "чаменяю" - это поменяю)))
да я уже поменял....
только без таймера толку нету - реакция происходит ровно через раз, тоесть после двойного нажатия тильды, а это утомляет...., сейчас вот его ставить буду...
keybd_event(17, Скан-код,
Ссылка выше.
Но эту проблему я решил с помощью простого таймера:
Код:
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
' возможность отключения перехвата
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