Unable to utilize numpad as my keyboard trigger - autohotkey

I am trying to change media using Autohotkey. I want to utilize Left Shift (<+) + LWin (<#) + Numpad8. Here is my code below but it does not work. I am having issues trying to utilize my Numpad8 to change music. I already know I can use the regular numbers on top of my keyboard but I would like to utilize my numpad instead. Please advise, thanks.
<+<#NumPad8::
Send {Media_Next}
return

From the Numpad Section of the docs, they mention:
If NumLock is OFF but Shift is pressed, the system temporarily releases Shift and acts as though NumLock is ON.
This appears to also be applicable vice versa, as holding Shift while Numlock is on before clicking NumPad8 instead appears to send NumpadUp instead of Shift+Numpad8.
We can work around this by creating a Hotkey to activate when Win+NumpadUp[+ any other modifier keys (such as Shift)] is pressed, and then check ourselves whether Shift and Numlock are active. If they are, then we Send the Media key.
Current Code:
*#NumPadUp::
if(GetKeyState("NumLock", "T") and GetKeyState("Shift", "P"))
Send {Media_Next}
return
However, if we hold down Win+Shift while repeatedly pressing the key, it appears to revert back from NumpadUp to Numpad8. In order to account for this, we can reuse the body of the previous Hotkey in a new Hotkey that activates when *#NumPad8 is used.
Final Code:
*#NumPadUp::
*#NumPad8::
if(GetKeyState("NumLock", "T") and GetKeyState("Shift", "P"))
Send {Media_Next}
return
Edit: Thank you #samthecodingman for bringing up an optimization that I missed- code has been edited to include this

Related

AHK script designed to toggle based on CapsLock Status always toggles on 'off' and I cannot change it to 'on'

(Note: Very new to scripting, borrowed some phrases from other scripts I've online.) I have Carpal Tunnel and play a video game that does not have any key-bind options not set to the F1-F0 keys so I want to rebind the F1-F4 keys to Z-V but only when capslock is enabled, to prevent being unable to type in chat windows and in other programs without closing the script. However, the script re-binds the basic keys to the f-keys ONLY when capslock is OFF, rather than allowing me to change it to ON. Not sure why.
I've tried 'hotfixing' it by rebinding it to Numlock, but when I moved to CapsLock changing 'OFF' to 'ON' did not keep the script from only rebinding the keys while CapsLock was OFF. Not sure why.
$Z::
GetKeyState, state, NumLock, T
if state = D ; NumLock is toggled ON
send, {z}
else
send, {F1}
Return
$X::
GetKeyState, state, NumLock, T
if state = D ; NumLock is toggled ON
send, {x}
else
send, {F2}
Return
etc...
etc...
I expected changing the value 'OFF' to 'ON' would result in the key rebinds only happening during the CapsLock status being toggled on.
Have you checked if you restarted the script after making changes? It's a very common mistake, not only among beginners. According to your example, your keys Z..V should behave as F1..F4 only when the NumLock is toggled off.
Given the nature of your script, you can consider to add the directive #SingleInstance Force which will automatically replace any older instance of your script by a new one each time you run the script again, making testing easier.
You can do conditional binding much easily with an #if directive, which makes the subsequent hotkeys and hotstring only effective when a condition is met.
To check the state of the CapsLock or NumLock keys you can also use the built-in function GetKeyState, which for toggle keys, such as CapsLock or NumLock, with the "T" mode returns either True or False based on the toggle state of the key.
Also, if you want to remap keys, you can simply write the target key's name at the right of the hotkey, which will completely bind the keys, on both Down and Up events. However, for this to work, you must specify your triggering keys as lowercase, since specifying uppercase would only trigger the remap when pressed the keys with the Shift key as well (the CapsLock would have no effect), and that is not your desired behaviour. [More on remapping keys]
Here is an example of what you could do:
#If GetKeyState("CapsLock", "T")
z::F1
x::F2
c::F3
v::F4
Note that, since key remapping always uses the keyboard hook (because it needs to register the Up events as well), there is no need to use the $ prefix in your hotkeys at all.
Nonetheless, you can automate your script even more if you use as condition for your hotkeys the currently active window and bind them to your game using the #IfWinActive directive.
However if there are also chats in the game, you might want to combine both conditions in a single #If, using the built-in function WinActive like this:
#If GetKeyState("CapsLock", "T") and WinActive("My Game Title")
z::F1
; ...
You can check how to narrow your search for the window by its title on the documentation for the WinTitle parameter.
If you want to improve your script even further, you could explore if there is any detectable change on the game window when the chat is active, such as if a certain control exists (you can check that as if it was another window using the WinExist function to check for a certain Window class.
To seek for such changes, you can use a script as the following (from the MouseGetPos documentation):
#Persistent
SetTimer, WatchCursor, 100
return
WatchCursor:
MouseGetPos, , , id, control
WinGetTitle, title, ahk_id %id%
WinGetClass, class, ahk_id %id%
ToolTip, ahk_id %id%`nahk_class %class%`n%title%`nControl: %control%
return
Which would allow you to see the window information of the windows below your mouse. You can use it to check for the name or class of the chat control by placing your mouse over it.
However, keep in mind that many games do not use Windows controls at all in their interfaces and rather just draw them on screen by themselves, so if you're trying this and can't progress much after a while you shouldn't waste too much time on it and rather enjoy playing with your CapsLock toggled binding.
Another tricky way to check if the chat is active is searching for an image on the screen or a pixel color using ImageSearch or much simpler PixelGetColor, but you can only do that if your game's interface is not very complex/animated.

Trying to recognize Fn + V on my keyboard

I hate that when I'm using my laptop on its own I often type FN+v when I mean to paste. So I decided to solve my problem with AHK. I installed a keyboard hook in my main script,and used that to extract the fn keys value, 163. My initial test worked, but adding the & to make it a modifier does not. What am I overlooking?
So this doesn't work
SC163 & v::
MsgBox, %A_ThisHotkey% was pressed.
return
but this did work
SC163::
MsgBox, %A_ThisHotkey% was pressed.
return
When you hit the FN key, it might be remapping the "v" to something else (like "Media_Play_Pause" button) in the keyboard driver. Therefore the key code wouldn't be SC163 & v but something like SC159.
The Special Keys section for mentions a method to get the Scan code:
Ensure that at least one script is running that is using the keyboard hook. You can tell if a script has the keyboard hook by opening its main window and selecting "View->Key history" from the menu bar.
Double-click that script's tray icon to open its main window.
Press one of the "mystery keys" on your keyboard.
Select the menu item "View->Key history"
Scroll down to the bottom of the page. Somewhere near the bottom are the key-down and key-up events for your key. NOTE: Some keys do not generate events and thus will not be visible here. If this is the case, you cannot directly make that particular key a hotkey because your keyboard driver or hardware handles it at a level too low for AutoHotkey to access. For possible solutions, see Special Keys.
If your key is detectable, make a note of the 3-digit hexadecimal value in the second column of the list (e.g. 159).

With AutoHotKey, how to use ctrl+alt in hotkey without system seeing them as down when sending other keys?

I'm trying to map ctrl+alt+d to delete. Unfortunately, when I press that combination, the system sees ctrl+alt+delete, which naturally brings up the lock screen.
I've tried this to make the ctrl and alt keys look up to the system, but it didn't work:
^!d::Send {Alt Up}{Ctrl Up}{Delete}
I've tried putting ~ and $ in front of the hotkey, but that didn't work either.
I realize I can use KeyWait to wait for the modifier keys to be released:
~^!d::
KeyWait Control
KeyWait Alt
Send {Delete}
return
But then I can't repeatedly press ctrl+alt+delete to quickly delete characters. I have to release the modifier keys between each press, which is awkward.
I realize I can simulate a forward delete with a selection to the right followed by a backspace:
^!d::Send {Shift Down}{Right}{Shift Up}{Backspace}
But that's a bit kludgy, though it does work without releasing the modifiers. It's starting to feel like there isn't a way of accomplishing this, so any help would be appreciated.
You can try SendPlay as that creates a series of events (messages) that flow directly to the active window rather than performing their native operating system function.
^!d::Sendplay {Delete}
Doc link http://ahkscript.org/docs/commands/Send.htm#SendPlayDetail
Hope it helps

Emulating Ctrl + Spacebar + AlphabeticalKey with Autohotkey

My problem :
^space & c::
send {F2}
send {Escape}
but it didn't work, how do I emulate Ctrl+Space + AlphabeticaklKey ?
As my previous speakers said, it can't be done easily. Here's my suggestion, it seems to work fine:
^space::
Loop {
if(GetKeyState("c")) {
break
}
if(!GetKeyState("CTRL") || !GetKeyState("SPACE")) {
return
}
Sleep, 50
}
msgbox, You have pressed CTRL+SPACE+C
return
The code is pretty self-explanatory. When CTRL + SPACE is pressed, it waits until either one of both is released or C is pressed. The latter triggers the actual functionality, otherwise it will return.
I actually don't like it very much, because theoretically it may fail in some cases (e.g. when CTRL + SPACE + C is pressed and released before the execution reaches the check for the state of C; although that seems very unlikely).
Update
There's also a way using #If. I recommend using that since it's more sophisticated and reliable. This is due to the fact that it doesn't need any loops:
#If GetKeyState("SPACE")
^c::Msgbox, You have pressed CTRL+SPACE+C
#If GetKeyState("c")
^space::Msgbox, You have pressed CTRL+SPACE+C
As far as I know, you can only combine two non-hotkey keys with the syntax:
space & c:: msgbox space and c
You can read it here
You can define a custom combination of two keys (except joystick
buttons) by using & between them. In the below example, you would hold
down Numpad0 then press the second key to trigger the hotkey:
Numpad0 & Numpad1::MsgBox You pressed Numpad1 while holding down
Numpad0. Numpad0 & Numpad2::Run Notepad
Trying to use control as well like in: space & c & control or space & ^c or any other combination will result in compile error.
My recommendation is that you don't combine that three keys together. Look for a pure hotkey combination or use another more or less useless key.
#!c:: windows + alt + c
AppsKey & c::
Remember that if you use a normal key as modificator, you have to remap it to itself to keep the original functionality, for example with the menu key (appskey):
AppsKey:: Send {Appskey}
AppsKey & c:: ;do what you want
There are actually a couple ways to get help. First of all the authors of this language have moved to a new domain ahkscript.org. It is always welcome to ask questions like these in our forum. I just happened to be digging through this site today and saw this by accident.
When you have more than one line of code after a hotkey you need to have a return follow it:
^space & c::
send {F2}
send {Escape}
return
Hope that helps

autohotkey: 3 keys pressed together = hotkey?

language: Autohotkey on Win7
"Shift" plus "right mouse button" plus "mouse wheel up"
I want my hotkey to be holding those three keys simultaneously. I have tried the following without any success
+ & rbutton & wheelup::
send 6
+rbutton & wheelup::
send 6
shift & rbutton & wheelup::
send 6
I always get an error when I try to make this hotkey does anyone know how to do it?
I'm still a newbie but I'll try and help =].
It doesn't seem to work when you use a modifier key with two mouse buttons, so this is a way that kind of works:
+WheelUp::
KeyWait, RButton, D ; Waits for RButton to be pressed down.
MsgBox, This works!
Return
The problem is it clicks (or releases) the right mouse button once the hotkey has run. If you instead put it like so:
+RButton::
KeyWait, WheelUp, D
There will be another problem in that it will work fine for the first use of the hotkey, it will from then on work with only Shift + Right Mouse Button, because it's already waited for WheelUp to be pressed down (or rather scrolled up).
I mucked around for a little bit with GetKeyState and the like but still being new I can't find a way around it xD. These may be sufficient for what you need for now, otherwise better to wait for someone more knowledgeable to post.
With the information from your comment (hold Shift+right and spam WheelUp) following solution works fine. Use Shift + WheelUp and check if the right mosue button is down.
+WheelUp::
if (GetKeyState("RButton", "P"))
send 6
else
send +{WheelUp}
return
You could remove the else part and add a ~ modifier, but then Shift + WheelUp will be catched and blocked by AHK even if you dont press the right mouse button.