Blink hotkey for NumLock key doesn't work

Report problems with documented functionality
jaejunks
Posts: 2
Joined: 29 Sep 2016, 02:45

Blink hotkey for NumLock key doesn't work

02 Apr 2017, 01:41

In below simplified code, the blind hotkey (*) for the NumLock key doesn't work at all, but it works for CapsLock and ScrollLock keys. i.e. the NumLock LED is never toggled when I pressed the NumLock key. The CapsLock and ScrollLock keys work as normal and toggle their LED.

Without AutoHotkey running, the NumLock key works properly (i.e. it's not a dead/broken key). I don't use any other keyboard shortcut/macro application, and my USB keyboard doesn't use a third party device driver.

Code: Select all

#UseHook On

*CapsLock::
SendInput {Blind}{CapsLock down}
return

*CapsLock up::
SendInput {Blind}{CapsLock up}
return

*NumLock::
SendInput {Blind}{NumLock down}
return

*NumLock up::
SendInput {Blind}{NumLock up}
return

*ScrollLock::
SendInput {Blind}{ScrollLock down}
return

*ScrollLock up::
SendInput {Blind}{ScrollLock up}
return
I need to have this hotkey setup because I need the NumLock key to behave differently based on some global variables. e.g. aside from toggling the CapsLock state, based on the global variables, it may be mapped to a different key, execute an application, or something else.
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: Blink hotkey for NumLock key doesn't work

02 Apr 2017, 02:08

This is due to Windows behaviour, and is not an AutoHotkey bug.

The hotkey is detected and sends the key-down/up event as requested, but the OS does not respond as you expect it to.

AutoHotkey does send some extra NumLock key events you did not ask for, but if it didn't, things would be worse. This is the related code (and comments):

Code: Select all

	// This handles the troublesome Numlock key, which on some (most/all?) keyboards
	// will change state independent of the keyboard's indicator light even if its
	// keydown and up events are suppressed.  This is certainly true on the
	// MS Natural Elite keyboard using default drivers on WinXP.  SetKeyboardState()
	// doesn't resolve this, so the only alternative to the below is to use the
	// Win9x method of setting the Numlock state explicitly whenever the key is released.
	// That might be complicated by the fact that the unexpected state change described
	// here can't be detected by GetKeyboardState() and such (it sees the state indicated
	// by the numlock light on the keyboard, which is wrong).  In addition, doing it this
	// way allows Numlock to be a prefix key for something like Numpad7, which would
	// otherwise be impossible because Numpad7 would become NumpadHome the moment
	// Numlock was pressed down.  Note: this problem doesn't appear to affect Capslock
	// or Scrolllock for some reason, possibly hardware or driver related.
	// Note: the check for KEY_IGNORE isn't strictly necessary, but here just for safety
	// in case this is ever called for a key that should be ignored.  If that were
	// to happen and we didn't check for it, and endless loop of keyboard events
	// might be caused due to the keybd events sent below.
	if (aHook == g_KeybdHook)
	{
		KBDLLHOOKSTRUCT &event = *(PKBDLLHOOKSTRUCT)lParam;
		if (aVK == VK_NUMLOCK && !aKeyUp && !IsIgnored(event.dwExtraInfo))
		{
			// This seems to undo the faulty indicator light problem and toggle
			// the key back to the state it was in prior to when the user pressed it.
			// Originally, I had two keydowns and before that some keyups too, but
			// testing reveals that only a single key-down is needed.  UPDATE:
			// It appears that all 4 of these key events are needed to make it work
			// in every situation, especially the case when ForceNumlock is on but
			// numlock isn't used for any hotkeys.
			// Note: The only side-effect I've discovered of this method is that the
			// indicator light can't be toggled after the program is exitted unless the
			// key is pressed twice:
			KeyEvent(KEYUP, VK_NUMLOCK);
			KeyEvent(KEYDOWNANDUP, VK_NUMLOCK);
			KeyEvent(KEYDOWN, VK_NUMLOCK);
		}
		UpdateKeybdState(event, aVK, aSC, aKeyUp, true);
	}
I need to have this hotkey setup because I need the NumLock key to behave differently based on some global variables.
That's faulty logic. This hotkey setup is what you are trying to use to achieve your end goal, but obviously this setup isn't working. So why do you need to have this setup and not some other setup which works? ;)

When you want a key to have its native function, don't override it. Overriding a key and then sending that same key is guaranteed to have some kind of side-effect, whether it's how this or other scripts treat the key, how some other application treats the key, or (as in this case) how the OS treats the key.

There are two ways to override a key only when you actually need to:
  1. Use the Hotkey command to register/enable the hotkey when it is needed and unregister/disable it when it is not.
  2. Use the #If directive (above the hotkey) with an expression which evaluates to true while the hotkey is needed and false at any other time.
jaejunks
Posts: 2
Joined: 29 Sep 2016, 02:45

Re: Blink hotkey for NumLock key doesn't work

02 Apr 2017, 13:17

However, when a keyboard low level hook handler which was set using SetWindowsHookEx() unconditionally calls CallNextHookEx(), the NumLock key works normally.
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: Blink hotkey for NumLock key doesn't work

02 Apr 2017, 16:24

No, if the hook unconditionally calls CallNextHookEx() and returns 0, the NumLock key works normally. But in that case it isn't blocked, so it would be like using the tilde prefix (~*NumLock::).

If the hook returns 1 for NumLock, even after calling CallNextHookEx(), the keydown/keyup message is blocked but the NumLock state toggles without changing the indicator light.

Return to “Bug Reports”

Who is online

Users browsing this forum: No registered users and 46 guests