#Persistent
Hold( "sc32" ; m
, 300, 100
, "+{m}", "{y}", "+{s}", "{c}", "{r}", "{i}", "{p}", "{t}", "{sc39}" )
Return
Hold(MyHotkey, TimeOut, SleepTime, HeldKeys*) {
static oInfo, WH_KEYBOARD_LL := 13
oInfo := { MyHotkey: MyHotkey, MyHotkeySC: "0x" . SubStr(MyHotkey, 3)
, TimeOut: TimeOut, SleepTime: SleepTime, HeldKeys: HeldKeys }
DllCall("SetWindowsHookEx", Int, WH_KEYBOARD_LL
, Ptr, RegisterCallback("LowLevelKeyboardProc", "Fast", 3, pInfo := Object(oInfo))
, Ptr, DllCall("GetModuleHandle", UInt, 0, Ptr), UInt, 0, Ptr)
ObjRelease(pInfo)
}
LowLevelKeyboardProc(nCode, wParam, lParam) {
static LLKHF_INJECTED := 0x10, WM_KEYDOWN := 0x100, WM_KEYUP := 0x101, timer
Critical
msg := wParam
flags := NumGet(lParam + 8, "UInt")
ext := flags & 1
sc := NumGet(lParam + 4, "UInt") | ext << 8
time := NumGet(lParam + 12, "UInt")
INJECTED := (flags & LLKHF_INJECTED) >> 4
oInfo := Object(A_EventInfo)
if (!INJECTED && msg = WM_KEYDOWN && oInfo.KeyDownTime != "")
Return 1
if (!INJECTED && msg = WM_KEYDOWN && sc = oInfo.MyHotkeySC && oInfo.KeyDownTime = "") {
if GetKeyState("Shift", "P") || GetKeyState("Alt", "P") || GetKeyState("Ctrl", "P")
Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, Ptr, wParam, Ptr, lParam)
oInfo.KeyDownTime := time
timer := Func("SendKeys").Bind(oInfo)
SetTimer, % timer, % "-" . oInfo.TimeOut
Return 1
}
if (!INJECTED && msg = WM_KEYUP && sc = oInfo.MyHotkeySC && oInfo.KeyDownTime != "") {
SetTimer, % timer, Delete
if (A_TickCount - oInfo.KeyDownTime <= oInfo.TimeOut)
SendInput, % "{" oInfo.MyHotkey "}"
oInfo.KeyDownTime := ""
Return 1
}
Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, Ptr, wParam, Ptr, lParam)
}
SendKeys(oInfo) {
max := oInfo.HeldKeys.MaxIndex()
while oInfo.KeyDownTime {
SendInput, % oInfo.HeldKeys[(k := mod(A_Index, max)) ? k : max]
Sleep, oInfo.SleepTime
}
}