Make turned on CapsLock act like Shift held down for all non-letter keys Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
A Keymaker
Posts: 455
Joined: 31 May 2022, 13:46
Location: Donjon du Château de Mérovingien

Make turned on CapsLock act like Shift held down for all non-letter keys

Post by A Keymaker » 03 Jul 2022, 15:27

Does anyone happen to have an already working comprehensive script, that would detect CapsLock being in the ON state and act as if Shift was being held down - and thus write down e.g. ! instead of 1 when the ! / 1 key on keyboard is pressed? And then to "turn OFF" Shift when CapsLock is physically pressed once more?

I could try to write this from scratch- but there is a lot of keys to be covered and then tested. And from my short experience with AutoHotkey, I reckon they might be some hard core issues, as after all e are talking here about nothing else than signs and not merely letters, right? Maybe already someone been thorugh all that potential pain of trying out different variants o sending data for [if I am not mistaken] 21 keys?

Or maybe this can be somehow achieved without the help of AutoHotkey?


For the longest time now It has been incomprehensible to me just why this is not a native function of the CapsLock key - to act as "Shift" for all those signs hiding under the numbers and to the left side of the Enter key. Or why do keyboards do not have something like SpecialLock or AlternativeLock key, even those modern ones that have all those extra media buttons and / or programmable ones

User avatar
mikeyww
Posts: 26937
Joined: 09 Sep 2014, 18:38

Re: Make turned on CapsLock act like Shift held down for all non-letter keys

Post by mikeyww » 03 Jul 2022, 17:22

Code: Select all

CapsLock::
+CapsLock::
Send % GetKeyState("Shift") ? "{Shift up}" : "{Shift down}"
SoundBeep, 1000 + 500 * GetKeyState("Shift")
Return
After 100 posts, you exit the category of "short experience". :)

User avatar
boiler
Posts: 16954
Joined: 21 Dec 2014, 02:44

Re: Make turned on CapsLock act like Shift held down for all non-letter keys

Post by boiler » 03 Jul 2022, 21:04

Keymaker wrote:
03 Jul 2022, 15:27
For the longest time now It has been incomprehensible to me just why this is not a native function of the CapsLock key - to act as "Shift" for all those signs hiding under the numbers and to the left side of the Enter key.
Because while there are often occasions when someone needs to type a significant number of shifted letter keys (i.e., all capital letters) without having to type any of the non-shifted characters of those keys (i.e., lower case letters), there are hardly any occasions of the same scenario for the non-letter keys. The vast majority of people never need to type a significantly long string of shifted-special characters in a row, especially without also needing to mix in the non-shifted characters on those same keys (i.e., numbers and other special characters). It is just not a useful feature for almost anyone.

For those old enough to remember typewriters, they worked that way only because that’s how it worked mechanically, not because it was deemed useful. If anything, it was a pain to have to undo the caps lock to type numbers and such when otherwise typing in all capital letters.

User avatar
A Keymaker
Posts: 455
Joined: 31 May 2022, 13:46
Location: Donjon du Château de Mérovingien

Re: Make turned on CapsLock act like Shift held down for all non-letter keys

Post by A Keymaker » 03 Jul 2022, 21:09

mikeyww wrote:
03 Jul 2022, 17:22
[...]
After 100 posts, you exit the category of "short experience". :)
No, I do not!
As I clearly was not thinking as an avid AutoHotkey user- if wanted to bind all the 21 alternate keys on a one-by-one basis

Or do I?
This script was working- but the light on the keyboard [plus my onscreen indicator from freeware CapsLock Indicator] stopped. So I added line

Code: Select all

CapsLock::CapsLock
before Return. This of course reversed the state of CapsLock and thus brought back the indications of CapsLock state but at the cost of not being able to actually switch between uppercase and lowercase

So either this script needs an addition in form of telling the Windows [and CapsLock Indicator] to turn on / off the light [and onscreen indication] - or if AutoHotkey cannot control this, then my original idea of 21 variants would have to be used. I went to the help files and thus tried using

Code: Select all

SetStoreCapsLockMode, On
and

Code: Select all

SetStoreCapsLockMode, Off
but to to no avail. I also found this https://www.autohotkey.com/board/topic/9587-keyboard-led-control-capslocknumlockscrolllock-lights/ but it is way above my skills to even try to rework it

User avatar
A Keymaker
Posts: 455
Joined: 31 May 2022, 13:46
Location: Donjon du Château de Mérovingien

Re: Make turned on CapsLock act like Shift held down for all non-letter keys

Post by A Keymaker » 03 Jul 2022, 21:16

boiler wrote:
03 Jul 2022, 21:04
Keymaker wrote:
03 Jul 2022, 15:27
For the longest time now It has been incomprehensible to me just why this is not a native function of the CapsLock key - to act as "Shift" for all those signs hiding under the numbers and to the left side of the Enter key.
[...]
It is just not a useful feature for almost anyone
[...]
I am also one of those persons that cannot comprehend why more people do not use their desktop PCs while laying in bed - thus having sometimes to use a virtual keyboard. It just annoys me to have to sometimes press Shift despite already writing in caps after pressing CapsLock

User avatar
mikeyww
Posts: 26937
Joined: 09 Sep 2014, 18:38

Re: Make turned on CapsLock act like Shift held down for all non-letter keys

Post by mikeyww » 03 Jul 2022, 21:40

Code: Select all

#If GetKeyState("CapsLock", "T")
`::+`
1::+1
2::+2
3::+3
4::+4
5::+5
6::+6
7::+7
8::+8
9::+9
0::+0
-::+-
=::+=
[::+[
]::+]
\::+\
`;::+;
'::+'
,::+,
.::+.
/::+/
#If

User avatar
A Keymaker
Posts: 455
Joined: 31 May 2022, 13:46
Location: Donjon du Château de Mérovingien

Re: Make turned on CapsLock act like Shift held down for all non-letter keys

Post by A Keymaker » 04 Jul 2022, 11:06

The above one works A-OK, thank you


But I also tried reversing it to "normal" state of affairs - i.e. making e.g. key
1 / ! write 1 when CapsLock is in ON state and Shift key is beeing physically pushed down, but this

Code: Select all

CapsLock::
CapsLock := GetKeyState("CapsLock") And GetKeyState("Shift")
    if (CapsLock = T)
        `::~
        1::!
        2::@
        3::#
        4::$
        5::+5
        6::^
        7::&
        8::*
        9::(
        0::)
        -::_
        =::+
        [::{
        ]::}
        \::|
        `;:::
        '::"
        ,::<
        .::>
        /::?
    else if (CapsLock = T) And (Shift = T)
        `::`
        1::1
        2::2
        3::3
        4::4
        5::5
        6::6
        7::7
        8::8
        9::9
        0::0
        -::-
        =::=
        [::[
        ]::]
        \::\
        `;::`;
        '::'
        ,::,
        .::.
        /::/
return
*/
did not work; as did not my other attempts

User avatar
mikeyww
Posts: 26937
Joined: 09 Sep 2014, 18:38

Re: Make turned on CapsLock act like Shift held down for all non-letter keys

Post by mikeyww » 04 Jul 2022, 12:14

As this looks like a shifting set of goals, I will sign off here. What the script does:
detect CapsLock being in the ON state and act as if Shift was being held down - and thus write down e.g. ! instead of 1 when the ! / 1 key on keyboard is pressed? And then to "turn OFF" Shift when CapsLock is physically pressed once more?
Best of luck!

User avatar
child_fs
Posts: 5
Joined: 05 Feb 2022, 12:58
Contact:

Re: Make turned on CapsLock act like Shift held down for all non-letter keys  Topic is solved

Post by child_fs » 05 Jul 2022, 13:22

Hi, in case you haven't reached a solution yet, see if this works out for you:

Code: Select all

SetCapsLockState, Off	; This is here just assure the script is working consistently
return				; End of auto-execute section

#If GetKeyState("CapsLock", "T")
`::
1::
2::
3::
4::
5::
6::
7::
8::
9::
0::
-::
=::
[::
]::
\::
`;::
'::
,::
.::
/::
+`::
+1::
+2::
+3::
+4::
+5::
+6::
+7::
+8::
+9::
+0::
+-::
+=::
+[::
+]::
+\::
+`;::
+'::
+,::
+.::
+/::
ThisHotkey := A_ThisHotkey
SendInput, % (InStr(ThisHotkey, "+") ? SubStr(ThisHotkey, 2) : "+" ThisHotkey) 
return
It's an adaptation of mikeyww's script to make it work like the "normal state of affairs", as you've mentioned.
It's rather lengthy, label-wise, I know... but as far as I've tested it, it works just fine works just fine after viewtopic.php?f=76&t=106055&p=471800#p471800

Basically, what it does is the following:
  • Like in mikeyww's script, those hotkeys are conditional ("context-sensitive", as the documentation puts it. See here, and here), meaning every time you press one of the keys of interest, AHK will check the condition in the #If directive in order to decide whether the key of interest will trigger the nested hotkey or not.
    For example: when you press the backtick (`) key, it will only trigger the hotkey if the toggle state of CapsLock is "On", otherwise AHK will act as if there's no defined hotkey for backtick at all (provided you haven't defined one elsewhere in your script) and send a good ol' backtick character accordingly;
  • However, I've added a corresponding "+KeyOfInterest::" label (notice the + in the beginning) for each label we already had, effectively doubling the amount of labels that can trigger the hotkey.
    The reason for that is that regardless of whether the condition in the #If directive has been met or not, AHK will not allow a hotkey to be triggered if you're pressing a modifier key along with the key of interest, unless you specifically tell AHK that you wish for it to do so, and for the specific modifier keys that you want.
    For example:
    1. A hotkey with a label such as "1::" will NOT trigger if you are pressing any modifier keys (such as Ctrl or Shift) along with the "1" key;
    2. A hotkey with label "+1::" will trigger ONLY if you are pressing a Shift key (LShift or RShift) and no other modifier key along with the "1" key;
    3. A hotkey with label "*1::" will trigger regardless of which modifier key(s) you may be pressing along with the "1" key, even pressing "1" with no modifier keys at all will trigger it;
  • The explanation for the "ThisHotkey := A_ThisHotkey" line is that the built-in variable A_ThisHotkey contains a string value with information about what keypress event triggered the hotkey (what label led to the triggering of the hotkey, minus the double-colon part, was it "1"? Was it "+6"?). This line stores this string value in another variable for safety, since A_ThisHotkey gets updated by AHK everytime a new hotkey thread interrupts a previous hotkey thread.
    This line might be unnecessary, since there's only a single line of functional code in this hotkey (the SendInput line) and AHK takes measures to ensure that newly launched threads will have enough time to execute their actions before allowing them to be interrupted by other threads, but I like to think that it's good practice to do what I did. :)
  • Finally, in the "SendInput" line, there's 2 things to notice:
    1. The percent sign (%) prefix tells AHK that what follows is an expression, and forces SendInput to accept it. Reference here.
    2. The expression wrapped around parenthesis is a ternary expression. What it does is the following:
      1. The InStr(ThisHotkey, "+") function check whether the string contained by ThisHotkey has a plus sign "+" in it or not. Effectively, what it does is check whether the current hotkey was triggered while pressing Shift (LShift or RShift). It returns a nonzero value, in our case, 1 (true) if it does, and 0 (false) if it didn't.
      2. The SubStr(ThisHotkey, 2) function is used only if InStr(ThisHotkey, "+") returned true, that is, only if this hotkey was triggered while holding Shift. This function returns a substring of ThisHotkey from its second character onwards, that would leave out the "+" sign. For example: Pressing Shift-9 while CapsLock is on would trigger the hotkey through the "+9::" label and have ThisHotkey hold the string "+9", InStr(ThisHotkey, "+") would return 1 (true) and SubStr(ThisHotkey, 2) would return "9". That way the SendInput line would evaluate to SendInput, % "9" and send a "9" character while pressing Shift-9 with CapsLock on.
      3. The "+" ThisHotkey substring is used only if InStr(ThisHotkey, "+") returned 0 (false), that is, only if this hotkey was NOT triggered while holding Shift. For example: Pressing "9" while CapsLock is on would trigger the hotkey through the "9::" label and have ThisHotkey hold the string "9", that way InStr(ThisHotkey, "+") would return 0 (false), and the SendInput line would evaluate to SendInput, % "+9" and send a "(" character while pressing 9 with CapsLock on.
I'm sorry if the answer was a bit too wordy, this is my first post in this forum and I wanted to be sure I got my point across not to only to you, but to anyone reading this afterwards. Please let me know if that helps.

Cheers! :wave:

Edit: Addressed my mistake, corrected some stuff, formatted some other stuff, put some links to the docs.
Last edited by child_fs on 08 Jul 2022, 11:07, edited 1 time in total.

User avatar
A Keymaker
Posts: 455
Joined: 31 May 2022, 13:46
Location: Donjon du Château de Mérovingien

Re: Make turned on CapsLock act like Shift held down for all non-letter keys

Post by A Keymaker » 07 Jul 2022, 18:52

child_fs wrote:
05 Jul 2022, 13:22
Hi, in case you haven't reached a solution yet, see if this works out for you:
Yes, I did not - and yes, it works

Now after using CapsLock and Shift for decades I have to learn to use them once more - it is not easy, but this change is what I wanted

child_fs wrote:
05 Jul 2022, 13:22
[...]
I'm sorry if the answer was a bit too wordy, this is my post in this forum and I wanted to be sure I got my point across to only to you, but to anyone reading this afterwards
[...]
This is very valuable

I small time code tweaker like me barely understand most of the example in Help

So thank you very much

User avatar
A Keymaker
Posts: 455
Joined: 31 May 2022, 13:46
Location: Donjon du Château de Mérovingien

Re: Make turned on CapsLock act like Shift held down for all non-letter keys

Post by A Keymaker » 07 Jul 2022, 19:39

However - both versions [viewtopic.php?f=76&t=106055&p=471723#p471130 & viewtopic.php?f=76&t=106055&p=471723#p471360] have a strange side effect. Let me explain

I have one bulk AHK file in which I keep all of adjustment of such kind. Among them is

Code: Select all

#If WinActive("ahk_exe C:\Program Files (x86)\Sony\Sound Forge 7.0\forge70.exe")

XButton2::
    Send {LAlt}
    Sleep, 55
    Send, pfg{Tab 12}{Down 12}{Enter}
    Sleep 99
return

XButton1::
    Send {LAlt}
    Sleep, 55
    Send, pfg{Tab 12}{Up 12}{Enter}
    Sleep 99
return


#If MouseIsOver("Sony Sound Forge")
MButton::Send q

MouseIsOver(WinTitle) {
    MouseGetPos,,, Win
    return WinExist(WinTitle . " ahk_id " . Win)
}
upgrading functionality of my audio editor. And it works works good enough [viewtopic.php?f=76&t=104940&p=466126&hilit=stop+sleep+send#p466599]

Unfortunately when I add to that AHK file of mine either of these also working CapsLock expansion codes, the section adjusting Sound Forge stops to work - i.e. it ignores input from Forward, Backward and Middle Mouse Button. So I double checked if it really was these CapsLock codes causing this and if it was my only script running. Then I opened Sound Forge without any script running to check if I can evoke such blocking. And what I established is that when on the keyboard

#1] CapsLock is turned on - pushing key Q still works

#2] CapsLock is turned on - Forward and Backward Mouse Button still work, but in a different [native] way that when that above script of mine is active

#3] CapsLock is turned on - Middle Mouse Button does not work, but that is because natively it does do anything in that very old software

#4] Shift is being held down - pushing key Q does nothing as apparently it is blocked

#5] Shift is being held down - pushing key Forward and Backward Mouse Button still work, but in a different [native] way that when that above script of mine is active

#6] Shift is being held down - Middle Mouse Button does not work, because natively it does do anything in that very old software


So how is that possible? How can these CapsLock codes block only input in Sound Forge - while other programs are not blocked? That whole AHK file of mine has content seen in this post viewtopic.php?f=76&t=105182#p469331 plus addition from this post viewtopic.php?f=76&t=105182#p470519

User avatar
A Keymaker
Posts: 455
Joined: 31 May 2022, 13:46
Location: Donjon du Château de Mérovingien

Re: Make turned on CapsLock act like Shift held down for all non-letter keys

Post by A Keymaker » 07 Jul 2022, 19:53

Keymaker wrote:
07 Jul 2022, 19:39
However
[...]
How can these CapsLock codes block only input in Sound Forge - while other programs are not blocked?
[...]
Because I forgot about the importance of keeping instructions for Run as Administrator at the top of AHK file and I was simply putting those CapsLock codes above that instruction - thus inadvertently resurrected the recently taken care of issue of Sound Forge not receiving input on the account of script not being elevated while audio editor being elevated [viewtopic.php?f=76&t=104854&p=465707]

In other words: false alarm - both codes work; i.e. viewtopic.php?f=76&t=106055&p=471729#p471130 and viewtopic.php?f=76&t=106055&p=471729#p471360

User avatar
A Keymaker
Posts: 455
Joined: 31 May 2022, 13:46
Location: Donjon du Château de Mérovingien

Re: Make turned on CapsLock act like Shift held down for all non-letter keys

Post by A Keymaker » 08 Jul 2022, 07:48

Keymaker wrote:
07 Jul 2022, 19:53
[...]
In other words: false alarm - both codes work; i.e. viewtopic.php?f=76&t=106055&p=471729#p471130 and viewtopic.php?f=76&t=106055&p=471729#p471360
Unfortunately, as it turns out now, this advanced one viewtopic.php?f=76&t=106055&p=471360#p471360 has a huge side effect: it makes something even as basic as

Code: Select all

x::y
work only if CapsLock is in the ON state [and to add insult to an injury it sends, as it "should", Y instead of y]

User avatar
child_fs
Posts: 5
Joined: 05 Feb 2022, 12:58
Contact:

Re: Make turned on CapsLock act like Shift held down for all non-letter keys

Post by child_fs » 08 Jul 2022, 08:56

Keymaker wrote:
08 Jul 2022, 07:48
Keymaker wrote:
07 Jul 2022, 19:53
[...]
In other words: false alarm - both codes work; i.e. viewtopic.php?f=76&t=106055&p=471729#p471130 and viewtopic.php?f=76&t=106055&p=471729#p471360
Unfortunately, as it turns out now, this advanced one viewtopic.php?f=76&t=106055&p=471360#p471360 has a huge side effect: it makes something even as basic as

Code: Select all

x::y
work only if CapsLock is in the ON state [and to add insult to an injury it sends, as it "should", Y instead of y]

I'm so sorry, I think I've made a small mistake with huge implications in that snippet: I forgot to turn off the context sensibility of the hotkey by wrapping it with a closing #If directive below it (you can see mikeyww did NOT make this mistake in his snippet).
This made it so every other hotkey that you added below it in your script would only take effect if the condition in the opening #If directive was met (if CapsLock was on). I think this is what is preventing you from adding other functional hotkeys to your code, like x::y. Fortunately, it's easy to fix this with:

Code: Select all

#If GetKeyState("CapsLock", "T")
`::
; ...
; All the other labels
; ...
+/::
ThisHotkey := A_ThisHotkey
SendInput, % (InStr(ThisHotkey, "+") ? SubStr(ThisHotkey, 2) : "+" ThisHotkey) 
return
#If 			; <--- Extremely important

; Your other (context-free) hotkeys
x::y

As a rule of thumb, it's always a good idea to wrap your context sensitive hotkeys inside a pair of
#If Condition
; Hotkeys
#If
directives.

I'm sorry once again for the trouble... :oops:

User avatar
A Keymaker
Posts: 455
Joined: 31 May 2022, 13:46
Location: Donjon du Château de Mérovingien

Re: Make turned on CapsLock act like Shift held down for all non-letter keys

Post by A Keymaker » 12 Jul 2022, 11:10

child_fs wrote:
08 Jul 2022, 08:56
[...]
I forgot to turn off the context sensibility of the hotkey by wrapping it with a closing #If directive below it
Yes- adding #If at the end fixed things
child_fs wrote:
08 Jul 2022, 08:56
I'm sorry once again for the trouble... :oops:
Oh, come on- you managed to create a more advanced version; and in a situation, when the first one was already working in accordance to initial requirements of the creator of the topic

And that whole #If shebang will hopefully make me remember to potentially look for a lack of it as a culprit in future scripts

Post Reply

Return to “Ask for Help (v1)”