一位网友请求在 webStorm 中实现 alt+字母替代方向键, 在实现过程中遇到些问题, 立此存照
实现一过程: 按照 ahk 正统思路, 直接设定快捷键映射, 发现每次按下 alt 后按辅助(jkliou 下同)键仅能实现一次映射, 第二次便恢复辅助键原始键值. 放开 alt 再次按下后才能再次激活热键映射.
通过
GetKeyState
语句对按键状态进行分析, 发现此时 alt 是可以检测到按下状态的, 但可能是目标程序本身的机制使得 alt 与辅助键之间不能形成有效的快捷键被 ahk 捕获, 使得映射失效.
此时转变思路, 设置辅助键为快捷键, 击发后检测 alt 状态, 如在按下状态则激活映射, 未按下则发送原始键.
测试可以成功响应, 但由于程序本身问题, 会随机的释放 alt, 使得状态检测机制失效, 而尝试了提权/虚拟击键等措施无果, 分析此种状态跟系统(测试时均为 Win10x64)和程序本身运行机制有关, 如不能深入了解其中原理则很难解决这个问题.
此时采用实现二方案, 仅仅在此程序激活时不使用此映射方案, 而可以应用在其他任意环境使用.
实现二要点已注释于源代码.
实现一
#SingleInstance, Force #NoEnv #Persistent if not A_IsAdmin { Run *RunAs "%A_ScriptFullPath%" ; 需要 v1.0.92.01+ ExitApp } keyj := "left" keyk := "down" keyl := "Right" keyi := "up" keyu := "home" keyo := "end" SetTitleMatchMode, RegEx Hotkey, IfWinActive, ahk_class SunAwtFrame Hotkey, !j, mapj Hotkey, !k, mapk Hotkey, !l, mapl Hotkey, !i, mapi Hotkey, !u, mapu Hotkey, !o, mapo return #IfWinActive ahk_class SunAwtFrame $j:: $k:: $l:: $i:: $u:: $o:: BlockInput, on thisK := SubStr(A_ThisHotkey, 0, 1) remapk := key%thisK% if IsAltDown()="D" Send, {Alt up}{%remapk%}{Alt Down} else SendInput %thisK% BlockInput, Off return mapj: mapk: mapl: mapi: mapu: mapo: BlockInput, on thisK := SubStr(A_ThisLabel, 0, 1) remapk := key%thisK% SendInput, {%remapk%}{Alt Down} BlockInput, Off return IsAltDown() { GetKeyState, state, Alt return state }
实现二
#SingleInstance, Force #NoEnv #Persistent /* 提权, 使用管理员模式 */ if not A_IsAdmin { Run *RunAs "%A_ScriptFullPath%" ; 需要 v1.0.92.01+ ExitApp } ;~ 设置监控窗口变化的 Timer SetTimer, WinActMonitor, 1 /* 按Alt+j 等于按方向键← 按Alt+k 等于按方向键↓ 按Alt+l 等于按方向键→ 按Alt+i 等于按方向键↑ 按Alt+u 等于按Home键 按Alt+o 等于按End键 */ ;~ 设置热键对应的映射按键变量 keyj := "left" keyk := "down" keyl := "right" keyi := "up" keyu := "home" keyo := "end" ;~ 定义热键,采用语句模式,便于统一修改 Hotkey, !j, mapj Hotkey, !k, mapk Hotkey, !l, mapl Hotkey, !i, mapi Hotkey, !u, mapu Hotkey, !o, mapo return ;~ 热键对应跳转 label mapj: mapk: mapl: mapi: mapu: mapo: ;~ 防止用户输入造成错误,虽然可能性很小 BlockInput, on ;~ 通过label截获对应热键的原键 thisK := SubStr(A_ThisLabel, 0, 1) ;~ 获取热键映射变量 remapk := key%thisK% ;~ 发送对应映射键,其中{Alt Down}保持alt按下状态 SendInput, {%remapk%}{Alt Down} ;~ 恢复用户输入响应 BlockInput, Off return WinActMonitor: ;~ 获取当前激活窗口类,并除去前后空 WinGetClass, Win_Now, A Win_Now := Trim(Win_Now) ;~ 判定当前窗口是否切换,未切换窗口则不必处理 ;~ 不使用Winwait是因为此语句会暂停脚本线程造成错误 if (Win_Now=Win_Old) return ;~ 当激活窗口为指定类(此处为webstorm窗口类)时,屏蔽热键,否则保留热键 if (Win_Now="SunAwtFrame") Suspend, On else Suspend, Off ;~ 保存当前窗口类名以便比较 Win_Old := Win_Now return
感谢分享。学习下
这样貌似就行了
#IfWinActive, ahk_exe webstorm64.exe
!j::
send, {left}
send {alt up}
return
!k::
send, {right}
send {alt up}
return
在其他软件中应该是可以的, 但这个软件不行, 对 alt 键的处理有问题.
如果提要求, 肯定是遇到无法解决的困难, 起码不是常规方法能完成的, 于是我特意下了软件安装后测试的, 果然遇到了问题.
webStorm 2017.1.1 win10 x64 正常。
好热心肠的ahker,群里 论坛里多你这样的人是福气
哈哈 谢谢夸奖
非常棒!!
感谢大佬分享,前来学习