Remap scroll wheel to keyboard

Get help with using AutoHotkey and its commands and hotkeys
WeThotUWasAToad
Posts: 312
Joined: 19 Nov 2013, 08:44

Remap scroll wheel to keyboard

19 Jan 2017, 20:28

Hello,

How would you remap the scroll wheel to the keyboard?

For example, what script would enable you to use Send ^{Up} and Send ^{Down} in place of the scroll wheel?

Some windows can be scrolled using the Up/Down keys but in other cases (eg the window in which I'm writing this post) the Up/Down keys and the scroll wheel have very different functions. I realize that varying the scroll speed is not possible with a key but aside from that, is there a way to get identical functionality?

By the way, another option which came to mind is to have a key which, when held down, enables the mouse to function as the scroll wheel. In that case, it would/might be possible to get variable speed.

Thanks
A ------------------------------ [A LOT OF SPACE] ------------------------------ LOT

"ALOT" is not a word. It never has been a word and it never will be a word.
"A LOT" is 2 words. Remember it as though there's [A LOT OF SPACE] between them.
User avatar
boiler
Posts: 9209
Joined: 21 Dec 2014, 02:44

Re: Remap scroll wheel to keyboard

20 Jan 2017, 01:01

Try this:

Code: Select all

~Control & Up::Send {WheelUp}
~Control & Down::Send {WheelDown}
The ~ keeps the control key from being applied to the wheel up/down.
You can adjust the speed by changing how many wheel scrolls are sent for each key:

Code: Select all

~Control & Up::Send {WheelUp 5}
~Control & Down::Send {WheelDown 5}
WeThotUWasAToad
Posts: 312
Joined: 19 Nov 2013, 08:44

Re: Remap scroll wheel to keyboard

20 Jan 2017, 20:28

This is great boiler. Thanks a bunch!

Is the other option also scriptable?
WeThotUWasAToad wrote:…another option which came to mind is to have a key which, when held down, enables the mouse to function as the scroll wheel.
A ------------------------------ [A LOT OF SPACE] ------------------------------ LOT

"ALOT" is not a word. It never has been a word and it never will be a word.
"A LOT" is 2 words. Remember it as though there's [A LOT OF SPACE] between them.
User avatar
boiler
Posts: 9209
Joined: 21 Dec 2014, 02:44

Re: Remap scroll wheel to keyboard

20 Jan 2017, 21:13

Code: Select all

~Control & Up::
while GetKeyState("Up", "P")
{
	Send {WheelUp 5}
	Sleep, 20
}
return

~Control & Down::
while GetKeyState("Down", "P")
{
	Send {WheelDown 5}
	Sleep, 20
}
return
User avatar
boiler
Posts: 9209
Joined: 21 Dec 2014, 02:44

Re: Remap scroll wheel to keyboard

20 Jan 2017, 21:16

Oh, just re-read and understood what you really said. That could be done, but you'd have to keep sampling the mouse position and send wheel up or down based on the change in position. Not really hard, but not something I can spend the time on right now.
guest3456
Posts: 3245
Joined: 09 Oct 2013, 10:31

Re: Remap scroll wheel to keyboard

11 Feb 2017, 00:59

WeThotUWasAToad wrote: By the way, another option which came to mind is to have a key which, when held down, enables the mouse to function as the scroll wheel. In that case, it would/might be possible to get variable speed.
https://autohotkey.com/board/topic/5528 ... scrolling/

Helgef
Posts: 4495
Joined: 17 Jul 2016, 01:02
Contact:

Re: Remap scroll wheel to keyboard

11 Feb 2017, 06:12

That's nice guest3456.
Also, it is really simple (<30 lines) to make this using MouseDelta.

Code: Select all

#SingleInstance force
md := new MouseDelta("MouseEvent")
return
RButton::
	KeyWait,Rbutton,T0.25
	if !ErrorLevel
	{
		Send,{Rbutton}
		return
	}
	if on
		return
	on:=1
	md.SetState(1)
return
#If on
RButton up::
	md.SetState(0)
	on:=0
return
#if
MouseEvent(MouseID, x := "", y := ""){
	static dy:=0, pDir:=0
	static threshold:=5
	if !y
		return
	dir:=abs(y)=y
	if !(pdir=dir)
		dy:=0
	pDir:=dir
	dy+=y
	if (abs(dy)>threshold)
	{
		Send, % dir ? "{WheelDown}":"{WheelUp}"
		dy:=0
	}
}

; Instantiate this class and pass it a func name or a Function Object
; The specified function will be called with the delta move for the X and Y axes
; Normally, there is no windows message "mouse stopped", so one is simulated.
; After 10ms of no mouse movement, the callback is called with 0 for X and Y
Class MouseDelta {
	State := 0
	__New(callback){
		;~ this.TimeoutFn := this.TimeoutFunc.Bind(this)
		this.MouseMovedFn := this.MouseMoved.Bind(this)

		this.Callback := callback
	}

	Start(){
		static DevSize := 8 + A_PtrSize, RIDEV_INPUTSINK := 0x00000100
		; Register mouse for WM_INPUT messages.
		VarSetCapacity(RAWINPUTDEVICE, DevSize)
		NumPut(1, RAWINPUTDEVICE, 0, "UShort")
		NumPut(2, RAWINPUTDEVICE, 2, "UShort")
		NumPut(RIDEV_INPUTSINK, RAWINPUTDEVICE, 4, "Uint")
		; WM_INPUT needs a hwnd to route to, so get the hwnd of the AHK Gui.
		; It doesn't matter if the GUI is showing, it still exists
		Gui +hwndhwnd
		NumPut(hwnd, RAWINPUTDEVICE, 8, "Uint")
 
		this.RAWINPUTDEVICE := RAWINPUTDEVICE
		DllCall("RegisterRawInputDevices", "Ptr", &RAWINPUTDEVICE, "UInt", 1, "UInt", DevSize )
		OnMessage(0x00FF, this.MouseMovedFn)
		this.State := 1
		return this	; allow chaining
	}
	
	Stop(){
		static RIDEV_REMOVE := 0x00000001
		static DevSize := 8 + A_PtrSize
		OnMessage(0x00FF, this.MouseMovedFn, 0)
		RAWINPUTDEVICE := this.RAWINPUTDEVICE
		NumPut(RIDEV_REMOVE, RAWINPUTDEVICE, 4, "Uint")
		DllCall("RegisterRawInputDevices", "Ptr", &RAWINPUTDEVICE, "UInt", 1, "UInt", DevSize )
		this.State := 0
		return this	; allow chaining
	}
	
	SetState(state){
		if (state && !this.State)
			this.Start()
		else if (!state && this.State)
			this.Stop()
		return this	; allow chaining
	}

	Delete(){
		this.Stop()
		;~ this.TimeoutFn := ""
		this.MouseMovedFn := ""
	}
	
	; Called when the mouse moved.
	; Messages tend to contain small (+/- 1) movements, and happen frequently (~20ms)
	MouseMoved(wParam, lParam){
		Critical
		; RawInput statics
		static DeviceSize := 2 * A_PtrSize, iSize := 0, sz := 0, pcbSize:=8+2*A_PtrSize, offsets := {x: (20+A_PtrSize*2), y: (24+A_PtrSize*2)}, uRawInput
 
		static axes := {x: 1, y: 2}
 
		; Get hDevice from RAWINPUTHEADER to identify which mouse this data came from
		VarSetCapacity(header, pcbSize, 0)
		If (!DllCall("GetRawInputData", "UPtr", lParam, "uint", 0x10000005, "UPtr", &header, "Uint*", pcbSize, "Uint", pcbSize) or ErrorLevel)
			Return 0
		ThisMouse := NumGet(header, 8, "UPtr")

		; Find size of rawinput data - only needs to be run the first time.
		if (!iSize){
			r := DllCall("GetRawInputData", "UInt", lParam, "UInt", 0x10000003, "Ptr", 0, "UInt*", iSize, "UInt", 8 + (A_PtrSize * 2))
			VarSetCapacity(uRawInput, iSize)
		}
		sz := iSize	; param gets overwritten with # of bytes output, so preserve iSize
		; Get RawInput data
		r := DllCall("GetRawInputData", "UInt", lParam, "UInt", 0x10000003, "Ptr", &uRawInput, "UInt*", sz, "UInt", 8 + (A_PtrSize * 2))
 
		x := 0, y := 0	; Ensure we always report a number for an axis. Needed?
		x := NumGet(&uRawInput, offsets.x, "Int")
		y := NumGet(&uRawInput, offsets.y, "Int")
 
		this.Callback.(ThisMouse, x, y)
 
		;~ ; There is no message for "Stopped", so simulate one
		;~ fn := this.TimeoutFn
		;~ SetTimer, % fn, -50
	}
 
	;~ TimeoutFunc(){
		;~ this.Callback.("", 0, 0)
	;~ }
 
}
Edit: Modified hotkeys to RButtoninstead.
guest3456
Posts: 3245
Joined: 09 Oct 2013, 10:31

Re: Remap scroll wheel to keyboard

11 Feb 2017, 10:04

Helgef wrote:That's nice guest3456.
Also, it is really simple (<30 lines) to make this using MouseDelta.
yes that's well done too

But I've been using DragToScroll for years. I've modified it to not move the mouse position while scrolling, and changed the mouse curosr while scrolling, and tweaked the speed and acceleration settings. You can also choose different Wheel Events other than just sending WheelUp/Down clicks

DragToScroll can probably be updated to use MouseDelta

Helgef
Posts: 4495
Joined: 17 Jul 2016, 01:02
Contact:

Re: Remap scroll wheel to keyboard

11 Feb 2017, 13:39

I've modified it to not move the mouse position while scrolling
I feel a bit dumb now, because, one of my reason for doing it with mousedelta was that I thought it would be nice to let the scroll continue even if you hit the edge of the screen, since mousedelta doesn't notice that, so to speak. But I was disappointed when I realised that when I get to the edge, the wheel turns aren't being sent to the same control/window anymore. So obviously, now when you said it, the solution is to keep the cursor fixed. Luckily, with mouse delta all that is needed is blockinput, mousemove :thumbup:
(disclaimer: untested )
WeThotUWasAToad
Posts: 312
Joined: 19 Nov 2013, 08:44

Re: Remap scroll wheel to keyboard

16 Feb 2017, 18:17

guest3456 wrote:I've been using DragToScroll for years. I've modified it to not move the mouse position while scrolling, and changed the mouse curosr while scrolling, and tweaked the speed and acceleration settings. You can also choose different Wheel Events other than just sending WheelUp/Down clicks…
Wow, this is great. Many thanks for your post.

I am particularly interested in what you said about having tweaked the script because it would need some additional tweaking before I could use it. I'm a bit hesitant to elaborate on the reasons why that is the case but will do so on the chance that it may improve the likelihood of finding a solution.

Quite a few years ago, I sustained a spinal cord injury in a motor vehicle accident. As a result, my wrists and hands are paralyzed and I have no sensation in my fingers, etc. For that reason, I cannot grasp a mouse to move it nor can I click buttons or keys with my fingers.

Fortunately, I do have partial use of my shoulder muscles and biceps and thus I can move my arms with fairly normal function. I wear wrist splints and devices on my hands called "typing aids" (as pictured here http://www.danmicglobal.com/dg21012.aspx) which give me function on a keyboard similar to someone who types using only their index fingers. In place of a mouse, I use a large trackball (https://www.kensington.com/us/us/4493/k ... -trackball) on which I can rest my hand and with my shoulder move the cursor.

Despite the above adaptations, a persistent problem has been clicking. The trackball has left and right click buttons of course but for a long time, using them necessitated lifting my arm off the trackball to press one of them with my typing aid. Needless to say, that was slow and cumbersome and my arm would quickly become fatigued. Fortunately I came across a couple of things (one of which is AutoHotKey) several years ago which alleviated that problem to a large degree.

I always have the trackball on the left side of the keyboard because with the keyboard NumberPad on the right, placing the trackball on the right moves it further away from me. With that configuration and with a bit of testing, I was able to significantly improve my clicking ability by simply remapping a couple of keys on the right side of my keyboard as follows:

Code: Select all

F12::LButton
NumpadEnter::RButton
I was excited to download and tryout the DragToScroll script you referenced and I was hopeful that with my remapped NumpadEnter key, the scrolling issue would be resolved. However, I discovered that not to be the case. It's puzzling though because with the remapping shown above, I can hold down the F12 key to drag a folder from one position to another or resize a window, etc.

I took a look at the DragToScroll script you provided and its way over my head. But if it's not too involved and does not require too much time, would you mind attempting an additional bit of tweaking to see if the functionality I'm after is possible? I would be absolutely thrilled if it is. :)

Thanks again
A ------------------------------ [A LOT OF SPACE] ------------------------------ LOT

"ALOT" is not a word. It never has been a word and it never will be a word.
"A LOT" is 2 words. Remember it as though there's [A LOT OF SPACE] between them.
Helgef
Posts: 4495
Joined: 17 Jul 2016, 01:02
Contact:

Re: Remap scroll wheel to keyboard

16 Feb 2017, 18:30

WeThotUWasAToad wrote: Quite a few years ago, I sustained a spinal cord injury in a motor vehicle accident.
I'm sorry to hear that.
Try this,

Code: Select all

#InputLevel,1
NumpadEnter::RButton
#InputLevel,0
For activating ahk hotkeys you might need to use a higher input level.

Good luck.
guest3456
Posts: 3245
Joined: 09 Oct 2013, 10:31

Re: Remap scroll wheel to keyboard

16 Feb 2017, 20:16

Yeah its def possible to get it working. Try Helgef's method for your script and see if it works first

WeThotUWasAToad
Posts: 312
Joined: 19 Nov 2013, 08:44

Re: Remap scroll wheel to keyboard

18 Feb 2017, 00:42

Helgef wrote:Try this,

Code: Select all

#InputLevel,1
NumpadEnter::RButton
#InputLevel,0
For activating ahk hotkeys you might need to use a higher input level.

Good luck.
That gets me a bit closer. The little hand appears and (sometimes) the page starts scrolling with the trackball. But as soon as I change direction, it fails.
A ------------------------------ [A LOT OF SPACE] ------------------------------ LOT

"ALOT" is not a word. It never has been a word and it never will be a word.
"A LOT" is 2 words. Remember it as though there's [A LOT OF SPACE] between them.
guest3456
Posts: 3245
Joined: 09 Oct 2013, 10:31

Re: Remap scroll wheel to keyboard

18 Feb 2017, 00:55

did you try Helge'f script above? you can change the RButton and make it to a different key altogether


Return to “Ask For Help”

Who is online

Users browsing this forum: Aza13, Bing [Bot], milkygirl90 and 47 guests