Page 1 of 1

GetKeyState for Wheel

Posted: 28 Jul 2018, 05:10
by serzh82saratov

Code: Select all

WheelUp::ToolTip % GetKeyState("WheelUp", "P")
#InputLevel, 100
3::Send {WheelUp}
If you first press 3, there will always be false, if you touch WheelUp, always true, before the next launch.
I understand that Wheel does not have an Up event, but you can make a definition of a physical or emulated push, since this can now be done with the rest of the keys.
For example, button 2.

Code: Select all

2::ToolTip % GetKeyState("2", "P")
#InputLevel, 100
3::Send {2}
Since at the moment, GetKeyState for Wheel does not work, and is more misleading, I suggest keeping the flag for the last pressing of Wheel - physical or emulated, from this will be at least some useful.
In any case, it is not difficult to do for hotkeys mousehook.

Code: Select all

#SingleInstance Force
#NoEnv
#Persistent
CoordMode, ToolTip 

MouseHook.Set() 

1::Send {WheelUp}
2::Send {WheelDown}
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") 
   } 
}


Re: GetKeyState for Wheel

Posted: 07 Aug 2018, 07:40
by malcev
May be it would be logical to remove mouse wheel from recognition and return empty string?

Re: GetKeyState for Wheel

Posted: 07 Aug 2018, 20:25
by lexikos
I'm not sure how it could be misleading (WheelUp is not a key or button and doesn't have any state, so what are you expecting?), but at least using GetKeyState to retrieve the last wheel delta value is a good idea. v2-alpha removes all other uses of A_EventInfo, so if this is done, A_EventInfo can be removed.
but you can make a definition of a physical or emulated push, since this can now be done with the rest of the keys.
I do not understand. Firstly, "the rest of the keys" is inappropriate since WheelUp is not a key (it represents a state transition of the wheel). Secondly, as you said, there is no up event. Keys have down and up events and state (pressed or not, down or up) based on these events. Whether it is physical or emulated is irrelevant. Send {2} will send a down event and an up event, whereas Send {WheelUp} will just send a WheelUp event.

Re: GetKeyState for Wheel

Posted: 08 Aug 2018, 04:02
by malcev
lexikos wrote:I'm not sure how it could be misleading (WheelUp is not a key or button and doesn't have any state, so what are you expecting?)
I am expecting to get empty string, because:
If KeyName is invalid or the state of the key could not be determined, an empty string is returned.
https://autohotkey.com/docs/commands/GetKeyState.htm
And it is strange thing:

Code: Select all

WheelUp::ToolTip % GetKeyState("WheelUp", "P")
#InputLevel, 100
f11::Send {WheelUp}
If we run this code and press f11 then we will get 0.
After that we press wheelUp button - we will get 1.
After that we press f11 then we will get 1.

But this code works OK - always shows 1.

Code: Select all

WheelUp::ToolTip %A_EventInfo%.
#InputLevel, 100
f11::Send {WheelUp}

Re: GetKeyState for Wheel

Posted: 08 Aug 2018, 05:00
by Helgef
KeyName wrote:This can be just about any single character from the keyboard or one of the key names from the key list
The mouse wheels are in the key list. Since you do not get an empty string back, there was no failure in determining the state, so it works as documented. I can sympathise with the idea that the mouse wheels shouldn't be valid input, but now they are, so we have to hope for v2, unless there is some good reason they should be valid as input which we have failed to realise yet.

Cheers.

Re: GetKeyState for Wheel

Posted: 08 Aug 2018, 08:47
by serzh82saratov
I understand that GetKeyState in any cases is not needed for the Wheel, so it does not matter how it behaves now. But...
Whether it is physical or emulated is irrelevant.
It still can carry some kind of benefit, for example, I want it to be physical pressures that are blocked, and for all other keys it's easy to do.

Code: Select all

; before testing, first click WheelUp
#If Func()
WheelUp::
Enter::Return 
#If

#InputLevel, 100
1::Send {Enter}
2::Send {WheelUp}

Func() {	
	ToolTip % GetKeyState(A_ThisHotkey, "P") 
 	Return GetKeyState(A_ThisHotkey, "P")
}
It turns out that Enter only works when you press 1 as I need it, and WheelUp in no case.

Re: GetKeyState for Wheel

Posted: 08 Aug 2018, 09:04
by serzh82saratov
That is, the benefit of GetKeyState for Wheel can only be at the very moment of pressing, so let it be at least the way, the more it is very easy to do.