1 (изменено: serzh82saratov, 2018-07-27 22:29:19)

Тема: AHK: GetKeyState и Wheel(Key)

Если запустить скрипт, и нажимать 1, то ожидаемо в ToolTip будет 0. Но если "крутнуть" 1 раз WheelUp, то после этого по единице будет всегда 1, почему?


#SingleInstance, Force
#NoEnv 

#InputLevel, 100

#If Func()
WheelUp::Return
#If

Func() {
 	ToolTip % GetKeyState("WheelUp", "P")
	Return 1
}

1::SendInput {WheelUp}

И почему нет блокировки, если WheelUp::Return, а по Func всегда правда. То есть по клавише "1" у меня всегда прокручивает, хотя есть тултип.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

2 (изменено: stealzy, 2018-07-27 22:16:03)

Re: AHK: GetKeyState и Wheel(Key)

Очень странно применять GetKeyState к колесику, не находите?
Если подумать, команда всегда должна возвращать false при передаче первым аргументом WheelUp/Down.

3

Re: AHK: GetKeyState и Wheel(Key)

Нахожу.
Но почему поведение GetKeyState меняется.

если "крутнуть" 1 раз WheelUp, то после этого по единице будет всегда 1

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

4

Re: AHK: GetKeyState и Wheel(Key)

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

5

Re: AHK: GetKeyState и Wheel(Key)

Не понимаю как это объясняет изменение поведения.

И почему нет блокировки

Получается #If для примера не требуется, и "блокировку можно починить", если InputLevel указывать ниже WheelUp.


WheelUp::ToolTip % GetKeyState("WheelUp", "P")
#InputLevel, 100
1::SendInput {WheelUp}
По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

6 (изменено: serzh82saratov, 2018-07-27 23:06:43)

Re: AHK: GetKeyState и Wheel(Key)

stealzy пишет:

Ну так вы же указали опцию "P" - физическое нажатие. Нажатие из скрипта таким не является.

Если запустить скрипт, и нажимать 1, то ожидаемо в ToolTip будет 0. Но если "крутнуть" 1 раз WheelUp, то после этого по единице будет всегда 1

Так я и говорю, что при нажатии "1" после прокрутки, почему всегда 1 становится, если хоткей "1" эмулирует через SendInput {WheelUp}, но до того как тронули колёсико показывает ноль.

Вообще засовывать в #If функцию, выполняющую какое-то действие помимо возврата, плохая идея.

Я же в 5 посте привёл пример без #If.
И идея плоха до ограничения 300мс, написано в #IfTimeout.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

7

Re: AHK: GetKeyState и Wheel(Key)

Это не физическое нажатие, с чего бы там 1 будет?

Так я и говорю что там ожидаемо ноль.

Интерпретатор не получил сообщение о физическом отжатии

В случае с колёсиком события отжатия может вообще не существовать.

Логически вы жмете или физически - какая к черту разница?

Большая. В начале по эмуляции всегда ноль, после одного касания по колёсику, всегда единица.
Если предположить что есть событие отжатия для колёсика, что мешает после сбросить его при событии нажатия.

Надеюсь донес мысль.

Нет, а я.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

8

Re: AHK: GetKeyState и Wheel(Key)

Значит это баг, а если бы не предусмотрено было бы вообще, то и поведение GetKeyState не менялось бы.
Надо писать багрепорт. Да и лечится это должно просто, во всяком случае в хоткеях на хуке, в LowLevelMouseProc есть флаг про это.

Кстати, зачем вам это?

Знать эмулировано нажатие, или нет.

А 0 вначале естественен - после опроса устройств выяснилось что WheelUp "не зажат

Тогда потом откуда единица вылазит, если всё равно кто нажал, нет события, и вообще это не предусмотрено.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

9 (изменено: serzh82saratov, 2018-07-28 00:57:35)

Re: AHK: GetKeyState и Wheel(Key)

Да, это баг, колесо надо обрабатывать отдельно — возвращать всегда 0 .

Ага, хотя бы так для начала.

AHK не записывает внутри себя эту информацию.

Но если обработка идёт внутри хука, то ничего не стоит изменить её на ноль в случае эмулированного нажатия.


#SingleInstance Force
#NoEnv
#Persistent
CoordMode, ToolTip 

MouseHook.Set() 

esc::ExitApp

class MouseHook
{
   Set()  {
      if !this.hook  {
         this.hook := this.SetMouseHook()
         OnExit( this.OnExit := ObjBindMethod(this, "Del") )
      }
   }
   
   Del()  {
      if this.hook  {
         this.SetMouseHook(this.hook)
         this.hook := ""
         OnExit(this.OnExit, 0)
      }
   }
   
   SetMouseHook(hHook := "")  {
      if hHook
         DllCall("UnhookWindowsHookEx", Ptr, hHook)
      else
         Return hHook := DllCall("SetWindowsHookEx", Int, WH_MOUSE_LL := 14
                                                   , Int, RegisterCallback("LowLevelMouseProc", "Fast")
                                                   , Ptr, DllCall("GetModuleHandle", UInt, 0, Ptr)
                                                   , UInt, 0, Ptr)
   }
}

LowLevelMouseProc(nCode, wParam, lParam)  {
   static oMem := [], lpData, size := VarSetCapacity(lpData, 16 + A_PtrSize*2, 0)
	If (wParam != 0x20A)  ;	WM_MOUSEWHEEL
		Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, Ptr, wParam, Ptr, lParam)
	DllCall("RtlMoveMemory", Ptr, &lpData, Ptr, lParam, Ptr, size)
	oMem.Push([wParam, &lpData])
	timer := Func("EventHandling").Bind(oMem)  ; во избежание фризов мыши обработка событий должна
	SetTimer, % timer, -10           ; происходить обязательно по таймеру, а не в теле этой функции
	Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, Ptr, wParam, Ptr, lParam)
}

EventHandling(oMem)  {  
   while event := oMem.RemoveAt(1)  {
      ext       := NumGet(event[2] + 10, "Short")
      flags     := NumGet(event[2] + 12, "UInt") 
      INJECTED  := flags & 1
      ToolTip % (ext = 120 ? "WheelUp" : "WheelDown") "`n" (INJECTED ? "Emulated" : "Physical"), 0, 0, 20
   } 
}

1::SendInput {WheelUp}
2::SendInput {WheelDown}

Конечно понятно, что если через час вызвать GetKeyState исходя из переменной в этой функции, то он вернёт то что было час назад, но если GetKeyState применимо к колёсику изначально не имеет смысла, то это может иметь смысл сразу после посыла колёсика. И как раз с помощью #If может быть однозначно определено как именно в последний раз послано колёсико.

А для взятия логических состояний используется другой метод

Известных методов и так несколько, и без evilC, разговор про то, что это можно сделать встроенным, тем более на фоне бесполезности и невнятности существующего GetKeyState в отношении Wheel(Key).

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

10

Re: AHK: GetKeyState и Wheel(Key)

stealzy пишет:

А вот о том, что {WheelUp Up} не существует, AHK не в курсе.

Почему не в курсе?
У WheelUp и WheelDown нельзя оаределить  состояние, так как при прокручивании посылается только down событие.

11

Re: AHK: GetKeyState и Wheel(Key)

У меня не возвращает:

f11::msgbox % GetKeyState("WheelUp", "P")

12 (изменено: Malcev, 2018-07-28 03:46:51)

Re: AHK: GetKeyState и Wheel(Key)

Так в чем собственно проблема?
Если не существует WheelUp Up события, то смысл обсуждать GetKeyState?
Так возвращает единицу, так как отправляется down, а up не существует.

WheelUp::msgbox % GetKeyState("WheelUp", "P")

Точно так же будет возвращать единицу, если перед нажатием f11 покрутить колесико:

#InstallmouseHook
f11:: msgbox % GetKeyState("WheelUp", "P")

13 (изменено: serzh82saratov, 2018-07-28 11:54:56)

Re: AHK: GetKeyState и Wheel(Key)

Тема про то, что я предлагаю написать в багрепорт о разном поведении GetKeyState применимо к Wheel, до и после нажатия.
И исправить это не на всегда ноль, а всегда ноль для опции L.
А в опции P сохранять флаг физического или нефизического нажатия.
Чтобы в момент нажатия можно было просто определить - физически отправлено или нет.
С клавишами это удобно:


2::ToolTip % GetKeyState("2", "P")
#InputLevel, 100
3::SendInput {2}

Хочется чтобы так же работало и с колёсиком:


WheelUp::ToolTip % GetKeyState("WheelUp", "P")
#InputLevel, 100
3::SendInput {WheelUp}
По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

14

Re: AHK: GetKeyState и Wheel(Key)

Malcev пишет:

Так возвращает единицу, так как отправляется down

Если нажать на 3, тоже отправляется down, но возвращается ноль.

WheelUp::ToolTip % GetKeyState("WheelUp", "P")
#InputLevel, 100
3::SendInput {WheelUp}
По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

15

Re: AHK: GetKeyState и Wheel(Key)

Изменить поведение на хоть сколько нибудь полезное, а логике оно противоречит и сейчас.

ради своего удобства/уменьшения кода в вашем скрипте?

Я за общее благо.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

16

Re: AHK: GetKeyState и Wheel(Key)

Ну если так сделать, оно никому не помешает. А вместо гадания как это воспримется, я написал в багрепорт (так как разное поведение это всё таки ошибка), и заодно внёс предложение.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

17

Re: AHK: GetKeyState и Wheel(Key)

stealzy пишет:

А поведение, которое вы описали, это по сути совершенно другая команда.

Просто это можно будет использовать только в одном случае, посмотрите оба кода в 20 посте, если починить как я предлагаю, то будет одинаково понятное и логичное поведение GetKeyState для всех кнопок, а то что есть сейчас ни к селу ни к городу.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

18

Re: AHK: GetKeyState и Wheel(Key)

serzh82saratov, понял, что ты имеешь в виду.
А почему SendInput?
У меня при нажатии 3 ничего не происходит - тултипа нету.

WheelUp::ToolTip % GetKeyState("WheelUp", "P")
#InputLevel, 100
3::SendInput {WheelUp}

19

Re: AHK: GetKeyState и Wheel(Key)

Странно, может у тебя почему то пустоту возвращает.

ToolTip % GetKeyState("WheelUp", "P") "`nGetKeyState" 
По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

20

Re: AHK: GetKeyState и Wheel(Key)

Malcev пишет:

А почему SendInput?

Не знаю, работает, надо же как то послать эмуляцию.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

21

Re: AHK: GetKeyState и Wheel(Key)

Malcev пишет:

serzh82saratov, понял, что ты имеешь в виду.

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

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

22

Re: AHK: GetKeyState и Wheel(Key)

Я думаю поймет.
Но у меня такой код не работает:

WheelUp::msgbox
#InputLevel, 100
3::SendInput {WheelUp}

Если Sendinput заменить на send то работает.

23

Re: AHK: GetKeyState и Wheel(Key)

Malcev пишет:

Я думаю поймет.

Если интересна тема, можешь добавить пост, а ля - да, это было бы удобно. Когда не один участник, то иногда это помогает обратить внимание на вопрос.

Malcev пишет:

Если Sendinput заменить на send то работает.

Выключил остальные скрипты, Sendinput работает. Вообщем новая тема для расследования.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

24

Re: AHK: GetKeyState и Wheel(Key)

stealzy пишет:

разработчики как вы могут написать свою реализацию.

Да, но это HOOK или HID, а они ещё до кучи обрабатывают все перемещения мыши, затратные решения, тем более на фоне того, что параллельно их же обрабатывает хук AutoHotkey.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

25 (изменено: Malcev, 2018-07-30 00:26:19)

Re: AHK: GetKeyState и Wheel(Key)

serzh82saratov пишет:

Выключил остальные скрипты, Sendinput работает

А точно все? Просто, если в каком-то из них используется клавиатурный хук, то вместо sendinput посылается sendevent.
А с ним у меня работает. Проверял на 3 компах.

serzh82saratov пишет:

Если интересна тема, можешь добавить пост, а ля - да, это было бы удобно.

Если через неделю не ответит, то подниму тему.