Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » [решено] Отслеживание нажатий клавиш на клавиатуре (чтоб узнать код нажатой клавиши)

Ответить
Настройки темы
[решено] Отслеживание нажатий клавиш на клавиатуре (чтоб узнать код нажатой клавиши)

Аватара для beve

Старожил


Сообщения: 307
Благодарности: 137


Конфигурация

Профиль | Отправить PM | Цитировать


Изменения
Автор: beve
Дата: 22-08-2009
Вопрос такой: нужно отслеживать нажатие клавиш на клавиатуре и если какая то клавиша нажата, вывести ее скан код, для примера, в ToolTip. (Хочу потом сделать чтото подобное, что есть у Punto Switcher-a, тоесть чтоб озвучивались нажатые клавиши в русской расскладке - одним звуком, в английской - другим, а в украинском - третьим. ) Есть код CreatoR-а: Ссылка, который я вот немного упростил, чтоб показать что мне нужно:
Код: Выделить весь код
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) 
$sBuffer= Chr($nKeyCode)&" - "&$nKeyCode
ToolTip($sBuffer , 0, 80) 
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
так вот, как изменить этот код, или сделать еще проще, чтоб в ToolTip показывался скан код нажатой клавиши, а то в этом примере отображаются только английские символы и причем в верхнем регистре, даже если нажать - ф, то отображается A.

-------
Не в кількості знань полягає освіта, а в повному розумінні і вмілому використанні того, що знаєш.


Отправлено: 00:43, 22-08-2009

 

Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Цитата beve:
как изменить этот код, или сделать еще проще, чтоб в ToolTip показывался скан код нажатой клавиши »
ToolTip($nKeyCode, 0, 80)?

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 01:01, 22-08-2009 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Аватара для beve

Старожил


Сообщения: 307
Благодарности: 137

Профиль | Отправить PM | Цитировать


Я специально сделал ToolTip($sBuffer , 0, 80) для примера, чтоб показать всем, что если нажать например на русскую букву а, при русской расскладке, то что будет показано в ToolTip при текущем коде, а мне нужно чтоб там была буква а, и ее код.

-------
Не в кількості знань полягає освіта, а в повному розумінні і вмілому використанні того, що знаєш.


Отправлено: 01:41, 22-08-2009 | #3


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Цитата beve:
Я специально сделал ToolTip($sBuffer , 0, 80) для примера »
В твоём вопросе в первом сообщении было явно указано:

Цитата beve:
Вопрос такой: нужно отслеживать нажатие клавиш на клавиатуре и если какая то клавиша нажата, вывести ее скан код, для примера, в ToolTip »
А я не заметил что $sBuffer это Chr($nKeyCode) & " - " & $nKeyCode

Теперь это уже вторая задача...

Цитата beve:
мне нужно чтоб там была буква а, и ее код »
Код: Выделить весь код
#include <Misc.au3>

HotKeySet("{ESC}", "OnAutoItExit")

Global $nOld_KC = -1

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)
    $nOld_KC = $nKeyCode
    If $nKeyCode < 65 Or $nKeyCode > 90 Then Return ;Исключаем всё кроме алфавитных букв

    Local $sChar = Chr($nKeyCode)

    Switch _WinGetKeyboardLayout(WinGetHandle("[ACTIVE]"))
        Case 0409
            ;
        Case 0419
            Local $aANSI_Chars = StringSplit("ёйцукенгшщзхъфывапролджэячсмитьбю.?", "")
            Local $aASCII_Chars = StringSplit("`qwertyuiop[]asdfghjkl;'zxcvbnm,./&", "")

            For $i = 1 To $aANSI_Chars[0]
                $sChar = StringReplace($sChar, $aASCII_Chars[$i], $aANSI_Chars[$i])
            Next

            $sChar = StringUpper($sChar) ;По умолчанию у нас же в верхнем регистре :)
    EndSwitch

    If Not _IsPressed(10) Then $sChar = StringLower($sChar)

    $sBuffer = $sChar & " - " & $nKeyCode
    ToolTip($sBuffer, 0, 80)
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 _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

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Последний раз редактировалось Creat0R, 22-08-2009 в 02:23.

Это сообщение посчитали полезным следующие участники:

Отправлено: 02:12, 22-08-2009 | #4


Аватара для beve

Старожил


Сообщения: 307
Благодарности: 137

Профиль | Отправить PM | Цитировать


Спасибо, за идею. Вот, сделал то что было непонятно (а то в приведенном выше примере "не работали" некоторые клавиши-ю,х,ъ...):
Код: Выделить весь код
#include <Misc.au3>

HotKeySet("{ESC}", "OnAutoItExit")


Global Const $WH_KEYBOARD_LL = 13
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(30)
WEnd

Func EvaluateKey($nKeyCode)
Local $captureCodes, $engWithShiftCodes, $engCodes, $rusWithShiftCodes,$rusCodes, $ukrWithShiftCodes, $ukrCodes, $i 

Switch $nKeyCode
Case 65 To 90, 48 To 57,186,188,190,191,192,219,221,222 ; проверяться будут только нажатия на буквы и цифры
    If StringLen($nKeyCode)<3 Then $nKeyCode="0"&$nKeyCode
    Switch _WinGetKeyboardLayout(WinGetHandle("[ACTIVE]"))
    ;Если раскладка английская
    Case 0409
    If _IsPressed(10) Then ; если нажата клавиша Shift
    $captureCodes = StringSplit("192,081,087,069,082,084,089,085,073,079,080,219,221,065,083,068,070,071,072,074,075,076,186,222,090,088,067,086,066,078,077,188,190,191,048,049,050,051,052,053,054,055,056,057", ",")
     $engWithShiftCodes = StringSplit("126,081,087,069,082,084,089,085,073,079,080,123,125,065,83,068,070,071,072,074,075,076,058,034,090,088,067,086,066,078,077,060,062,063,041,033,064,035,036,037,094,038,042,040", ",")
        For $i = 1 To $captureCodes [0]
            $nKeyCode = StringReplace($nKeyCode,$captureCodes [$i], $engWithShiftCodes[$i])
        Next
    ToolTip(Chr($nKeyCode)& " - "&$nKeyCode, 0, 80)
    SoundPlay("en.wav") ;проигрывать звук при нажатии
Else ; если не нажата клавиша Shift
    $captureCodes = StringSplit("192,081,087,069,082,084,089,085,073,079,080,219,221,065,083,068,070,071,072,074,075,076,186,222,090,088,067,086,066,078,077,188,190,191,048,049,050,051,052,053,054,055,056,057", ",")
    $engCodes = StringSplit("096,113,119,101,114,116,121,117,105,111,112,091,093,097,115,100,102,103,104,106,107,108,059,039,122,120,099,118,098,110,109,044,046,047,048,049,050,051,052,053,054,055,056,057", ",")
        For $i = 1 To $captureCodes [0]
            $nKeyCode = StringReplace($nKeyCode,$captureCodes [$i], $engCodes[$i])
        Next
    ToolTip(Chr($nKeyCode)& " - "&$nKeyCode, 0, 80)
     SoundPlay("en.wav") ;проигрывать звук при нажатии
    EndIf

    ;Если расскладка русская
    Case 0419
    If _IsPressed(10) Then  ; если нажата клавиша Shift
    $captureCodes = StringSplit("192,081,087,069,082,084,089,085,073,079,080,219,221,065,083,068,070,071,072,074,075,076,186,222,090,088,067,086,066,078,077,188,190,191,048,049,050,051,052,053,054,055,056,057", ",")
     $rusWithShiftCodes = StringSplit("168,201,214,211,202,197,205,195,216,217,199,213,218,212,219,194,192,207,208,206,203,196,198,221,223,215,209,204,200,210,220,193,222,044,041,033,034,185,059,037,058,063,042,040", ",")
        For $i = 1 To $captureCodes [0]
            $nKeyCode = StringReplace($nKeyCode,$captureCodes [$i], $rusWithShiftCodes[$i])
        Next
    ToolTip(Chr($nKeyCode)& " - "&$nKeyCode, 0, 80)
    SoundPlay("ru.wav") ;проигрывать звук при нажатии
Else  ; если не нажата клавиша Shift
    $captureCodes = StringSplit("192,081,087,069,082,084,089,085,073,079,080,219,221,065,083,068,070,071,072,074,075,076,186,222,090,088,067,086,066,078,077,188,190,191,048,049,050,051,052,053,054,055,056,057", ",")
    $rusCodes = StringSplit("184,233,246,243,234,229,237,227,248,249,231,245,250,244,251,226,224,239,240,238,235,228,230,253,255,247,241,236,232,242,252,225,254,046,048,049,050,051,052,053,054,055,056,057", ",")
        For $i = 1 To $captureCodes [0]
            $nKeyCode = StringReplace($nKeyCode,$captureCodes [$i], $rusCodes[$i])
       Next
    ToolTip(Chr($nKeyCode)& " - "&$nKeyCode, 0, 80)
    SoundPlay("ru.wav") ;проигрывать звук при нажатии
    EndIf   

    ;если расскладка украинская
Case 0422
    If _IsPressed(10) Then ; если нажата клавиша Shift
    $captureCodes = StringSplit("192,081,087,069,082,084,090,085,073,079,080,219,221,065,083,068,070,071,072,074,075,076,186,222,089,088,067,086,066,078,077,188,190,191,048,049,050,051,052,053,054,055,056,057", ",")
     $ukrWithShiftCodes = StringSplit("146,201,214,211,202,197,205,195,216,217,199,213,175,212,178,194,192,207,208,206,203,196,198,170,223,215,209,204,200,210,220,193,222,044,041,033,034,185,059,037,058,063,042,040", ",")
        For $i = 1 To $captureCodes [0]
            $nKeyCode = StringReplace($nKeyCode,$captureCodes [$i], $ukrWithShiftCodes[$i])
        Next
    ToolTip(Chr($nKeyCode)& " - "&$nKeyCode, 0, 80)
    SoundPlay("ukr.wav") ;проигрывать звук при нажатии
    Else ; если не нажата клавиша Shift
    $captureCodes = StringSplit("191,192,081,087,069,082,084,090,085,073,079,080,219,221,065,083,068,070,071,072,074,075,076,186,222,089,088,067,086,066,078,077,188,190,048,049,050,051,052,053,054,055,056,057", ",")
    $ukrCodes = StringSplit("046,039,233,246,243,234,229,237,227,248,249,231,245,191,244,179,226,224,239,240,238,235,228,230,186,255,247,241,236,232,242,252,225,254,048,049,050,051,052,053,054,055,056,057", ",")
        For $i= 1 To $captureCodes [0]
            $nKeyCode = StringReplace($nKeyCode, $captureCodes [$i], $ukrCodes[$i])
        Next
    ToolTip(Chr($nKeyCode)& " - "&$nKeyCode, 0, 80)
    SoundPlay("ukr.wav") ;проигрывать звук при нажатии
    EndIf

    EndSwitch
Case Else ; если была нажата не буква и не цыфра, то выход из функции
    Return
EndSwitch
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 _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

-------
Не в кількості знань полягає освіта, а в повному розумінні і вмілому використанні того, що знаєш.


Отправлено: 19:46, 22-08-2009 | #5


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Цитата beve:
Вот, сделал »
Да... вижу ты не экономил на коде

Я бы сократил так:

Код: Выделить весь код
#include <Misc.au3>

HotKeySet("{ESC}", "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 $sUkrCapture_Codes, $sUkr_Codes, $sUkrShift_Codes

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

    Local $sSound

    Switch $nKeyCode
        Case 65 To 90, 48 To 57, 186, 188, 190, 191, 192, 219, 221, 222 ; проверяться будут только нажатия на буквы и цифры
            If StringLen($nKeyCode) < 3 Then $nKeyCode = "0" & $nKeyCode

            $sCapt_Codes = _
                "192,081,087,069,082,084,089,085,073,079,080,219,221,065,083,068,070,071,072,074,075,076," & _
                "186,222,090,088,067,086,066,078,077,188,190,191,048,049,050,051,052,053,054,055,056,057"

            $sEng_Codes = _
                "096,113,119,101,114,116,121,117,105,111,112,091,093,097,115,100,102,103,104,106,107,108," & _
                "059,039,122,120,099,118,098,110,109,044,046,047,048,049,050,051,052,053,054,055,056,057"

            $sEngShift_Codes = _
                "126,081,087,069,082,084,089,085,073,079,080,123,125,065,083,068,070,071,072,074,075,076," & _
                "058,034,090,088,067,086,066,078,077,060,062,063,041,033,064,035,036,037,094,038,042,040"

            $sRus_Codes = _
                "184,233,246,243,234,229,237,227,248,249,231,245,250,244,251,226,224,239,240,238,235,228," & _
                "230,253,255,247,241,236,232,242,252,225,254,046,048,049,050,051,052,053,054,055,056,057"

            $sRusShift_Codes = _
                "168,201,214,211,202,197,205,195,216,217,199,213,218,212,219,194,192,207,208,206,203,196," & _
                "198,221,223,215,209,204,200,210,220,193,222,044,041,033,034,185,059,037,058,063,042,040"

            $sUkrCapture_Codes = StringReplace($sCapt_Codes, "090", "089")

            $sUkr_Codes = _
                "046,039,233,246,243,234,229,237,227,248,249,231,245,191,244,179,226,224,239,240,238,235," & _
                "228,230,186,255,247,241,236,232,242,252,225,254,048,049,050,051,052,053,054,055,056,057"

            $sUkrShift_Codes = _
                "146,201,214,211,202,197,205,195,216,217,199,213,175,212,178,194,192,207,208,206,203,196," & _
                "198,170,223,215,209,204,200,210,220,193,222,044,041,033,034,185,059,037,058,063,042,040"

            $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, ",")

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

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

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

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

                    $sSound = "ukr.wav"
            EndSwitch

            ToolTip(Chr($nKeyCode) & " - " & $nKeyCode, 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(ByRef $nKeyCode, $aSearch_Array, $aReplace_Array)
    For $i = 1 To $aSearch_Array[0]
        $nKeyCode = StringReplace($nKeyCode, $aSearch_Array[$i], $aReplace_Array[$i])
    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

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community

Это сообщение посчитали полезным следующие участники:

Отправлено: 23:47, 22-08-2009 | #6


Аватара для beve

Старожил


Сообщения: 307
Благодарности: 137

Профиль | Отправить PM | Цитировать


Цитата Creat0R:
Я бы сократил так: »
Согласен, так выглядет получше! И почти все работает, но вот при украинской расскладке, если набирать буквы в нижнем регистре, то набирается не то: при наборе символов абвгдеєжзиіїйклмнопрстуахцчшщюяь - в ToolTip показываются вьінлкждщмфх'уосZрапчицвзйягшбетс...А в верхнем регистре (при удерживании Shift) набирается то что нужно.
У себя в примере, я тоже заморочился немного с укр раскладкой, но там проблема была в трех местах, а тут? Может тебе понятней почему тут так?

-------
Не в кількості знань полягає освіта, а в повному розумінні і вмілому використанні того, що знаєш.


Последний раз редактировалось beve, 23-08-2009 в 01:54.


Отправлено: 01:37, 23-08-2009 | #7


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Цитата beve:
но вот при украинской расскладке »
Сорри, я в украинском не бум бум, и ставить её для проверки пока не могу, у меня были серъёзные траблы с раскладками, пока наладилось, трогать не хочется, чтобы не испортить

P.S
Но могу предложить использовать всё же мой метод, с реальными буквами в массиве, а не кодами - так будет легче для разбора в дальнейшем.

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 02:52, 23-08-2009 | #8


Аватара для beve

Старожил


Сообщения: 307
Благодарности: 137

Профиль | Отправить PM | Цитировать


Цитата Creat0R:
Но могу предложить использовать всё же мой метод, с реальными буквами в массиве, а не кодами - так будет легче для разбора в дальнейшем. »
Согласился и переделал. Кажись теперь всё :
Код: Выделить весь код
#include <Misc.au3>

HotKeySet("{ESC}", "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
Case 65 To 90, 48 To 57, 186 To 192, 219, 221, 222 ; проверяться будут только нажатия на буквы и цифры и еще клавиши минус и плюс, что после клавиши 0.
           
            $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

-------
Не в кількості знань полягає освіта, а в повному розумінні і вмілому використанні того, що знаєш.


Последний раз редактировалось beve, 23-08-2009 в 17:16.

Это сообщение посчитали полезным следующие участники:

Отправлено: 16:57, 23-08-2009 | #9


Новый участник


Сообщения: 6
Благодарности: 0

Профиль | Отправить PM | Цитировать


а как можно усовершенствовать скрипт чтобы допусти отслеживать (пробел, кнопки мыши, цифровую клавиатуру) ? второй день сижу не могу догнать, спасайте люди добрые

Отправлено: 10:41, 01-09-2010 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » [решено] Отслеживание нажатий клавиш на клавиатуре (чтоб узнать код нажатой клавиши)

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Какая разница между пирамидальной и обычной раскладкой клавиш на клавиатуре? Sev Флейм 2 17-02-2009 12:01
[решено] Горячие клавиши на Клавиатуре. krema Хочу все знать 2 04-02-2009 22:52
Как назначить кнопкам джойстика функцию нажатой клавиши на клаве. spiritmen Игры 4 05-06-2007 13:44




 
Переход