Войти несколько ключей с AutoHotkey - PullRequest
2 голосов
/ 08 апреля 2019

Я пытаюсь позволить гоночной игре играть через AutoHotkey. Я использую этот сценарий для вставки нажатых клавиш в текстовый файл, чтобы они автоматически воспроизводились.

Моя проблема теперь в том, что этот скрипт может регистрировать только один ключ, например, {w down} для перемотки вперед. Но чтобы вести машину лучше, вы должны нажать w и d , чтобы повернуть направо.

Как мне изменить код, чтобы он работал так, как я хочу?

$F1::
start := A_TickCount
FileDelete, log.txt

Loop
{
Input, key, L1 V, %endkeyslist%
IfInString, ErrorLevel, EndKey:
{
StringTrimleft, key, ErrorLevel, 7
}
time := (A_TickCount - start)
start := A_TickCount
text1:="Sleep, " time "`n"
text2:="Send {" key " Down} `n"
FileAppend, %text1%, log.txt
FileAppend, %text2%, log.txt

KeyWait, %key% ;waits the key to be released
time := (A_TickCount - start)
start := A_TickCount
text1:="Sleep, " time "`n"
text2:="Send {" key " Up} `n"
FileAppend, %text1%, log.txt
FileAppend, %text2%, log.txt
}
return

$F2:: ExitApp

1 Ответ

1 голос
/ 08 апреля 2019

Я бы рекомендовал использовать OnMessage() для отслеживания сообщений о событиях нажатия клавиш (0x100) и нажатия клавиш (0x101). Вот несколько ссылок на соответствующую справочную документацию: OnMessage () , Список сообщений Windows .

Ниже приведен рабочий пример создания файла на рабочем столе testEE.txt с параметрами, аналогичными тем, которые вы регистрируете. Обратите внимание, что это не будет регистрировать движения мыши или щелчки (возможно, я просто не настроил это таким образом). Нажмите F1, чтобы начать и остановить запись.

f1::
bT := !bT
If bT
{
    MsgBox ,,, Recording started , 1
    KeyBdHook := DllCall(   "SetWindowsHookEx" , "int" , 13  , "uint" , RegisterCallback( "KeyBdProc" ) , "uint" , 0 , "uint" , 0 )
    nStart := A_TickCount
} Else {
    DllCall( "UnhookWindowsHookEx" , "ptr" , KeyBdHook )
    MsgBox ,,, Recording terminated , 1
}
Return

KeyBdProc( nCode , wParam , lParam )
{
    global
    Critical
    If ( wParam = 0x100 || wParam = 0x101 )
    {
        nKey := Format( "{:x}" , NumGet( lParam + 0 , 0 , "int" ) )
        nTime := A_TickCount - nStart , nStart := A_TickCount
        If ( wParam = 0x100 && nKey != nKeyPrev )
        {
            nKeyPrev := nKey
            FileAppend , % nTime . "|" . nKey . " down`n" , %A_Desktop%/testEE.txt
        }
        If ( wParam = 0x101 )
        {
            If ( nKey = nKeyPrev )
                nKeyPrev := ""
            FileAppend , % nTime . "|" . nKey . " up`n" , %A_Desktop%/testEE.txt
    }   }
    Return DllCall( "CallNextHookEx" , "uint" , KeyBdHook , "int" , nCode , "uint" , wParam , "uint" , lParam )
}

Это воспроизведет ваши нажатия клавиш:

f2::
aData := []
FileRead , sText , %A_Desktop%/testEE.txt
Loop , Parse , sText , `n , `r
{
    nCt := A_Index
    Loop , Parse , A_LoopField , |
        aData[ nCt , A_Index ] := A_LoopField
}
Loop , % aData.Length()
{
    If InStr( aData[ A_Index , 2 ] , "70 " ) ; 0x70 is F1
        Continue
    Sleep , % aData[ A_Index , 1 ]
    Send , % "{vk" . aData[ A_Index , 2 ] . "}"
}
Return

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

Я нашел эти сообщения особенно полезными, для справки:
https://autohotkey.com/board/topic/27067-mouse-move-detection/
https://www.autohotkey.com/boards/viewtopic.php?t=11922
Как активировать функцию каждый раз, когда целевое окно становится активным в AutoHotkey
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowshookexa
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-unhookwindowshookex

...