AutoHotkey получает застрял ключ управления
У меня есть несколько ситуаций, когда мой управляющий ключ застревает, и это происходит только тогда, когда у меня работает AutoHotkey. Это происходит с несколькими различными клавишами-модификаторами (клавиша # (windows), особенно клавиша! (Alt)).
Подобные проблемы были опубликованы несколько раз ранее: 1, 2, 3. Существуют некоторые решения, и предложенное здесь частично помогло мне (уменьшило частоту возникновения проблемы), но у меня все еще иногда застрял управляющий ключ.
У меня есть два вопроса:
- Можно ли предотвратить эту проблему?
- Есть ли хороший способ, чтобы AutoHotkey исправил это, как только это произойдет?
Я попробовал все предложенное и создал свою собственную версию функции StuckKeyUp (как предложено здесь:
StuckKeyUp(){
sleep 300
send {<# up}
send {># up}
send {# up}
send {+ up}
send {<+ up}
send {! up}
send {<! up}
send {>! up}
send {^<^^>! up}
send {^<^>! up}
send {^ up}
send {Ctrl down}
send {Ctrl up}
Send {§ up}
Send {Shift Up}
Send {LShift Up}
Send {RShift Up}
Send {Alt Up}
Send {LAlt Up}
Send {RAlt Up}
Send {Control Up}
Send {LControl Up}
Send {<^ down}
Send {<^ Up} ; solves some issues, but not all
Send {>^ down}
Send {>^ Up}
Send {RControl Up}
Send {LControl Up}
Send {LWin Up}
Send {RWin Up}
sleep 100
; reload, ; Avoid - Reloading AutoHotkey File causes functions depending on this function to break
return
}
5 ответов
Среди других методов отладки вы можете попробовать это:
Поместите этот код в определенные позиции в вашем скрипте (в определениях горячих клавиш, которые отправляют управляющую клавишу или в таймере)
If GetKeyState("Ctrl") ; If the OS believes the key to be in (logical state),
{
If !GetKeyState("Ctrl","P") ; but the user isn't physically holding it down (physical state)
{
Send {Blind}{Ctrl Up}
MsgBox,,, Ctrl released
KeyHistory
}
}
и посмотрите в KeyHistory (после закрытия окна сообщения), в каких ситуациях ключ застревает.
У меня также была эта проблема (только Ctrl когда-либо зависал), и для меня исправление заключалось в использовании #MenuMaskKey в верхней части скрипта:
;; Avoid Ctrl getting stuck in down state, even when not physically pressed:
#MenuMaskKey vkFF
Справочная информация с https://www.autohotkey.com/docs/commands/_MenuMaskKey.htm
Ключ маски отправляется автоматически, чтобы предотвратить активацию меню "Пуск" или строки меню активного окна в неожиданное время.
Клавиша маски по умолчанию - Ctrl.
...
Если система должна обнаруживать только нажатие клавиши Win или Alt и нажатие клавиши без промежуточного нажатия клавиш, она обычно активирует меню. Для предотвращения этого крючок клавиатуры или мыши может автоматически отправлять ключ маски.
Я добавил #InstallKeybdHook, и все было хорошо. Подробнее см. Ниже.
https://www.autohotkey.com/docs/commands/_HotkeyModifierTimeout.htm
Хотя ответ user3419297 очень хорош, я думаю, что blind keyup
звонок - это не то, что решает проблему.
Похоже, что KeyHistory
команда вызывает отпускание клавиш.
Когда я использовал версию скрипта user3419297 без KeyHistory
, у меня это никогда не работало. Напротив, обращение кKeyHistory
одного было достаточно, чтобы решить проблему каждый раз, когда она возникала.
Эта проблема внезапно стала возникать в сценарии, который работал без сбоев в течение многих лет и в который я не вносил никаких изменений. FWIW начался после обновления Windows, которое, похоже, немного замедлило как скрипты AHK, так и скрипты python, которые отправляют нажатия клавиш приложениям. Кажется, что все говорят, что этого не может быть, но я знаю, что вижу. Как бы то ни было, я пробовал все, что мог найти, и ничего не работало, пока я не поставил это в начале своего скрипта:
^T:: ;Script starts here
Sleep, 500
Send {LCtrl Up}
;Script continues and Ctrl is no longer pressed :)
Извините, у меня нет точного технического объяснения, почему это работает. Я предполагаю, что я не отпускаю клавишу Ctrl достаточно быстро, когда нажимаю горячую клавишу (в данном случае Ctrl-T), но она почему-то не совсем зарегистрирована в AHK. В любом случае, эта небольшая пауза перед отправкой ключа, кажется, срабатывает каждый раз. 500 мс были произвольными; это работает, и я не стал пытаться сделать его короче. Больше не нужно нажимать Ctrl после каждого скрипта, ура!