Log in

No account? Create an account

RavenWorks's Journal


Previous Entry Share
Mapping the scroll wheel to your Logitech G600's buttons with AutoHotKey
I've just spent the past day or so wrestling with a stupid shortcoming of Logitech's drivers..... I have a long and sordid history with the head-shaking incompetence of Logitech software, but I keep buying their products anyway because the hardware is so good... and lately, I was actually starting to think that their days of useless drivers were finally behind them.... but then, I bought a G600 mouse, installed the Logitech Game Software drivers, and discovered that not only do they possess no way to map the extra buttons to the scroll wheel (or map the scroll wheel to anything else), but you can't even just map those buttons to F13-F24 to let AutoHotKey handle it. In fact, not only that, but now I can't use F13-F24 on my G11 keyboard EITHER, even though the OLDER drivers (before updating to LGS replaced them too) could!

So that's awful and stupid, and there would be so many ways to fix it. For one thing, you CAN control the scroll wheel via their LUA scripts, but there's no way to make an event keep firing while holding a button down (without piling up an event queue through a bizarre hack involving the keyboard's M keys, or integrating some external LUA libraries), so that's useless for a 'hold to scroll' feature. All they would have to do is add a timed 'still holding' event to their scripting system, or add 'turn the scroll wheel' to their standard macro system -- or even just give us back F13-F24 as spare signals for something like AutoHotKey to pick up!

But anyway, this post isn't (entirely) just to lambast Logitech's engineers -- as it turns out, AutoHotKey is powerful enough to handle things like this without even NEEDING help from Logitech's drivers, thanks to the AHKHID library. AHK scripts are very very tricky to get going though, there's all sorts of flags you need to know to set before it can capture USB HID signals in the background... but like I said, after a day of fussing with tutorials (and some very helpful advice from folks in the #ahk IRC channel), I now have a working script that will turn G11 and G14 on a G600 mouse into 'hold to scrollwheel' buttons! And since it was such an ordeal, I figured I might as well post the script here publicly, where hopefully Google can find it, and I can save someone else some time.

I'm not going to explain how to install AHK scripts, you can find that elsewhere on the internet, but I WILL explain that in order for this to work properly, you should set the affected Gkeys to UNASSIGNED in the LGS software, in order to prevent both drivers from doing something. Also don't forget to unassign it in the g-shift mapping as well! (This script uses g-shift as a button you can hold to speed up the scrolling.)

If you want to change which keys do what, it's as easy as changing the "upHeldNew := " (etc) lines; unfortunately you WILL need to know what bits (of what bytes) each key represents, but you can find that through just logging all the values and watching what changes when you press the keys. (If you don't know what a bitwise-AND is, find someone who does and ask them for help.)

Anyway, for the script itself! This is my first AHK script (and is based 90% on the AHKHID example files), so there might be really stupid things wrong with it, or ways to make it more performant, but at least it works. ;) )

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

Gui +LastFound

OnMessage(0x00FF, "InputMsg")

GuiHandle := WinExist()

AHKHID_AddRegister(65408, 128, GuiHandle, RIDEV_INPUTSINK )

upHeld := false
downHeld := false
shiftHeld := false

scrollSlow := 50
scrollFast := 25
scrollDelay := scrollSlow

InputMsg(wParam, lParam) {
	Local r, byteOne, byteTwo, upHeldNew, downHeldNew, shiftHeldNew
	Critical    ;Or otherwise you could get ERROR_INVALID_HANDLE
	r := AHKHID_GetInputData(lParam, uData)
	byteOne := NumGet(uData, 1, "UChar")
	byteTwo := NumGet(uData, 2, "UChar")
	upHeldNew := byteTwo & 4
	downHeldNew := byteTwo & 32
	shiftHeldNew := byteOne & 32
	if (shiftHeldNew <> shiftHeld) {
		if (shiftHeldNew) {
			scrollDelay := scrollFast
		} else {
			scrollDelay := scrollSlow
		if (upHeld) {
			SetTimer, RepeatUp, %scrollDelay%
		if (downHeld) {
			SetTimer, RepeatDown, %scrollDelay%
		shiftHeld := shiftHeldNew
	if (upHeldNew <> upHeld) {
		if (upHeldNew) {
			Gosub RepeatUp
			SetTimer, RepeatUp, %scrollDelay%
		} else {
			SetTimer, RepeatUp, Off
		upHeld := upHeldNew

	if (downHeldNew <> downHeld) {
		if (downHeldNew) {
			Gosub RepeatDown
			SetTimer, RepeatDown, %scrollDelay%
		} else {
			SetTimer, RepeatDown, Off
		downHeld := downHeldNew


MouseClick, WheelUp

MouseClick, WheelDown

  • 1
Hey, thanks very much for this! It saved me a TON of work in getting autohotkey to work with the Logitech mouse.

I made a couple of changes to make this more generalizable:

Added the include at the top to incorporate the AHKHID library:
#Include %A_ScriptDir%
#Include AHKHID.ahk

Changed the variable assignment to the following:
byteOne := NumGet(uData, 1, "UChar") << 0
byteTwo := NumGet(uData, 2, "UChar") << 8 ;applies bitshifts
byteThree := NumGet(uData, 3, "UChar") << 16

bytes = % Round(log(byteOne + byteTwo + byteThree) / log(2)) + 1 ;this gets us the actual mouse's G number of the button (shift button is 6)

upHeldNew := bytes = 11 ;true/false check to see if the button pressed is button 11
downHeldNew := bytes = 14
shiftHeldNew := bytes = 6

With these changes, I can now assign functions to all the other buttons.

Oh, tremendous :D I was worried this post might not ever actually turn up in searches, but if it's already been of help then I'm thrilled. :)

And that addition is wonderful! By the time I had it working, I was too sick of wrestling with it all day to generalize it... This is exactly what it needed :) Thanks!

  • 1