1 (изменено: sergeant.coolagin, 2012-07-05 04:24:46)

Тема: AHK: Как отследить сколько времени нажата клавиша?

Допустим, мне нужно сделать какое-то действие по нажатию на клавишу R. Если я просто тыкаю кнопку, то выполняется какое-то одно действие, если зажимаю на опр. период времени - другое.
Я себе это представляю так:


R::
{
*Запустить секундомер и записывать время на секундомере в опр. переменную*
}

R Up::
{
if кнопка была нажата < 50мс до отпускания
{
;Выполнить этот участок кода
}

else if кнопка была нажата > 50мс до отпускания
{
;Выполнить этот участок кода
}
Return

Подскажите, пожалуйста, как отследить сколько времени была нажата кнопка после нажатия и до отпускания?

2

Re: AHK: Как отследить сколько времени нажата клавиша?

Если не использовать таймер, то вот простой вариант

StartTime := A_TickCount
Sleep, 1000
ElapsedTime := A_TickCount - StartTime
MsgBox,  %ElapsedTime% milliseconds have elapsed.

думаю всё понятно, A_TickCount встроенная переменная.
Конечно можно и по другому - вариантов много.

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

3

Re: AHK: Как отследить сколько времени нажата клавиша?

r::
    KeyWait, r
    MsgBox % A_TimeSinceThisHotkey
    return

4

Re: AHK: Как отследить сколько времени нажата клавиша?

Я что-то неправильно понимаю или?.. Почему не работает вот так?

T::
{
StartTime := A_TickCount
}
Return

T Up::
{
UpTime := A_TickCount
ElapsedTime := UpTime - StartTime
MsgBox,  %ElapsedTime% milliseconds have elapsed.
}
Return

Выводит рандомные значения. Иногда 40 мс, иногда 60, иногда 150, иногда 450. Хотя кнопку я зажимаю на 1 секунду или 5 секунд...

5

Re: AHK: Как отследить сколько времени нажата клавиша?

Зачем вы используете фигурные скобки для выделения части подпрограммы горячей клавиши?
Фигурные скобки там не требуются.
Значения не «рандомные», а соответствующие описанному алгоритму.
Если вы желаете видеть «длительность физического нажатия клавиши» используйте KeyWait и A_TimeSinceThisHotkey.

6

Re: AHK: Как отследить сколько времени нажата клавиша?

creature.ws пишет:

Зачем вы используете фигурные скобки для выделения части подпрограммы горячей клавиши?
Фигурные скобки там не требуются.
Значения не «рандомные», а соответствующие описанному алгоритму.
Если вы желаете видеть «длительность физического нажатия клавиши» используйте KeyWait и A_TimeSinceThisHotkey.

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

Почему не работает вот так?

T::
StartTime := A_TickCount
Return

T Up::
UpTime := A_TickCount
ElapsedTime := UpTime - StartTime
MsgBox,  %ElapsedTime% milliseconds have elapsed.
Return

В описании написано:

A_TickCount - Количество миллисекунд, прошедшее со времени перезагрузки компьютера. Сохранив значение A_TickCount в переменной, можно позднее измерить общее время работы. Для этого необходимо вычесть значение этой переменной из последнего значения A_TickCount. Например:
start_time := A_TickCount
Sleep, 1000
elapsed_time := A_TickCount - start_time
MsgBox, прошло %elapsed_time% миллисекунд.
Переменная A_TickCount округляется до 10 мс. Округление управляется командой QueryPerformanceCounter().

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

7 (изменено: creature.ws, 2012-07-05 22:43:08)

Re: AHK: Как отследить сколько времени нажата клавиша?

Почему не работает вот так?

Работает так, это вам кажется, что «не работает».

Нажали вы клавишу, перехватилось autohotkey-ем это событие, выполнилась подпрограмма от T:: до return, продолжаете удерживать клавишу — продолжают «клавиатурой» отправляться нажатия, продолжает выполняться подпрограмма от T:: до return, отпускаете клавишу выполняется подпрограмма от T Up:: до return, видите время прошедшее с момента перехвата отправленного нажатия до момента перехвата отправленного «отпускания».

Возможно, стоит таки обратить внимание на пример из сообщения #3.

8 (изменено: Irbis, 2012-07-05 23:13:09)

Re: AHK: Как отследить сколько времени нажата клавиша?

creature.ws, бывают такие случаи, когда человек не хочет понять доносимой ему мысли...
Тогда проще дать готовый пример, если уж есть желание помочь. А лучше просто "забить" на это дело.

vk52::
   KeyWait, % A_ThisHotkey
   if (A_TimeSinceThisHotkey < 150) ; 50мс маловато, ИМХО
   {
; Выполнить этот участок кода
   }
   else
   {
; Выполнить этот участок кода
   }
return

(Есть подозрение, что если повесить хоткей на R, и не использовать вирт.коды, то следующая тема будет "АНК: помогите, хоткей то работает, то нет")

9 (изменено: sergeant.coolagin, 2012-07-09 04:50:08)

Re: AHK: Как отследить сколько времени нажата клавиша?

creature.ws пишет:

Работает так, это вам кажется, что «не работает».

Нажали вы клавишу, перехватилось autohotkey-ем это событие, выполнилась подпрограмма от T:: до return, продолжаете удерживать клавишу — продолжают «клавиатурой» отправляться нажатия, продолжает выполняться подпрограмма от T:: до return, отпускаете клавишу выполняется подпрограмма от T Up:: до return, видите время прошедшее с момента перехвата отправленного нажатия до момента перехвата отправленного «отпускания».

Возможно, стоит таки обратить внимание на пример из сообщения #3.

Ок. Теперь понял. Я предполагал такое и это вписывается в логику. Но тогда почему, например, вот тут:

RBUTTON::
{
Send {Q}
}
return

Подпрограмма выполнится лишь один раз. Т.е. кнопка Q нажмется лишь один раз после зажатия правой кнопки мыши, а не будет нажиматься до тех пор, пока я не отпущу правую кнопку мыши. Точно так же, как и эта программа нажмет кнопку Q только один раз:

RBUTTON::
{
Send {Q Down}
sleep, 50
Send {Q Up}
}
return
creature.ws пишет:

Возможно, стоит таки обратить внимание на пример из сообщения #3.

Я сразу обратил внимание и попробовал. A_TimeSinceThisHotkey работает отлично. Спасибо вам за подсказки.
Но мне все равно интересно, как же все-таки записать значение теперешнего времени только один раз, сразу после нажатия. Подскажите, пожалуйста, как мне это сделать.
Мне нужно измерять время не только сколько кнопка зажата, но и сколько она была отпущенна.
Только что пришло в голову. Надо будет попробовать так:

vk52::
start_time := A_TickCount
KeyWait, vk52
UpTime := A_TickCount
Return
Irbis пишет:

creature.ws, бывают такие случаи, когда человек не хочет понять доносимой ему мысли...
Тогда проще дать готовый пример, если уж есть желание помочь. А лучше просто "забить" на это дело.

vk52::
   KeyWait, % A_ThisHotkey
   if (A_TimeSinceThisHotkey < 150) ; 50мс маловато, ИМХО
   {
; Выполнить этот участок кода
   }
   else
   {
; Выполнить этот участок кода
   }
return

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

10

Re: AHK: Как отследить сколько времени нажата клавиша?

Клавиатура с автоповтором (сделано для удобства ввода большого количества одинаковых символов), у мыши автоповтора нет.

sergeant.coolagin пишет:

...Q нажмется лишь один раз после зажатия правой кнопки мыши, а не будет нажиматься до тех пор, пока я не отпущу правую кнопку мыши.

Следовательно Вам нужен некий цикл, и проверка состояния клавиши:

SetKeyDelay, 250

RButton::
   While, GetKeyState(A_ThisHotkey, "P")
      Send, {vk51} ; q
   Return
RButton::
   While, GetKeyState(A_ThisHotkey, "P")
   {
      Send, {vk51} ; q
      Sleep, 250
   }
   Return
RButton::
   Loop
   {
      Send, {vk51} ; q
      Sleep, 250
      If !GetKeyState(A_ThisHotkey, "P")
         Break
   }
   Return
sergeant.coolagin пишет:

Мне нужно измерять время не только сколько кнопка зажата, но и сколько она была отпущенна.

Я так концовку предложения понял, что нужно знать, сколько времени прошло с момента предыдущего отжатия этой клавиши в момент её текущего отжатия:

SetFormat, Float, 0.3 ; выставляем число знаков после запятой
ReleaseTime:=A_TickCount ; чтобы переменная не была пустой, присвоим ей значение,...
; ...тем самым при первом отжатии у нас будет показатель времени с момента запуска скрипта

vk52:: ; r
   StartTime:=A_TickCount ; присваиваем переменной текущее время
   KeyWait, % A_ThisHotkey ; тут понятно, что происходит...
   OldReleaseTime:=ReleaseTime ; присваиваем переменной время с предыдущего отжатия,...
   ReleaseTime:=A_TickCount ; ...а этой время текущего отжатия
   ; (A_TickCount-StartTime)/1000 собственно тоже самое, что и A_TimeSinceThisHotkey/1000
   TrayTip,, % "время с момента нажатия:`t`t"(A_TickCount-StartTime)/1000
          . "`nвремя с момента предыдущего отжатия:`t"(ReleaseTime-OldReleaseTime)/1000
   Return

11 (изменено: sergeant.coolagin, 2012-07-10 03:08:46)

Re: AHK: Как отследить сколько времени нажата клавиша?

Grey пишет:

Я так концовку предложения понял, что нужно знать, сколько времени прошло с момента предыдущего отжатия этой клавиши в момент её текущего отжатия:

SetFormat, Float, 0.3 ; выставляем число знаков после запятой
ReleaseTime:=A_TickCount ; чтобы переменная не была пустой, присвоим ей значение,...
; ...тем самым при первом отжатии у нас будет показатель времени с момента запуска скрипта

vk52:: ; r
   StartTime:=A_TickCount ; присваиваем переменной текущее время
   KeyWait, % A_ThisHotkey ; тут понятно, что происходит...
   OldReleaseTime:=ReleaseTime ; присваиваем переменной время с предыдущего отжатия,...
   ReleaseTime:=A_TickCount ; ...а этой время текущего отжатия
   ; (A_TickCount-StartTime)/1000 собственно тоже самое, что и A_TimeSinceThisHotkey/1000
   TrayTip,, % "время с момента нажатия:`t`t"(A_TickCount-StartTime)/1000
          . "`nвремя с момента предыдущего отжатия:`t"(ReleaseTime-OldReleaseTime)/1000
   Return

Спасибо. Это то, что мне нужно.

Grey пишет:

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

В конечном итоге мне нужно измерять время между нажатием и отпусканием; между предыдущим отпусканием и текущим нажатием; между предыдущим отпусканием и текущим откусканием клавиши... И это все нужно мерять между разными хоткеями. Поэтому, ИМХО, A_TimeSinceThisHotKey не очень удобно.

Понял насчет клавиатуры и мыши, автоповтора нажатия и т.д. Спасибо всем за разъяснения и советы.