1 (изменено: Indomito, 2013-11-03 08:46:42)

Тема: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

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

Скрипт практически переносим в другой скрипт, а для полной его мобильности следует сделать.
1. Вместо явного объявления клавиши RShift следует написать -
     HotKey %имя переменной(клавиша)%, МеткаПодпрограммы, On
2. Заменить метки подпрограмм:
- RShift(1) и RShift(2)
- на %имя переменной(клавиша)%(1) и %имя переменной(клавиша)%(2) соответственно.

Я такой вариант не проверял, но должно работать.

И ещё заблокирован автоповтор (он в моём случае мешал) методом посылки нажатой клавиши (RShift)

Send, {%сBaseKey% Down}
KeyWait, % A_ThisHotkey  
Send, {%сBaseKey% Up}

Вот сам скрипт

+ открыть спойлер
;----- Общий вариант для RShift с фунцией посылки 1, 2 и 3 без автоповтора.
#Persistent
  cAloneKey             := "1"
  cDoubleKey            := "2"
  cHoldingKey           := "3"
  сBaseKey              := "RShift"
  сPause_PressKey       := 500 
  cCountHoldingBaseKey  := 20
  cWaitHoldingBaseKey   := сPause_PressKey//cCountHoldingBaseKey
return

#UseHook, On

RShift::  
  if (fnHoldingBaseKey(cWaitHoldingBaseKey, cCountHoldingBaseKey)) ;Удержание
      {
        ToolTip, Удержание RShift = send %cHoldingKey%
          Send, {%cHoldingKey% Down}
          sleep 10
          Send, {%cHoldingKey% Up}
          Sleep, 1500
          ToolTip          
        Send, {%сBaseKey% Down}
        KeyWait, % A_ThisHotkey  
        Send, {%сBaseKey% Up}
        return
      } 
    else 
      Gosub, sbPressCountKeys
return  

RShift(1):          ;Одиночный 
  ToolTip, Одиночный RShift = send %cAloneKey%
  Send, {%cAloneKey% Down}
  sleep 10
  Send, {%cAloneKey% Up}
  Sleep, 1500
  ToolTip  
  Send, {%сBaseKey% Down}
  KeyWait, % A_ThisHotkey  
  Send, {%сBaseKey% Up}  
Return

RShift(2):          ;Двойной
  ToolTip, Двойной RShift = send %cDoubleKey%
  Send, {%cDoubleKey% Down}
  sleep 10
  Send, {%cDoubleKey% Up}  
  Sleep, 1500
  ToolTip
  Send, {%сBaseKey% Down}
  KeyWait, % A_ThisHotkey  
  Send, {%сBaseKey% Up}  
Return

#UseHook, Off


sbPressCountKeys:
  ;Если пауза меньше "сPause_PressKey" количества миллисекунд, то нажатие двойное, а если больше, то 
  ; оно расценивается как 2 одиночных.
  If not сSecond_PressKey
  {
    сSecond_PressKey := 1
    SetTimer, sbDoublePressKey, -%сPause_PressKey%
  }
  Else
  {
    сSecond_PressKey := 0
    SetTimer, %A_ThisHotkey%(2), -1
  }
Return

sbDoublePressKey:
  If not сSecond_PressKey
    Return
  сSecond_PressKey := 0
  SetTimer, %A_ThisHotkey%(1), -1
Return

fnHoldingBaseKey(vSleep, vCount)
  {
   Global сBaseKey  
    while ((GetKeyState(сBaseKey, "P")) && vCount)
      {
       sleep %vSleep%
       vCount--
      }
    if (vCount)
         return false
    return  true
  }

 

Если не нужна отладка, то везде убрать два фрагмента:

+ открыть спойлер
ToolTip, C текстом

и

Sleep, 1500
ToolTip

Оптимальные значения сPause_PressKey  и cCountHoldingBaseKey для игр и мышки:

+ открыть спойлер
  1. сPause_PressKey  := 300, cCountHoldingBaseKey  :=  50

  2. Для игры "The Witcher 2 - Assassins of Kings EE" это соотношение значений -  300 и 25

  3. Лучше первое значение не трогать, т.е. сPause_PressKey  := 300 или 500, а менять второе (число шагов цикла).

  4. Если сPause_PressKey будет больше 500 или меньше 300, то будут проблемы с двойным нажатием и удержанием.

  5. Eсли cCountHoldingBaseKey будет больше 75, то удержание вызовет одиночное нажатие.



P.S. По сути я этот скрипт писал для "The Witcher 2 - Assassins of Kings EE", т.к. там три клавиши достать/убрать серебряный меч, достать/убрать стальной меч и убрать оружие - это дело мне надоело, ну я сделал одну клавишу с тремя функциями

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

2

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

Что-то знакомое есть в коде. Не отсюда: http://forum.script-coding.com/viewtopic.php?id=490 ?

3

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

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

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

4 (изменено: dredj, 2014-05-22 12:27:05)

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

~sc155::
if (A_PriorHotkey <> "~sc155" or 

A_TimeSincePriorHotkey > 400)
{
    KeyWait, sc155
    return
}
MsgBox !!!!!!!!!!.
return

Выдаёт

5

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

Проблема в KeyName? Если да то как его решить? Не могу понять куда его вставить и как.

6 (изменено: Indomito, 2014-05-22 12:47:35)

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

dredj а какое отношение твой скрипт имеет к самому  топику то?

Ну, да ладно....

Проблема в записи IF - надо так писать

~sc155::
if ((A_PriorHotkey <> "~sc155") or  (A_TimeSincePriorHotkey > 400))
{
    KeyWait, sc155
    return
}
MsgBox !!!!!!!!!!.
return

ну это как минимум... не разбивай конструкцию, это же AHK, а не С++ или JS.

Потом посмотрим, где будут косяки, я на прямую их не вижу.

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

7

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

Теперь так

8

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

{sc155}

9 (изменено: dredj, 2014-05-22 13:08:42)

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

Кстати это немножко видоизменённый пример из http://www.script-coding.com/AutoHotkey/KeyWait.html

10

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

YMP пишет:
{sc155}

И так пробовал, тоже не робит.

11

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

dredj я как понимаю скрипт был написан на основе FAQ-ru?

~RControl::
if (A_PriorHotkey <> "~RControl" or A_TimeSincePriorHotkey > 400)
{
    ; Слишком большой промежуток между нажатиями, так что это не двойное нажатие.
    KeyWait, RControl
    return
}
MsgBox Вы дважды нажали правый Control.
return

ну если да, то она же обрабатывает не скан-код.

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

12

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

А как его заставить обработать именно скан?

13

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

А мы что, обязаны знать наизусть, какой клавише соответствует sc155? Или всё же снизойдёте к нам и подскажете?

14

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

В общем, KeyWait со сканкодами не работает, как я понимаю. Так что облом.

15

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

YMP пишет:

А мы что, обязаны знать наизусть, какой клавише соответствует sc155? Или всё же снизойдёте к нам и подскажете?

В том и дело что у клавиши нет имени, кроме "Unknown: 0хЕ055(Е055)" который выдал утилита SharpKeys,  поэтому спрашивал про KeyName.

16 (изменено: dredj, 2014-05-22 13:30:34)

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

В FAQ KeyWait в параметре KeyName сказано что "может быть указан код виртуальной клавиши, например, vkFF"(вирт.код я знаю), вот я не знаю куда и как этот параметр вставить в скрипте.

17 (изменено: Indomito, 2014-05-22 13:38:12)

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

Даю ответ, что бы более не искать.

+ VkScCode_64.ahk
#Persistent
   OnExit, Exit
   hHookKeybd := DllCall("SetWindowsHookEx"
      , Int, WH_KEYBOARD_LL := 13
      , Ptr, RegisterCallback("LowLevelKeyboardProc", "Fast")
      , Ptr, DllCall("GetModuleHandle", UInt, 0, "Ptr")
      , UInt, 0, "Ptr")
   Return
 
Exit:
   DllCall("UnhookWindowsHookEx", Ptr, hHookKeybd)
   ExitApp
 
LowLevelKeyboardProc(nCode, wParam, lParam)
{
   Critical
   SetFormat, Integer, H
   ToolTip, % wParam . "| vkCode: " . NumGet(lParam+0, 0, "UInt") . " scCode: " . NumGet(lParam+0, 4, "UInt")
      . " Extended: " . NumGet(lParam+0, 8, "UInt") & 1 . " Time: " . NumGet(lParam+0, 12, "UInt")
   Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, Ptr, wParam, Ptr, lParam)
}

Запусти, нажми и напиши что за странная клавиша без имени

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

18 (изменено: dredj, 2014-05-22 13:50:03)

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

0x1011| vkCode: OxFF scCode: 0x55 Extended: 0x1 Time: 0x419222
Странна другой скрипт для определении скан кода показала sc155.

19

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

А имя то  клавиши есть?
Если -  vkCode: OxFF то надо использовать scCode: 0x55

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

20

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

Indomito пишет:

А имя то  клавиши есть?
Если -  vkCode: OxFF то надо использовать scCode: 0x55

А больше нечего, нету имени кажись.

21 (изменено: serzh82saratov, 2014-05-22 16:41:38)

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

YMP пишет:

В общем, KeyWait со сканкодами не работает, как я понимаю. Так что облом.

Как так:

KeyWait vkDsc1C, D
MsgBox Вы нажали Enter


dredj пишет:

А больше нечего, нету имени кажись.

Попоробуй этим, вкладка "Button".
А так на лицо:

KeyWait vkFFsc55, D
MsgBox Вы нажали vkFFsc55
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

22

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

serzh82saratov пишет:

Как так:

KeyWait vkDsc1C, D
MsgBox Вы нажали Enter

А как этак?


KeyWait vkDscABCDEF, D
MsgBox Вы нажали Enter

23

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

Разве это говорит о том, что KeyWait со сканкодами не работает.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

24

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

А о чём это говорит?

25

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

serzh82saratov пишет:

Попоробуй этим, вкладка "Button".

Пробиндил кнопку на дефолт той самой утилитой, теперь у кнопки нормальное имя и теперь кажись всё решилось. Всем спасибо.

26

Re: AHK: Рабочий скрипт одиночного/двойного/удержания нажатия на клавишу

И да, вы извините за мой русский, я долеко не русский и мысль формулирую долго да ещё и результат не очень.