I felt compelled to understand this. Here you go!
Basically, I created a hotkey for each Shift + Letter key combination to send the correct key case and also set the value to Abort . The Abort value is then referenced when one of the Shift keys is pressed to determine whether or not to send the corresponding ones.
Rolling was accomplished by creating a Hotkey for LShift + RShift (and vice versa). He then looks at which key is issued first to determine () or )( .
Accept if this is what you were looking for!
Loop 26 { Hotkey, % "~LShift & " Chr(A_Index+96), LetterKey ; Hotkeys for AZ Hotkey, % "~RShift & " Chr(A_Index+96), LetterKey ; Hotkeys for AZ } Return RShift:: LShift:: Abort := 0 keyDown := A_TickCount Keywait, % A_ThisHotkey duration := A_TickCount - keyDown If (duration < 200) and (Abort = 0) SendInput % (A_ThisHotkey = "LShift") ? "(" : ")" Send {LShift Up} Return RShift & LShift:: LShift & RShift:: Keywait, LShift If GetKeyState("RShift", "P") { Keywait, RShift Send () } Else Send )( Return LetterKey: SendInput, % "+" SubStr(A_ThisHotKey, 0, 1) Abort := 1 Return
EDIT: Hmm, I seem to have the same problem as you. I always get a duration of 0 due to keyboard shortcuts.
source share