【问题标题】:Log multiple Keys with AutoHotkey使用 AutoHotkey 记录多个键
【发布时间】:2019-08-29 21:46:26
【问题描述】:

我正在尝试通过 AutoHotkey 进行比赛游戏。我使用这个脚本将我按下的键粘贴到一个 txt 中,让它们自动播放。

我现在的问题是这个脚本只能记录一个键,例如 {w down} 用于驱动前进。但是为了更好地在游戏中驾驶,您必须按 wd 向右行驶。

如何更改代码以使其按我想要的方式工作?

$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

【问题讨论】:

    标签: autohotkey


    【解决方案1】:

    我建议使用OnMessage() 来监控按键按下 (0x100) 和按键按下 (0x101) 事件消息。以下是相关帮助文档的一些链接:OnMessage()List of Windows Messages

    下面是一个工作示例,它将在您的桌面上创建一个文件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
    How to activate a function everytime the target window becomes active in 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

    【讨论】:

    • 谢谢你的快速帮助:D。但这并没有解决我的问题......我需要实现我可以一次记录多个 Keypress 或者我自动格式化它:睡眠,31 发送 {65 向下} {68 向下} 睡眠,31 发送 {65 向上} {68 Up} 告诉我我什么时候没有收到它
    • @Broump 没问题。这确实会一次记录多个按键,但它的格式与您的格式不同。这只是一个如何使用OnMessage() 的示例。要按照您的意愿进行格式化,您需要将 wParam 转换为虚拟键号(KeyHistory 可以帮助您发现每个键的代码)并添加额外的文本(特别是 @987654337 @ 和 text2)。
    • 哦,谢谢,现在我看到了 :)。你的翻译是什么意思? KeyHistory 给我的数字与你的脚本不同......它可以使用这样的 if 语句工作吗: if (wPd == 87) { key = "w" } 还是我必须使用不同的技术?谢谢帮助
    • @Broump 通过翻译,我的意思是将其从十进制转换为十六进制。我更新了代码并添加了另一部分来读取它。我相信它完全可以满足您现在的需求。
    • 但它只在 gui 处于活动状态时记录键...。我需要切换到游戏,脚本没有记录任何内容...
    猜你喜欢
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-31
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    相关资源
    最近更新 更多