AHK-UMSS框架 (AHK通用修饰键解决方案,任何键都是修饰键)
1 #Warn 2 #NoEnv ; # 禁用环境变量检查:不检查空变量是否为"环境变量",可以极大地提高效率 3 #Hotstring EndChars ◎ ; # 热字串终止符号设置:只把空格作为终止符,(文档上所说是不能单独用空格的,最多是空格之外再加一个,所以用◎充数) 4 #Hotstring ? O Z 5 ;~ #SingleInstance force ;# 强制重启:启动时如果旧脚本已经运行,不弹出提示,直接关闭旧的之后运行,主要是便于程序的调试和更改 6 ;~ SetStoreCapsLockMode, Off 7 SetTitleMatchMode 2 ;# Title匹配模式:Title只需要包含即可匹配 8 9 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 10 ; 脚本名称:AHK-UMSS框架 (AHK通用修饰键解决方案,任何键都是修饰键) 11 ; 中英文结合:AHK-UMSS (AHK通用修饰键解决方案 AutoHotKeyUniversalModifierSymbolsSolution) 12 ; 脚本版本号 v3.0.1 beat 13 ; AHK版本: 1.1.30 14 ; 语言:中文 15 ; 作者:心如止水<QQ:2531574300> <Autohotkey高手群(348016704)> 16 /* 17 # 脚本功能: 可以在Tab本身功能完全不受影响的前提下(包括长按和短按)让其作为修饰键,支持各种参数的自定义,能力比v1.x版本上了一个台阶。 18 ## 提示:只是框架解决方案,里面没有设置依托Tab设置大量热键,你需要根据自己的情况设置,另外Tab应该也可以改为任何的"非修饰键",比如"分号"等等等。潜力无限,等你挖掘。 19 # 衍生版本: 暂无 20 # 下一步的思路:1,支持更多自定义 2,更模块化面向对象 3,继续优化注释做到简明扼要 4,添加功能更方便(用一句函数可以完成,只需要输入按键和功能延续片段,长的#Include) 21 # 已知问题:1,在长时间发送大写修饰符的时候,会隔10个左右的字符发送一次小写字符,但是这个问题几乎没影响使用,这个场景太小众,看了一下没找出原因,不打算修复,拉长TabndemSpeed会改善,应该是AHK的反应太慢导致的吧。 22 # 主力更新地址1(智能热键论坛) https://www.autoahk.com/archives/12126 23 (格式为 https://www.autoahk.com/archives/[0-9]{6}) 24 # 主力更新地址2(博客园随笔) https://www.cnblogs.com/xrvu/p/9787884.html 25 (格式为 https://www.cnblogs.com/xrvu/p/[0-9]{7}.html) 26 */ 27 ; ^_^: 如果您有什么新的想法和改进的建议,或者是发现了BUG,欢迎加我的QQ,一起探讨改进 :^_^ 28 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 29 ;~ 测试区域 30 31 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 32 /* 33 版本信息: 34 v1.0.2:增补了注释,Tab单击改为默认关闭 35 v1.0.3:在名字中加入AHK(AutoHotKey)便于搜索引擎的爬取 36 v1.1.0:1,添加注释(改造潜力/派生方案) 2,增加注释"主更新"地址 37 v1.1.1 注释:刚刚才发现,如果要实现这个思路,必须使用热键自带的方法,不能使用send的方法,谢谢cobocy的指教,如果您知道帮助文件在哪个地方讲过这件事情,欢迎您能够告诉我,我还没找到。 38 v1.1.5 1,紧急修复BUG,level3没有加return,会导致出现误触发,已修复,感谢@长岛的雪 的报告 2,增加了"关于响应速度的说明"等注释 39 v2.0beat:这个版本的机制和之前的版本是完全不同的,所以两条线更新,类似AHKL和AHK2,有关系,但是区别很大。 40 v2.0.1beat:1,修复MsgBox %LongPressLoop%测试语句忘记注释的BUG 2,解决了开头的脚本信息错误的问题,增加了一些内容 41 v2.0.2beta :改为更容易被检索和理解的名字,AHK-UMSS (AHK通用修饰符解决方案 AutoHotKeyUniversalModifierSymbolsSolution) 42 v2.0.3beta :增加了最后的"尾巴:伟大的征途 - 这个脚本的来龙去脉"的注释 43 v2.0.4beta :实现了按键变量的自定义 44 v2.0.5beta :1,支持旧版Tab++1.x的热键方式(其实更适合大多数人的情况,默认就是用这个) 2,支持一键修改热键 45 v2.1.0 :1,"热键白名单" 注释增补 2,新增3模式,表示采用禁用单击发送修饰键的OldKey模式 3,Old等待时间单独用一个变量来表示 4,增加快速为当前修饰键添加连发热键的方法 5,加入"设置保存并重启当前脚本的热字串" 6,"跳板热键(中转键)可更改" 7.感谢"沉默不语"的BUG反馈 46 v2.1.1 :解决一个会导致程序失效的严重问题 47 v2.1.2 :1,修复CapsLock开启时,无法正常发送大写字母的问题,感谢 @丶行者先生、 的反馈 2,改TabndemSpeed=25 为 TabndemSpeed=35 48 v2.1.3 :1,使用函数ST()设置触发器,让程序可复用性更好 2,加了一些注释 49 v2.5 beat :1,修复了CapsLock等3个可切换键,无法切换的问题,感谢 @丶行者先生、 的反馈 2,默认send模式改为2 50 v2.61 beat :1,增加了send模式2+,并且改为默认 2,为了程序的简洁和可读性,不再采用"一键默认设置" 3,优化了send模式选择错误提示框显示的方式 51 v3.0 beat :新增了一种功能添加方法(新的被叫做方法1,之前的被叫做方法2),该方法非常灵活,支持通过语境约束定义热键(可以实现三按键) 52 v3.01 beat :1,注释掉一处不该有的MsgBox(调试时剩下的) 2,注释继续优化 3,自动执行段上方微调 53 */ 54 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 55 56 ;# 定义:制表符xx指的就是发送{Tab},功能xx指的就是以Tab为组合键执行的任务,比如F20 & j。 57 58 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 59 /* 60 # 关于响应速度的说明 61 ## 长按必定导致单击速度变慢:例如用户按下一个键会停留50毫秒左右,如果该键没有长按功能,那么只要检测到用户按下这个键, 在其手指没有离开的时候,可能几毫秒的时间之内这个键的功能就已经被激发了;但是如果这个键设置了长按功能,那么只要用户的手指没有离开,系统就无法分辨到底是长按还是短按,命令就不能发送,直到用户的手指离开或者时间已到才可以采取相应的动作,人短按的时候肯定是不如机器快的,那么"只要按键开启了长按,短按的效率必定下降"。 62 63 # UMSS针对该问题的方法: 64 ## 广泛的自定义:既然速度降低,是不可避免的,那么就应该有一个可以完全自定义的方案,UMSS就是如此。你可以选择好几种模式。 65 66 ## 四种模式供你选择 九个参数均可自定义 两种不同的功能添加方法 67 68 ### 模式1 修饰键功能保全方案:修饰键的完整功能被保留。在这个模式下修饰键是可以发送自己的,比如修饰键为Tab,那么 无论是短按还是长按都是可以正常发送Tab的,长按的,连发效果也保留。这个模式下的诸多参数,你可以自定义,以便调整到一个最适合你的(默认方案应该适合大多数人,所以说如果不是遇到问题,那就先不用调) 69 ### 模式2 可单击修饰键方案:在方案二的基础上,如果快速的单击的话,是可以发送修饰键本身的。(但是有一定时间限制,长按时间超过大约1秒就不会再发送) 70 ### 模式2+ 可单击修饰键方案Plus:在方案二的基础上可以自定义"等待时间"(Timeout2),从 1s到无穷 可以自定义 71 ### 模式3 完全修饰键方案:这个很好理解,也就是修饰键无法发送自己(大多修饰键都如此)。不过如果在此模式下你要用修饰键本身,方案就是启用组合热键来替代发送功能(包括连发也可以一并解决),程序内置了OtherTabndemKey,你可以通过修此参数一键设置。 72 73 ## 心如止水的方案:我个人的方案就是让Tab安安静静的做他的修饰键,我把send{Tab}的功能外包给了CapsLock+Space,主要是和我的语音识别键是离得很近的,在我的思维导图软件iThoughts用起来很爽,所以就习惯了。 74 ## 特别提示:主要的作用是把非修饰键当做修饰键来用,所以:1,已经是修饰键的例如(Ctrl)不能用 2,一定有延迟,所以对延迟敏感的场景不能用(比如字母,会影响打字速度) 75 76 77 */ 78 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 79 80 ;# 声明全局变量 81 global LongPressWT,TandemWT,TabndemSpeed,Timeout,OP,TA,keys,LongPressLoop,OldTimeout,OtherTabndemKey,FF,Timeout2 82 83 ;--------------------------------------------------------------------------------------------------------------- 84 85 86 ;# 设置详细说明 87 88 ;# 全局生效设置 89 ;## 被修改为修饰键的键 Keys(String) :无需多解释,默认是Tab。如果使用分号等,不要忘记转义。 90 ;## 替代连发按键 OtherTabndemKey(String) :可以设置一个热键(与当前修饰键),来专门连发当前修饰键,以弥补Tab1.x中按键无法连发的问题(默认不开启留空,如果想开启,填入对应按键就可以,比如global OtherTabndemKey:="u") 91 ;## (已经弃用)是否强制使用默认参数 OP(0|1):0的意思是关闭,1是打开 92 ;## 中转键 FF(String):中转热键是为更好的实现程序迫不得已的选择,好在系统内置了F13-F24,平常根本就用不到,所以刚好拿来做中转。提供更改中转键的选项,是因为很多用户可能会同时使用多个修饰键,如果不重新定义,那就会冲突。 93 94 ;# 在"模式1 功能保全方案"中起效的设置 95 ;## 长按等待组合键触发时间 LongPressWT(ms):在模式1中,系统会等待您一段时间,在这个时间段内,如果按下组合键则触发功能,否则就不触发功能,而是发送修饰符本身。该项就是设置此时间段的。 96 ;## 修饰符连发等待时间 TandemWT(ms):在模式1中,如果已经超过了等待时间,程序会进入发送本身模式,但是在连续发送之前会有一段时间的停顿(Windows正常的连发就是如此)。该项就是设置该停顿的。 97 ;## 修饰符连发速度 TandemSpeed(ms):在模式1中,进入了实质性的连发阶段,虽然叫做连发,其实还是有一小段的间隔的,发送的快了,不好掌握(Windows正常的连发就是如此)。该项就是设置该小段间隔的。 98 ;## 功能连发超时 Timeout(s):特别提示的是,TimeOut的单位和别的不一样,不是毫秒而是 秒。在模式1中,进入了功能的连发阶段,连续发送很长的一段时间之后,为了防止出现BUG,连发会停止(因为一般人也用不到连发五秒,基本上半屏幕符号了)。该项就是设置功能连发上限时间的。 99 100 ;# 在"模式2 可单击修饰键方案"以及"模式3 完全修饰键方案"中起效的设置 101 ;## Old版本按下等待时间 OldTimeout(s):在Old模式下,和windows本身的不同,修饰键按下是有等待时间的(比如按下5秒内可以触发)。该项就是设置该等待时间的。 102 103 ;# 在"模式2+"的设置 104 ;## Timeout2(S),在Timeout2内,长按keys,只要功能没有触发,松开后都会发送keys本身。默认是无穷,也就是-1,可以重新自己设置(最少1s)。 105 ;--------------------------------------------------------------------------------------------------------------- 106 107 ;# 添加新的功能 108 ;# 这只是一个框架,所以里面基本上没装什么功能,就只是装了一个按下jk分别左右移动的功能。 109 ;# 装功能的话你搜一下"<<<<<<<<<<<<功能添加区>>>>>>>>>>>>"就行了 110 111 ;# 强制使用默认模式:1表示强制使用默认参数,0表示采用自定义参数 112 ;## 为了程序的可读性,该设置取消 113 ;~ global UseDefault:=0 114 115 ;--------------------------------------------------------------------------------------------------------------- 116 117 ;# 不可自定义参数 118 119 ;# TA是功能被触发计数器,1表示有Tab功能已经被触发,0表示并没有,所以每个功能都要以TA=1结尾,告诉程序功能已经触发了。 120 121 122 global TA:=0 123 ;# 通过用户输入的长按等待时间计算检测循环次数 124 ;~ global LongPressLoop :=Ceil(500/50) 125 ;改为10,提高灵敏度 126 global LongPressLoop :=Ceil(500/10) 127 128 ;--------------------------------------------------------------------------------------------------------------- 129 130 131 ;# 可自定义参数 132 133 ;## 全局设置 134 135 ;### 请选择模式 模式1-修饰键功能保全方案 模式2-可单击修饰键方案 模式2+ 可单击修饰键方案Plus 模式3-完全修饰键方案 136 global MySendMode:="2+" 137 138 ;### 选择要变成修饰键的按键 139 global keys:="Tab" 140 141 ;### 一键设置替代组合键(默认关闭) 142 global OtherTabndemKey:="" 143 144 ;### 设置"中转键" 145 global FF:="F20" 146 147 ;### 设置连发时间上限 148 Timeout=5 ;单位是s 149 150 ;## 为模式1设置参数 151 152 LongPressWT=500 ;### 判断为长按的时间 153 TandemWT=180 ;### 进入发送模式后,第一个发送与连发的间隔 154 TabndemSpeed=35 ;### 进入连发模式后,连发之间的间隔 155 156 ;## 为模式2&3设置参数 157 158 ;### 功能组合键等待时间(过了等待时间不会响应功能组合键) 159 OldTimeout=5 ;单位是s 160 161 ;## 为模式2+设置参数 162 163 ;### 按键等待时间(过了等待时间,松手也不会发送按键本身,也不会响应功能,-1代表无限) 164 Timeout2=-1 ;单位是s,-1代表无限(实际上<=0都代表无限) 165 166 ;--------------------------------------------------------------------------------------------------------------- 167 168 169 170 ;通过HotKey的方式定义热键(便于直接使用变量修改) 171 172 if(MySendMode==1) 173 { 174 Hotkey,%Keys%,MyKey,I2 175 } 176 else if(MySendMode==2) 177 { 178 Hotkey,%Keys%,OldMyKey,I2 179 180 ;# 这里是 mode2 中注册 单击映射 的地方 181 Hotkey,%FF%,EnableClick,I0 182 } 183 else if(MySendMode=="2+") 184 { 185 Hotkey,%Keys%,MyKey2_Plus,I2 186 } 187 else if(MySendMode==3) 188 { 189 Hotkey,%Keys%,OldMyKey,I2 190 } 191 else 192 { 193 MsgBox,16,模式选择出现错误,错误的 MySendMode 值是 "%MySendMode%" 194 } 195 196 197 ;--------------------------------------------------------------------------------------------------------------- 198 199 ;# 拼接Timeout2 200 if (Timeout2>0) 201 Timeout2:="T" . Timeout2 202 else 203 Timeout2:=-1 204 205 ;--------------------------------------------------------------------------------------------------------------- 206 207 208 209 ;如果不为空就注册热键,用于修饰键自身的连发 210 if !(OtherTabndemKey=""){ 211 212 Hotkey,%keys% & %OtherTabndemKey%,OtherTabndem,I0 213 } 214 215 ; # 注册主功能热键(请放在最后,因为会干扰自动执行段) 216 domain() 217 218 ; # 自动执行段结束 219 return 220 221 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 222 223 ;# 热键白名单(如果使用此脚本之后,系统或其它应用的相关热键出现问题无法使用,可以把热键添加到这个名单中。新版本已经基本修复了这个问题,但是还留着以防后患吧。) 224 225 #inputlevel,3 226 227 ;## 在这个层级是不覆盖系统默认键的,可以设置系统默认键的白名单 228 ;~的意思是不覆盖系统本身的快捷键 229 230 ;### 为了能让系统的窗口切换可以正常运行,以Level3的速度发送这些按键,避免受到干扰 231 ;位置0 232 ;# 注意 每个系统热键下面,必须加return 233 /* 234 235 ~!Tab:: 236 return 237 ~#Tab:: 238 */ 239 return 240 241 242 #inputlevel 243 244 245 ;--------------------------------------------------------------------------------------------------------------- 246 247 248 ;<<<<<<<<<<<<功能添加方法1:示例功能区(推荐)>>>>>>>>>>>> Start 249 #If GetKeyState(keys,"p") ;## 语境约束:意思是当keys被实际按下时,一下内容就生效 250 251 252 q:: 253 ST() ;## 这个函数的意思是告诉程序已经触发功能,所以不需要再等,send模式1和send模式2+用得到,send模式2-3用不到 254 MsgBox,成功触发 `n %keys%+q 热键 255 return 256 257 ;## 方法1的优势:方法1 很灵活,可以搭配系统中其他的修饰键,做到定义3快捷键 ,而且你也可以使用语境约束来适配更多情景,比如当Word存在时(下面有例子)。 258 !q:: 259 ST() 260 MsgBox,成功触发 `n Alt+%keys%+q 热键 261 return 262 263 ;## 两种方法的优先级:当方法1和方法2冲突时,方法2优先,在这里Keys+k代表向右移动2次,在模式2中是1次,只有注释方法2中的内容,才能移动2次。 264 k:: 265 ST() 266 send,{right 2} 267 return 268 return 269 270 #If ;## 语境约束结束 271 272 273 ;--------------------------------------------------------------------------------------------------------------- 274 275 #If GetKeyState(keys,"p") AND WinExist("ahk_exe WINWORD.EXE") ;## 语境约束:意思是当keys被实际按下并且Word.exe窗口存在时,生效 276 277 !w:: 278 ST() 279 MsgBox,成功触发 `n Alt+%keys%+w 热键 280 return 281 282 #If ;## 语境约束结束 283 284 285 ;<<<<<<<<<<<<功能添加方法1:示例功能区(推荐)>>>>>>>>>>>> End 286 287 288 289 ;--------------------------------------------------------------------------------------------------------------- 290 291 292 293 ;<<<<<<<<<<<<功能添加方法2:功能添加区>>>>>>>>>>>> Start 294 domain(){ 295 global LongPressWT,TandemWT,TabndemSpeed,Timeout,OP,TA,keys,LongPressLoop,OtherTabndemKey,FF 296 297 ;# 注册热键等等被激发 298 Hotkey,%FF% & j,Kj,I0 ;这是注册热键的意思,%FF% & j中的"%FF%"就是你填的中转键,这个不用动,默认是F20,& 就是并且的意思,%FF% & j就是"当你的修饰键和j键同时按下时",kj是函数名,是要执行的功能,在下方的功能区可以自己填。I0,指的是接收等级inputlevel,具体的意思可以看帮助文件,大多数时候根本用不到,也不用去碰。 299 Hotkey,%FF% & k,Kk,I0 300 return 301 302 } 303 304 305 Kj(){ ;这个地方是函数名,命名规则是字符k+按键名,比如用修饰键配合j触发的,就叫做Kj,这不是硬性规定,只不过我觉得这样的话可读性会好。 306 ST() ;这个函数的意思是告诉程序已经触发功能,所以不需要再等,模式1和模式2+用得到,模式2-3用不到 307 308 send,{Left} ;然后这个地方就可以增加语句了,就是你的功能,这里是发送"向左",怎么做随你。如果功能代码量大,为了可读性建议使用#Include导入。 309 return ;不要忘记加return 310 } 311 312 313 Kk(){ 314 ST() 315 send,{right} 316 return 317 } 318 319 ;<<<<<<<<<<<<功能添加方法2:示例功能区>>>>>>>>>>>> End 320 321 322 323 ;--------------------------------------------------------------------------------------------------------------- 324 325 326 327 #inputlevel 0 328 329 ;# 下面是替代连发热键 330 OtherTabndem: 331 ;修改1 332 ;~ Send,{%keys%} 333 MySend(keys) 334 return 335 336 337 EnableClick: 338 ;## 开放单击(根据需求自己考虑开不开) 339 MySend(keys) 340 return 341 #inputlevel 342 343 344 345 346 ;--------------------------------------------------------------------------------------------------------------- 347 348 #inputlevel,2 349 ;# 这是旧版发送方式 350 OldMyKey(){ 351 352 global LongPressWT,TandemWT,TabndemSpeed,Timeout,OP,TA,keys,LongPressLoop,OtherTabndemKey,FF 353 send,{%FF% Down} 354 355 KeyWait, %keys%,T%OldTimeout% 356 { 357 send,{%FF% Up} 358 } 359 return 360 } 361 #inputlevel 362 363 ;重置触发器 Reset Trigger 364 RT(){ 365 global TA 366 TA:=0 367 return 368 } 369 370 371 ;设置触发器 Set Trigger 372 ST(){ 373 global TA 374 TA:=1 375 return 376 } 377 378 379 #inputlevel,2 380 381 382 ;--------------------------------------------------------------------------------------------------------------- 383 384 ;位置1 385 ;# 这是新版发送方式(模式1) 386 MyKey() 387 { 388 ;声明一下,该函数内使用的全局变量 389 global LongPressWT,TandemWT,TabndemSpeed,Timeout,OP,TA,keys,LongPressLoop,OtherTabndemKey,FF 390 391 ;# 先按下%FF%(便于后面的捕获) 392 send,{%FF% Down} 393 394 ;# 循环十次 如果出了循环之后说明用户是在单独长按,企图发送连续的Tab 395 loop,%LongPressLoop% 396 { 397 ;功能激活在没有检测到keys被松开的时候功能激活了 398 if (TA==1) 399 { 400 401 KeyWait, %keys%,T%Timeout% 402 { 403 ;~ MsgBox,Tab被释放,所以%FF%被释放 404 405 send,{%FF% Up} 406 RT() 407 return 408 } 409 410 ;重置触发器 411 send,{%FF% Up} 412 RT() 413 return 414 } 415 ;不管是最后Tab等到了释放,或者是过了10秒,程序就结束了 416 ;重置触发器 417 418 ;如果发现功能没有被激活,那就检查是否Tab已经被松开,如果是的话,再检查一下触发器,如果没有触发,那么说明他只是想发送一个单独的Tab,如果触发了,那就释放%FF%,结束程序 419 ;如果发现功能没有被激活,先检查一下Tab是否被松开,如果被松开了那么再确认一下功能是否被激活,如果确认激活了,那么松开即可,如果没有被激活发送一个Tab松开 420 421 ;中途突然发现keys被松开了 422 if !(GetKeyState(keys,"P")) 423 { 424 425 if (TA==0) 426 { 427 send,{%FF% Up} 428 MySend(keys) 429 RT() 430 return 431 } 432 433 ;离开的同时去了其他线程,既然已经离开了,那么就直接释放%FF%,什么我感觉还是可以的 434 send,{%FF% Up} 435 RT() 436 return 437 } 438 439 ;我发现既没激活,都没有被松开,那么就等待50毫秒,如此重复,500毫秒过去之后,说明用户是想长按 440 441 ;~ Sleep 50 442 ;改为10 提高灵敏度 443 Sleep 10 444 445 } 446 ;# 500毫秒已经过去,并没有触发功能,也没有松开Tab 447 ;## 既然不想触发功能,那么就松开%FF% 448 449 send,{%FF% Up} 450 ;## 松开之后,立即发送一个Tab 451 MySend(keys) 452 ;## 等待200毫秒 之后检查是否松开 453 Sleep %TandemWT% 454 ;~ Sleep 200 455 ;等到200毫秒之后,连续发送,直到检查到用户松开 456 ;持续按下200毫秒,进入循环模式 457 ;只要检查发现按下就一直发,如果发现没按下就停下 458 459 loop 460 { 461 462 if !(GetKeyState(keys,"P")) { 463 RT() 464 return 465 break ;如果中途松开,那就跳出循环, 程序也就结束了 466 } 467 468 ;如果一直不松开,就一直发送下去, 469 else 470 { 471 MySend(keys) 472 473 Sleep %TabndemSpeed% 474 } 475 } 476 477 RT() 478 } 479 return 480 481 482 ;--------------------------------------------------------------------------------------------------------------- 483 484 485 ;# send模式2+ 的函数 发送模式2Plus 486 MyKey2_Plus() 487 { 488 ;## 声明一下,该函数内使用的全局变量 489 global Timeout2 490 491 ;## 按下%FF% (等待被触发) 492 send,{%FF% Down} 493 ;## 等待被松开 494 ;### 如果是-1那么就一直等,如果不是就等"Timeout2"秒 495 if (Timeout2==-1) 496 KeyWait,%keys% 497 else 498 KeyWait,%keys%,%Timeout2% 499 ;~ KeyWait,%keys%,T1 500 ;### 如果超时了 501 if (ErrorLevel=1){ 502 ;~ MsgBox,超时 503 ;#### 释放%FF% 504 send,{%FF% Up} 505 ;#### 重置计数器 506 RT() 507 return 508 } 509 else 510 { 511 ;~ MsgBox 6 512 ;## 松开了如果功能已经触发则不发出原按键,否则就发出 513 514 515 ;### 如果松开之后功能已经触发 516 if (TA==1){ 517 ;#### 释放%FF% 518 send,{%FF% Up} 519 ;#### 重置计数器 520 RT() 521 522 } 523 ;### 如果松开之后功能并触发,那么就发出原按键即可 524 else 525 { 526 527 ;#### 释放%FF% 528 send,{%FF% Up} 529 ;#### 重置计数器 530 RT() 531 MySend(keys) 532 533 return 534 } 535 } 536 537 538 539 } 540 541 #inputlevel 542 543 544 ;--------------------------------------------------------------------------------------------------------------- 545 546 547 ; # 设置保存并重启当前脚本的热字串 ;rl 548 #If WinActive(A_ScriptName) 549 ;###保存并重启当前脚本 550 :?:`;rl:: 551 Sleep 25 552 send ^s 553 Sleep 25 554 Reload 555 return 556 #If 557 558 559 ;--------------------------------------------------------------------------------------------------------------- 560 561 562 563 ;# 以下是用到的函数 564 565 ;# 检测目前CapsLock状态 566 CheckCapsLock(){ 567 ;开着是1,关掉是0 568 return GetKeyState("CapsLock","T") 569 } 570 571 572 ;--------------------------------------------------------------------------------------------------------------- 573 574 575 ;# 针对CapsLock等可切换热键的针对性优化send函数 576 MySend(ukey){ 577 578 ;# 如果发现是3种切换键,那么不使用Send,而是直接切换,速度会快很多很多 579 if(FastSwap(ukey)==1) 580 return 581 ;# 如果CapsLock没开,那么就直接发送即可 582 if(CheckCapsLock()=0){ 583 Send,{%ukey%} 584 return 585 } 586 ;~ /* 587 ;如果发现并非单字符字母键,那么不在该使用场景内,直接发送原版,结束程序 588 else if !(StrLen(ukey)==1){ 589 Send,{%ukey%} 590 return 591 } 592 ;如果大写是开启的,那么转换为大写再发送一下 593 ;~ */ 594 else 595 { 596 StringUpper,ukey,ukey 597 Send,{%ukey%} 598 } 599 return 600 } 601 602 603 ;--------------------------------------------------------------------------------------------------------------- 604 605 ;# 如果发现是"可切换"按键,那么就切换一下,0代表不是"可切换"按键,1代表发送了切换的指令 606 ;## 特别提示,AHK1.3.0新特性,支持用 0/1 代表 OFF/On 但是为了照顾兼容性还是用了字符串 607 ;## 由来:不知道为什么,如果直接send这些可切换键的话,切换会特别慢(帮助文件上说可以这么搞),让人以为是锁定住了,那没办法,只能用另外的方法。 608 609 FastSwap(ByRef ukey){ 610 thetemp:=CheckOfukey(ukey,1) 611 if (thetemp="0001_输入的按键不是可切换键") 612 return 0 613 else if (SubStr(thetemp,1,1)="c") 614 { 615 SetCapsLockState,% GetKeyState("CapsLock","T") ? "OFF" : "On" 616 return 1 617 } 618 else if (SubStr(thetemp,1,1)="n") 619 { 620 621 SetNumLockState,% GetKeyState("NumLock","T") ? "OFF" : "On" 622 return 1 623 } 624 else if (SubStr(thetemp,1,1)="s") 625 { 626 SetScrollLockState,% GetKeyState("ScrollLock","T") ? "OFF" : "On" 627 return 1 628 } 629 return 0 630 631 } 632 633 634 ;--------------------------------------------------------------------------------------------------------------- 635 636 637 ;# CheckOfukey 函数 检查"可切换按键"的状态 638 CheckOfukey(ByRef ukey,returnname:="0"){ 639 TheShow :="" 640 ; # 提取按键字符 只有returnname不等于0 才会返回按键的第一个字母的小写形式 641 if(returnname!="0"){ 642 TheShow := SubStr(ukey,1,1) 643 StringLower, TheShow, TheShow 644 } 645 646 if(ukey="CapsLock") 647 return % TheShow GetKeyState("CapsLock","T") 648 if(ukey="NumLock") 649 return % TheShow GetKeyState("NumLock","T") 650 if(ukey="ScrollLock") 651 return % TheShow GetKeyState("ScrollLock","T") 652 653 else 654 ;错误代码0001 655 return,% "0001_输入的按键不是可切换键" 656 } 657 658 ;--------------------------------------------------------------------------------------------------------------- 659 660 ; # checkString 函数 检查某字符串中是否含有某关键词(可以是多个,用|隔开即可) 如果有则return 1,没有return 0 661 checkString(WaitCheck,TheKey){ 662 Loop,parse,TheKey,`| 663 { 664 if(InStr(WaitCheck,A_LoopField,false,1,1)) 665 return 1 666 } 667 return 0 668 } 669 670 /* 671 672 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 673 ;# 尾巴:这个脚本的来龙去脉 674 ;# 作为不平凡而且不满足的人,我们想尽可能提升操作电脑的效率,比如说进行文本编辑这件事,那些快捷键实在是太远太乱,如果可以用Space作为修饰键就很好了。 675 知阳(Power-Keys)和Space(SpaceZ)做了大量的尝试,显然他们的方案已经能够大幅提高效率,但是比较敏感的群友(比如我和Ever)会发现,还是对中文上屏的速度有干扰(因为目前中文输入法的上屏需要按下空格,而且主流的输入法没有自定义选项)。 676 我本来想搞一个无干扰的方案,但是昨天晚上突然想明白了,无干扰的方案是不存在的(因为某个键有长按和单击,单击的速度几乎是一定要被拖慢的,在最前面举过例子),只是干扰的大小罢了,可以说以上二位的方案应该就是最优方案了,Space修饰键探索可以结束了。 677 基于以上认识,我就设计了一个可以"把任何按键都变成修饰键不会影响任何本身功能"的解决方案,里边的各个参数都可以自定义,你可以再不明白原理的基础上做出任何你想要的修改(现在可以修改9个参数,可能还会再增加一些),我用了一上午的时间,终于完工了,任何脚本的第一个版本,一定是有一些问题的,您在使用过程中如果遇到了欢迎向我反馈,我们来一起完善它。 678 最后,希望我的这个脚本能够给您带来更高效率的PC操作体验。 ^_^ 679 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 680 681 */
posted on 2018-10-14 20:49 心如止水_Zen 阅读(...) 评论(...) 编辑 收藏