1

Тема: AHK: Хоткеи - последовательное нажатие

Всем привет! Подскажите пожалуйста, как реализовать следующий хоткей: зажимаю Ctrl, затем жму 1 и отпускаю, затем жму 2 и отпускаю, затем отпускаю Ctrl и после этого начинается выполнение команд. Иными словами нажал Ctrl, затем напечатал несколько цифр или букв в нужной последовательности и после этого следует команда.

По форуму поискал, но не нашел того что мне нужно, либо не хватило мозгов чтобы переделать под свои нужды.

2 (изменено: serzh82saratov, 2014-11-01 09:59:41)

Re: AHK: Хоткеи - последовательное нажатие

Например так:


Global keys, spot, thishk
OnExit, Exit
hHookKeybd := DllCall("SetWindowsHookEx"
   , Int, WH_KEYBOARD_LL := 13
   , Ptr, RegisterCallback("LowLevelKeyboardProc", "Fast")
   , Ptr, DllCall("GetModuleHandle", UInt, 0, Ptr)
   , UInt, 0, Ptr)
Return

~LControl::keys := "", spot := 1, thishk := "vkA2" 

~LControl Up::
    spot := 0
    If keys = {vk31}{vk32}{vk51}  ;  1 2 Q
        MsgBox LControl 1 2 Q
    else If keys = {vk51}{vk32}{vk31}  ;   Q 2 1
        MsgBox LControl Q 2 1
    Return
    
Exit:
   DllCall("UnhookWindowsHookEx", Ptr, hHookKeybd)
   ExitApp
   
LowLevelKeyboardProc(nCode, wParam, lParam)  { 
    If (spot && wParam = 0x101)  ;  WM_KEYUP := 0x101
    {  
        SaveFormat := A_FormatInteger
        SetFormat, IntegerFast, H
        vk := "vk" SubStr(NumGet(lParam+0, 0, "UInt"), 3)
        SetFormat, IntegerFast, %SaveFormat%
        If (vk != thishk)
            keys .= "{" vk "}" 
    }
    Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, Ptr, wParam, Ptr, lParam) 
}

затем напечатал несколько цифр или букв

Это если цифры и буквы подразумеваются как соответствующие клавиши.
Если имеются ввиду именно вводимые символы, то нужно иначе.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

3

Re: AHK: Хоткеи - последовательное нажатие

Если под "несколько цифр или букв" понимается несколько конкретных знаков, а не любые из всего доступного набора, то можно так:

~Ctrl Up::
   If IsLabel(Combo)
      GoSub %Combo%
   Combo := ""
Return
^1:: ; Ctrl+1
^2:: ; Ctrl+2
^vk51:: ; Ctrl+Q
  Combo .= A_ThisHotkey
  KeyWait, %A_ThisHotkey%
Return

^1^2:
   SoundBeep, 750, 200
   MsgBox % A_ThisLabel
Return

^vk51^2^1:
MsgBox Q-Два-Один
Return

4

Re: AHK: Хоткеи - последовательное нажатие

serzh82saratov, твой вариант работает.. но! Запускаю скрипт, нажимаю Ctrl + 1q2w, выскакивает MsgBox, жму ОК, окно закрывается, а вот после если начать мышкой щелкать по открытым окнам, то MsgBox снова начинает появляться (не сразу, а примерно секунд через 5-10). Если при первом запуске скрипта не нажимать Ctrl + 1q2w, то MsgBox не появляется при тех же условиях.

Irbis, твой вариант работает великолепно и к тому же еще и короче))

Товарищи, спасибо вам большое, что уделили время и помогли решить мою задачу! Вы джедаи своего дела!))

5

Re: AHK: Хоткеи - последовательное нажатие

Пожалуйста

Запускал скрипт, который предложил Серж, все работает, ложных срабатываний добиться не получилось.

По поводу "проще-сложней" или "больше-меньше", все относительно. Если клавиш, подлежащих обработке, много, то предложенный клавиатурный хук предпочтительней, на мой взгляд, чем куча хоткеев.

6

Re: AHK: Хоткеи - последовательное нажатие

ravensblade всё согласно ТЗ.
Ведь у тебя такой нюанс:

нажал Ctrl, затем напечатал несколько цифр или букв в нужной последовательности

То есть можно ведь в случае хоткеев нажать 1, потом что угодно, после 2, и всё равно будет верно?

если начать мышкой щелкать по открытым окнам, то MsgBox снова начинает появляться

Даже представить не могу такого.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

7 (изменено: akhill, 2014-11-05 00:51:21)

Re: AHK: Хоткеи - последовательное нажатие

Вариант serzh82saratov почему-то не заработал на моей Win7 x 64 хоть я и запускал AutoHotkey_L v1.1.16.05.
А вариант Irbis заработал, но у меня возник вопрос: Что делать если нужно сохранить стандартную обработку нажатия например Ctrl+1? Потому что когда таким образом производится переназначение для, например, Ctrl+12 мы убиваем возможность стандартной (по умолчанию) обработки Ctrl+1, как и Ctrl+2, как и Ctrl+Q в других приложениях. Возможен ли выход из этой ситуации? Спасибо!

8 (изменено: Irbis, 2014-11-05 08:30:34)

Re: AHK: Хоткеи - последовательное нажатие

Выход есть,  конечно.  Надо сразу было учесть этот нюанс, хоть он и не оговорен в ТЗ. Первый хоткей примет вид

if ...
GoSub ...
else
SendInput ...

Плюс добавить префикс "$" к остальным хоткеям, чтобы была возможность отправлять их из скрипта. Вечером, с компьютера отправлю рабочий вариант, если никто раньше не исправит.

Upd: В любом случае оригинального мгновенного срабатывания ctrl+1 и прочих не получится, возможны 2 варианта: отправка по отжатию Ctrl или таймауту между последовательным нажатиями.

9

Re: AHK: Хоткеи - последовательное нажатие

~Ctrl Up::
   If IsLabel(Combo)
      GoSub %Combo%
   Combo := ""
Return
$^1:: ; Ctrl+1
$^2:: ; Ctrl+2
$^vk51:: ; Ctrl+Q
   if !GetKeyState("Ctrl","P")
      SendInput, % "{Ctrl Down}{" SubStr(A_PriorHotkey,3) "}{Ctrl Up}"
   Combo .= A_ThisHotkey
   KeyWait, %A_ThisHotkey%
Return

$^1$^2:
MsgBox Control+1,2
Return

10

Re: AHK: Хоткеи - последовательное нажатие

Спасибо, Irbis! Даже не ожидал что выход найдется. Благодаря Вам у меня появилось поле для «творчества». Буду применять эту технику.

11

Re: AHK: Хоткеи - последовательное нажатие

Пожалуйста.

12

Re: AHK: Хоткеи - последовательное нажатие

Здравствуйте, товарищи! Подскажите пожалуйста, я пытаюсь переделать скрипт так, чтобы он срабатывал не от кнопки Ctrl, а от RButton, но у меня ничего не получается((. Первый вариант от serzh82saratov работает с RButton, но стоит лишь добавить в скрипт пару строк с другими горячими клавишами, так он перестает работать. Добавлял вот это:

Suspend
RWin::Suspend
F12::Reload

Так же не работает, если добавить это:

~LControl Up::
    spot := 0
    If keys = {vk31}{vk32}{vk51}  ;  1 2 Q
        ImageSearch, x, y, 0, 0, A_ScreenWidth, A_ScreenHeight, /* путь к файлу */
        if ErrorLevel = 0
        MsgBox LControl Q 2 1
    else If keys = {vk51}{vk32}{vk31}  ;   Q 2 1
        MsgBox LControl Q 2 1
    Return

Второй же вариант от Irbis вообще не могу переделать на RButton (сейчас пользуюсь этим скриптом).

13 (изменено: serzh82saratov, 2015-07-21 20:06:24)

Re: AHK: Хоткеи - последовательное нажатие

С RButton так:

Global keys, spot 
OnExit, Exit
hHookKeybd := DllCall("SetWindowsHookEx"
   , Int, WH_KEYBOARD_LL := 13
   , Ptr, RegisterCallback("LowLevelKeyboardProc", "Fast")
   , Ptr, DllCall("GetModuleHandle", UInt, 0, Ptr)
   , UInt, 0, Ptr)
Return

~RButton::keys := "", spot := 1 

~RButton Up::
    spot := 0
    If keys = {vk31}{vk32}{vk51}  ;  1 2 Q
        MsgBox RButton 1 2 Q
    else If keys = {vk51}{vk32}{vk31}  ;   Q 2 1
        MsgBox RButton Q 2 1
    Return
    
Exit:
   DllCall("UnhookWindowsHookEx", Ptr, hHookKeybd)
   ExitApp
   
LowLevelKeyboardProc(nCode, wParam, lParam)  { 
    If (spot && wParam = 0x101)  ;  WM_KEYUP := 0x101
    {  
        SaveFormat := A_FormatInteger
        SetFormat, IntegerFast, H
        vk := "vk" SubStr(NumGet(lParam+0, 0, "UInt"), 3)
        SetFormat, IntegerFast, %SaveFormat% 
        keys .= "{" vk "}"  
    }
    Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, Ptr, wParam, Ptr, lParam) 
}

Ну а что там ещё добавлено, я уже не знаю.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

14

Re: AHK: Хоткеи - последовательное нажатие

При запуске ругается на OnExit, Exit - Target label does not exist. Изменил на OnExit, Exit2 и пример заработал, но мои примеры с добавлением RWin::Suspend и if ErrorLevel = 0 все равно не работают((.

15

Re: AHK: Хоткеи - последовательное нажатие

Suspend и Reload никак не мешают работе. Переделанный вариант LControl -> RButton:

Suspend
RWin::Suspend
F12::Reload
RButton Up::
   If IsLabel(Combo)
      GoSub %Combo%
   else Click R
   Combo := ""
Return
#If GetKeyState("RButton","P")
1::
2::
vk51::
   Combo .= A_ThisHotkey
   KeyWait, %A_ThisHotkey%
Return
#If

12:
   MsgBox RButton + 1,2
Return
22vk51:
   MsgBox RButton + 2,2,Q
Return

16

Re: AHK: Хоткеи - последовательное нажатие

Irbis, огромнейшее спасибо! Все работает)) В очередной раз выручаете меня.

17

Re: AHK: Хоткеи - последовательное нажатие

Пожалуйста.