Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Is there any way to get Shift to toggle like Caps lock?


  • Please log in to reply
6 replies to this topic
bbint
  • Members
  • 43 posts
  • Last active: Nov 23 2015 04:21 AM
  • Joined: 17 Sep 2008
Right now, I need 2 buttons:

Shift::Send {Shift down}
LCtrl::Send {Shift up}

I’d like to be able to press shift, press the buttons that I want shift-modified, and then press shift to release/toggle off, just like caps lock

I want to be able to activate shift and deactivate shift by only pressing shift

Shift::
Send {Shift down}
However, if previous key was shift down
That is, 
If previous GetKeyState(shift down)
Then Send {Shift up}
Return

This is incorrect because GetKeyState always sees that shift is down as soon as I press shift

I need GetKeyState to see any {Shift down} that is not in the remapping

I’m not sure as to how to stop from going around in circles

I just found these 2 posts with code that seem relevant, but I don’t understand them

Of the 2 pieces of code in the 2 posts, which one works for me?

Thanks for any help

<!-- m -->http://www.autohotke... ... ggle shift<!-- m -->

by Icarus

#SingleInstance Force

; Define source keys (on the keyboard)
; Define target keys
; In this example, pressing "a" will send "q" and "b" will send "w"
Source := "abcdefghijklmnopqrstuvwxyz1234567890-=[];'\,./"
Target := "qwertyuiqwertyuiquwyteriuyqtweriuytiquywetriuy"

; Loop through all source keys and create a hotkey for each
Loop parse, Source
   Hotkey $%A_LoopField%, PressKey

Return

; This function handles all hotkeys
PressKey:
   
   ; First, remove the $ sign
   StringReplace ThisHotkey, A_ThisHotkey, $
   
   ; Find the position of the pressed key in the "Source" string
   Position := InStr( Source, ThisHotkey )
   
   ; Pull the "twin" of the source character from the target string
   TargetChar := SubStr( Target, Position, 1 )
   
   ; If caps lock is on, send Shift+TheKey, else, send only TheKey
   If( GetKeyState( "CAPSLOCK", "T" ) )
      SendInput +%TargetChar%
   Else
      SendInput %TargetChar%   
   
Return

ESC::ExitApp

<!-- m -->http://www.autohotke... ... ggle shift<!-- m -->

by animeaime

thid code looks simpler, but animeaime is replying to someone who only needs "wasd" modified for his game

#SingleInstance Force
#NoEnv

Shifted := false
return

;Toggle <Shifted>
Control::Shifted := !Shifted

;Sends wasd
$w::Send("w")
$a::Send("a")
$s::Send("s")
$d::Send("d")

Send(Key)
{
    ;if <Shifted>, sends +%Key%
    ;else, sends %Key%

    global Shifted
   
    if Shifted
        Send, +%Key%
    else
        Send, %Key%
}


Superfraggle
  • Members
  • 1019 posts
  • Last active: Sep 25 2011 01:06 AM
  • Joined: 02 Nov 2004
$shift::
Shifted:=!Shifted
If (shifted)
  Send,{Shift Down}
else 
  Send,{Shift UP}
REturn

Ok thats strange, pressing left shift will activate and deactivate the shift lock. Pressing right shift will activate, but not de-activate.
Steve F AKA Superfraggle

http://r.yuwie.com/superfraggle

sinkfaze
  • Moderators
  • 6367 posts
  • Last active: Nov 30 2018 08:50 PM
  • Joined: 18 Mar 2008
Here is my solution tweaking Icarus' example a little bit:

Source := "abcdefghijklmnopqrstuvwxyz1234567890-=[];'\,./"
State = 0 ; variable used to toggle shift state

Loop, parse, Source
  Hotkey $%A_LoopField%, PressKey
return

LShift::
if !State ; if state = 0
  State++ ; sets state = 1 to turn on
else      ; if state = 1
  State-- ; sets state = 0 to turn off
return

PressKey:

if (State = 1 && InStr(Source,SubStr(A_ThisHotkey,2))) ; if toggle state on and key exists in source list
  Send % "+" SubStr(A_ThisHotkey,2) ; send shifted key
else
  Send % SubStr(A_ThisHotkey,2) ; send unshifted key
return


MRCS
  • Members
  • 2 posts
  • Last active: Jun 10 2009 01:57 AM
  • Joined: 08 Jun 2009
I don't know whether this will help you or not, but I wanted my CapsLock to still work the same after making the common change to have Shift turn off CapsLock.

After configuring the Shift key to turn off Caps Lock (either by Attributes or ScanCode methods), two scripts needed to be created. The first one I named CapsLockR.ahk and contains the following script:
CapsLock UP::Run C:\Documents and Settings\k\CapsLock.ahk

The second one is named CapsLock.ahk and has this script:
GetKeyState, state, CapsLock, T
if state = D
SetCapsLockState, off
else
SetCapsLockState, on
exit

bbint
  • Members
  • 43 posts
  • Last active: Nov 23 2015 04:21 AM
  • Joined: 17 Sep 2008
last noob question.. is sinkfaze's code supposed to work if I just copy and paste that?

$%A_LoopField%
PressKey

am I supposed to replace any of those?

thanks

sinkfaze
  • Moderators
  • 6367 posts
  • Last active: Nov 30 2018 08:50 PM
  • Joined: 18 Mar 2008

...is sinkfaze's code supposed to work if I just copy and paste that?


Yes, that code is ready to work as is. The $ is a designator for how the hotkey works when it is assigned via the Hotkey command, but it is also included in the A_ThisHotkey variable when it is called to send the character. This:

SubStr(A_ThisHotkey,2)

Removes the $ from A_ThisHotkey so only the character is sent.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
That script seems like overkill to me. Do you essentially want StickyKeys, but only for the (left) Shift key?

This is incorrect because GetKeyState always sees that shift is down as soon as I press shift

Unless you specify "P" for the second parameter of GetKeyState, it returns the logical state of the key. Since the hotkey Shift:: blocks the native function of the key, its logical state should not change when you press the key. By contrast, hotkeys with the ~ modifier do not block the key's native function.

The following works for me:
LShift:: Send % "{Blind}{LShift " . (GetKeyState("LShift") ? "Up}" : "Down}")
... or the more readable version:
LShift::
    if GetKeyState("LShift") ; LShift is logically down. Release it.
        Send {Blind}{LShift Up}
    else ; LShift is logically up. Press it.
        Send {Blind}{LShift Down}
return
(See also [VxE]'s := guide ? ( to the ternary ) : ( operator ).)

If you did not want to rely on GetKeyState, you could toggle a variable:
LShift:: Send % "{Blind}{LShift " . ((lshift:=!lshift) ? "Down}" : "Up}")
(I'm sure this has been demonstrated countless times across the forum.)