Created
May 26, 2024 17:21
-
-
Save KuroiLight/aea214c3ac299c1fbaf4e5f0345b2b1a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;Author: KuroiLight - klomb - <kuroilight@openmailbox.org> | |
;Started On: 08/08/15 | |
;License: Public Domain (http://www.unlicense.org/) | |
GetUserHotkey(enable := true) { | |
global __htky, __last_valid | |
static WH_KEYBOARD := 2, WH_MOUSE_LL := 14, KBHHandle := 0, MHHandle := 0, info | |
static MouseCallback := RegisterCallback("MouseProc",,3), KeyboardCallback := RegisterCallback("KeyboardProc",,3) | |
if(MHHandle) { | |
DllCall("UnhookWindowsHookEx", Ptr, MHHandle) | |
MHHandle := 0 | |
} | |
if(KBHHandle) { | |
DllCall("UnhookWindowsHookEx", Ptr, KBHHandle) | |
KBHHandle := 0 | |
} | |
if(enable) { | |
KBHHandle := DllCall("SetWindowsHookEx", Int, WH_KEYBOARD, Ptr, KeyboardCallback, Ptr, 0, Int, DllCall("GetCurrentThreadId")) ;application level kb hook (local) | |
MHHandle := DllCall("SetWindowsHookEx", Int, WH_MOUSE_LL, Ptr, MouseCallback, Ptr, 0, Int, 0) ;low level mouse hook (global) | |
Gui, _klhtkywin: New, -SysMenu -Border | |
Gui, font,, Consolas | |
Gui, Add, Text, Center vinfo, % "Press the key combination for your hotkey." | |
Gui, font, w800 | |
Gui, Add, Text, Center v__htky, % " " | |
Gui, Show, Center Autosize | |
Gui, _klhtkywin: +LastFound | |
WinWaitClose, | |
return __last_valid | |
} else { | |
Gui, _klhtkywin:Cancel | |
} | |
} | |
KeyboardProc(code, wParam, lParam) { | |
if(code != 0) | |
return DllCall("CallNextHookEx", Ptr, 0, Int, code, Ptr, wParam, Ptr, lParam) | |
vk := wParam ;get vk | |
keydown := (0x80000000 & lParam) ? false : true ;get keyup bits only (bit 31) | |
sc := (lParam & 0x1FF0000) >> 16 ;get sc/ext bits only (bits 16-24) | |
ProcessKey(GetKeyName(Format("vk{1:x}sc{2:x}", vk, sc)), keydown) | |
return 1 ;block input, stops dinging | |
} | |
MouseProc(code, wParam, lParam) { | |
static mouse_buttons := {0x0201:"LButtonD", 0x0204:"RButtonD", 0x0207:"MButtonD", 0x20B:"XButtonD", 0x0202:"LButton", 0x0205:"RButton", 0x0208:"MButton", 0x20C:"XButton"} | |
if(code != 0) | |
return DllCall("CallNextHookEx", Ptr, 0, Int, code, Ptr, wParam, Ptr, lParam) | |
mouse_button := "" | |
for hex, name in mouse_buttons | |
if(wParam = hex) | |
mouse_button := StrReplace(name, "D", "", button_down) ;if D exists in name it will be removed and the button_down flag set to 1 | |
if(mouse_button == "XButton") | |
mouse_button .= *(lParam+10) ;get the byte at the high-word in mouseData, which is either 1 or 2. | |
if(mouse_button) | |
ProcessKey(mouse_button, button_down) | |
return 0 ;dont block input | |
} | |
test_label: | |
return | |
ProcessKey(key, state) { | |
static keysdown := "", key_count := 0 | |
global __last_valid | |
static regex_mods_all := "S)(?:Control|Shift|Alt|Win)*" | |
static def_map := {"Control":"^", "Shift":"+", "Alt":"!", "Win":"#"} | |
ahk_hotkey := "" | |
if(key = "") | |
return | |
if(state) { | |
if(RegExMatch(keysdown, "S)(?:^|\s)" . key . "(?:\s|$)")) | |
return ;return early | |
key_count++ | |
keysdown .= (key_count > 1 ? " " : "") . key | |
tcount := key_count | |
for k, v in def_map { | |
if(InStr(keysdown, k)) { | |
if(tcount > 1) | |
ahk_hotkey .= v | |
else | |
ahk_hotkey .= k | |
tcount-- | |
} | |
} | |
ahk_hotkey .= Trim(RegExReplace(keysdown, regex_mods_all)) | |
Hotkey, %ahk_hotkey%, test_label, UseErrorLevel Off | |
if(ErrorLevel == 0) | |
__last_valid := ahk_hotkey | |
} else { | |
if(key_count = 1) | |
keysdown := StrReplace(keysdown, key) | |
else | |
keysdown := RegExReplace(keysdown, "S)(?:^|\s)" . key . "(?:(\s)|$)", "$1") | |
key_count-- | |
if(__last_valid) { | |
GetUserHotkey(false) ;remove the hooks | |
MsgBox, 0x4,, % "You selected " . __last_valid . " as your hotkey.`nEnable passthrough? (no if you don't know what this is)" | |
IfMsgBox, Yes | |
__last_valid := "~" . __last_valid | |
Gui _klhtkywin:Destroy | |
} | |
} | |
GuiControl, _klhtkywin:Text, __htky, % StrReplace(__last_valid, "&", "&&") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment