Page 1 of 1

How to use GetKeyState to "batch" key combination code?

Posted: 19 Sep 2016, 13:44
by GollyJer
I found code on the forum to do the following... and it works.

Code: Select all

CapsLock::
    KeyWait, CapsLock
	If (A_PriorKey="CapsLock")
		SetCapsLockState, % GetKeyState("CapsLock","T") ? "Off" : "On"
return

#If GetKeyState("CapsLock", "P")
   a:: MsgBox % "You pressed CapLock + a"
   b:: MsgBox % "You pressed CapLock + b"
#If
I'd like to do the same with the Control key and thought this would work but it doesn't.

Code: Select all

Control::
    KeyWait, Control
return

#If GetKeyState("Control", "P")
   a:: MsgBox % "You pressed Control + a"
   b:: MsgBox % "You pressed Control + b"
#If
What am I missing? Thanks!

Re: How to use GetKeyState to "batch" key combination code?

Posted: 19 Sep 2016, 14:20
by Nextron
This is kind of the basic stuff: https://autohotkey.com/docs/Hotkeys.htm#Symbols

Control is a modifier key. Hotkeys are usually defined either with or without modifier key requirements. You defined the hotkey a without modifiers. So it will only trigger if no modifiers are pressed. Then you created an additional requirement that -at the same time- control should be physically down. So that is not a common situation. Use this instead:

Code: Select all

^a:: MsgBox You pressed Control + a
^b:: MsgBox You pressed Control + b
Unless you deliberately want to suppress the key repeat of control?

Re: How to use GetKeyState to "batch" key combination code?

Posted: 20 Sep 2016, 06:56
by GollyJer
Hi Nextron. Thanks for the reply.
Your example is cleary the correct and recommended way to create a Ctrl+a hotkey.
I realize this is basic stuff. I'm asking so I can learn a little more about how AHK functions.

Why does the code with CapsLock work (holding down CapsLock + a will fire the messagebox)?
But holding down Control + a never fires a message box?
Other than the line keeping Capslock from toggling, the code is identical.

Why does one work and not the other?

Thanks!

Re: How to use GetKeyState to "batch" key combination code?

Posted: 20 Sep 2016, 08:17
by Nextron
Control, Alt, Shift and Windows are modifier keys, ideally suited for hotkey combinations (These buttons are even wired differently on most keyboards). Within AHK they have a special prefix for hotkey definition; ^, !, + and # respectively. These will make the hotkey only trigger when those modifiers are pressed. Similarly, not using those prefixes will make the hotkey not trigger when that modifier is pressed. So you defined a hotkey to trigger when the control key is logically up, but physically down (these's a difference ;) ). You can remove this explicit matching by making it trigger on any combination by using the * prefix, like: *a::Soundbeep.

CapsLock on the other hand isn't a modifier so hotkeys aren't excluded from triggering based on its state unless you explicitly define it like you have.

Re: How to use GetKeyState to "batch" key combination code?

Posted: 23 Sep 2016, 13:07
by GollyJer
Cool. It makes sense now.

Given that info, this is the working version.

Code: Select all

#If GetKeyState("Control", "P")
   *a:: MsgBox % "You pressed Control + a"
   *b:: MsgBox % "You pressed Control + b"
#If
Which behaves like...

Code: Select all

^a:: MsgBox % "You pressed Control + a"
^b:: MsgBox % "You pressed Control + b"
Thanks!

Re: How to use GetKeyState to "batch" key combination code?

Posted: 23 Sep 2016, 13:31
by Nextron
Just for you to get the complete picture, the above example behaves almost like: *^a:: MsgBox % "You pressed Control + a"
Any modifiers can be pressed as long as control is one of them. The bottom example works if only control is pressed.

Also, the top example checks the physical state of the key, while the others check the logical state. This distinction becomes apparent when you remap other keys to/from control.