关于“keywait按键等待”的一点想法

在一段时间内等待一个按键被按下、松开,可以用来做交互,也可以用来达到类似于热键嵌套。文章末尾最终代码可以直接拿来使用。

KeyWait,没有参数,默认,等待按键被释放。使用其它选项可以改。

使用D,等待按键被按下,使用L,测试按键的状态。T表示时间,在此期间。如果此参数为空, 则命令会无限期等待用户松开指定的按键或鼠标/操纵杆按钮.

  1. e::
  2.  
  3. KeyWait,r,d,t1
  4.  
  5. if  ErrorLevel
  6.  
  7. MsgBox,0
  8.  
  9. Else
  10.  
  11. MsgBox,no

在一秒钟内,按下r,keywait完成,errlrlevel设置为0,输出else的no。

这里有一个违背我逻辑的地方,一直都以为,完成、达到某种要求,会返回1,结果在keywait中,达成目的,返回0.

  1. e::
  2.  
  3. KeyWait,r,l,t10
  4.  
  5. if  ErrorLevel
  6.  
  7. MsgBox,0
  8.  
  9. Else
  10.  
  11. MsgBox,no

将d改成l,检测按键状态。直接按e,程序到达keywait行,在十秒钟时间里检测按键是否有被释放。长按r,启动热键e,放开r,被释放,那么值为0,输出else。坚持10秒不放开,没被释放,值为1,输出if。

这个命令感觉有点麻烦,不但有按键之间的关系,还有时间上的关系。

————————————

指令基本摸清楚了,开始实战吧。

在使用CAD过程中,每个命令都需要敲击一次空格,好麻烦,尝试使用长按来达到目的。

从命令e+空格入手

最终代码——目前在用

  1. e::
  2.  
  3. keywait,e,,t1
  4.  
  5. if errorlevel=1
  6.  
  7. {
  8.  
  9. send,e
  10.  
  11. send,{space}
  12.  
  13. return
  14.  
  15. }

既不是D也不是L,所以会一直等下去,直到e被释放。因为设定了T,超时就为1,利用这一点,完成长按。

——结论

keywait就我目前的理解,只有errorlevel可以用,还有就是,这个指令完成后才能继续下一步的指令。

————

缺点,这样e就不能用了,只能长按激活热键,本身e的功能就废了。改。

花了不少时间去补之前的笔记。

回过神来回顾了一下keywait,发现···要么是条件能达到,比如说一定时间内释放或者按下,要么是超时与不超时,足够用了。

最终代码——目前在用

  1. keywait,e,,t0.06
  2.  
  3. if errorlevel=0
  4.  
  5. {
  6.  
  7. send,e
  8.  
  9. return
  10.  
  11. }

在0.06秒内,e不处于按下的状态,达到条件,值为0.

  1. keywait,e,,t0.8
  2.  
  3. if errorlevel
  4.  
  5. {
  6.  
  7. send,e
  8.  
  9. return
  10.  
  11. }

在0.8秒内,e不处于按下的状态,值为0,这么理解就错了。因为我现在这个代码不论是长按还是短按,都是0.

在0.8秒内,e松开,就可以了。自己低估了计算机的计时器,其实在触发热键松开的之前,代码激活了计时器,可能都已经跑了几十几百了。

——————

到目前为止,我的功能要求已经实现了,单击不会影响字母的输出,好让它们可以组合,比如e和ex,长按可以完成指令发送。初衷是为了减少按键次数,但是,之前做了A_TimeSinceThisHotkey,发现和keywait类似,所以打算用keywait去实现双击和三击。

  1. KeyWait,e,d,t1
  2.  
  3. If ErrorLevel
  4.  
  5. {
  6.  
  7. MsgBox,目标失败
  8.  
  9. Return
  10.  
  11. }
  12.  
  13. {
  14.  
  15. MsgBox,成功
  16.  
  17. Return
  18.  
  19. }

在测试这段代码的时候有点麻烦。按理说是在一秒钟内按下e,打成,值为1,成功。应该是这样才对。但是自己测试的时候,在注释掉之前的代码的情况下,按一次e,不论如何都是成功,完全没有还手的余地;在怀疑智商的同时,取消之前代码的注释,再来测试。发现不论如何,都不能激活两个窗口,长按也不能激发快捷键了,怀疑是T的问题。

————————

代码全部由一个快捷键激活,脚本从上往下开始执行,所以代码的先后顺序很重要,时间也很重要。

在完成第一层代码目标的时候,等待T,在T完成之前,触发第二层代码目标,等待T2,以此类推,暂时这么理解。

——————

最后找到bug的原因比较狗血,不值得一说。

————

  1. e::
  2.  
  3. KeyWait,e,,t1.5 ;在1.5秒钟内等待e松开
  4.  
  5. If ErrorLevel
  6.  
  7. send,长按超过1.5
  8.  
  9. Else
  10.  
  11. Send,单击
  12.  
  13. KeyWait,e,d,t1 ;在1秒内按下e
  14.  
  15. If ErrorLevel
  16.  
  17. send,失败
  18.  
  19. Else
  20.  
  21. Send,成功
  22.  
  23. KeyWait,e,d,t0.5
  24.  
  25. If ErrorLevel
  26.  
  27. send,123
  28.  
  29. Else
  30.  
  31. Send,666

直接去测试,不论单击还是双击还是三击,都可以得到三个数据。只要筛选好,就能直接使用,把多余的删除就行。所谓多余,不论有没有else,重点errorlevel都会改变,代码可以继续下一行,不会影响之后的判断。
代码操作逻辑——热键开始的时候默认松开,按下,松开,按下,松开。(热键开始默认松开这个结论得得蛋疼,百思不得···)

终究我放弃这段代码了,变数好大···不玩了···

——+——+——+——+——+——+——+——

在实际使用过程中,发现rec需求比较大,犹豫上面的指令设定和时间紧密相关,所以使用起来有延迟,短短几毫秒的延迟,虽然不多,但是和以前相比,手指还是能感觉出来的。

解决办法,让keywait等一个e,也就是r激活热键,然后等e。

————————————————————

他人优秀代码学习:

  1. p::
  2.  
  3. keywait,p,T0.2
  4.  
  5. if errorlevel
  6.  
  7. {
  8.  
  9. msgbox,超时
  10.  
  11. return
  12.  
  13. }
  14.  
  15. keywait,p,D T0.13
  16.  
  17. if errorlevel
  18.  
  19. {
  20.  
  21. msgbox,单击
  22.  
  23. return
  24.  
  25. }
  26.  
  27. keywait,p,T0.07
  28.  
  29. if errorlevel
  30.  
  31. {
  32.  
  33. msgbox,双击
  34.  
  35. return
  36.  
  37. }
  38.  
  39. keywait,p,D T0.13
  40.  
  41. if errorlevel
  42.  
  43. {
  44.  
  45. msgbox,双击
  46.  
  47. return
  48.  
  49. }
  50.  
  51. MsgBox,三击
  52.  
  53. Return

————————————————————————————————————————

在实际使用过程中,又发现了点问题,不算大,但也是心中的结。从代码来看,我只能使用单击+长按,或者一次单击+快速双击+慢速双击,以A_TimeSinceThisHotkey和本人对keywait的理解,尚不能完成三连击的效果,对知识点消化不良,所以也不打算直接借用上面的代码。

最终代码——起初在参考文档和上面代码的时候,思考逻辑被自己限定死了。

  1. e::
  2.  
  3. KeyWait,e,,t0.2
  4.  
  5. if ErrorLevel
  6.  
  7. {
  8.  
  9. SendInput,长按
  10.  
  11. return
  12.  
  13. }
  14.  
  15. KeyWait,e,d,t0.15
  16.  
  17. if ErrorLevel
  18.  
  19. {
  20.  
  21. send,一次
  22.  
  23. return
  24.  
  25. }
  26.  
  27. KeyWait,e,t0.8
  28.  
  29. KeyWait,e,d,t0.1
  30.  
  31. if ErrorLevel
  32.  
  33. {
  34.  
  35. send,两次
  36.  
  37. return
  38.  
  39. }
  40.  
  41. else
  42.  
  43. {
  44.  
  45. send,三次
  46.  
  47. }

代码从上往下,要忽视等待时间,只能给出false。计时器激活的瞬间,可能物理键盘上的按键还没来得及松开。

第一次按键,按下的时候,激活热键,热键在被激活的瞬间,就开始计时,等待0.2秒,在此期间,松开按键,第一次按键完成,同时激活下一个一次定时器;在0.15秒内再次按下e,任务完成,errorlevel=0,条件判断无效,继续下一个定时器;这个定时器没有任何语句,但是作用不小。在第二次按下e的时候,计时器已经开始工作,很有可能会影响按键的判断,这0.8秒是用来解决激活按键到松开按键延时的问题,只要在0.8秒内松开按键,就可以正常进行第三次按键了,这0.8秒是给自己留的余地,这是最关键的一步了。之后有0.1秒的时间去第三次按键,超时就输出两次。

起初第三步不是0.8秒,是0.13秒,测试的时候发现一个问题。如果第一次短按,第二次长按,没有第三次按键,那么会默认输出三次,也就是第二次按键没松开,被最后一个计时器等到了。为了防止这样的情况,所以延长了时间,再超过我也没办法了,这TM也不算双击了。

最终代码——长按、单击、单击+长按、双击、三击。

  1. e::
  2.  
  3. KeyWait,e,,t0.2
  4.  
  5. if ErrorLevel
  6.  
  7. {
  8.  
  9. SendInput,长按
  10.  
  11. return
  12.  
  13. }
  14.  
  15. KeyWait,e,d,t0.15
  16.  
  17. if ErrorLevel
  18.  
  19. {
  20.  
  21. send,一次
  22.  
  23. return
  24.  
  25. }
  26.  
  27. KeyWait,e,t0.8
  28.  
  29. if ErrorLevel
  30.  
  31. {
  32.  
  33. send,短按长按666
  34.  
  35. return
  36.  
  37. }
  38.  
  39. KeyWait,e,d,t0.1
  40.  
  41. if ErrorLevel
  42.  
  43. {
  44.  
  45. send,两次
  46.  
  47. return
  48.  
  49. }
  50.  
  51. else
  52.  
  53. {
  54.  
  55. send,三次
  56.  
  57. return
  58.  
  59. }

在此基础上修改出双击+长按也是可行的。现在脉络清清楚楚,想怎么改都可以了,这让我想到了单片机的延时消抖···经验很重要,多接触,多积累。为什么一开始想不到,而是任务完成了才想到···只能说自己动手少···唉······

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
其他应用

剑灵咒术师卡刀

2016-11-20 12:27:01

其他教程

关于“利用鼠标切换软件窗口功能”的一点笔记

2016-11-21 1:29:39

0 条回复 A文章作者 M管理员
欢迎您,新朋友,感谢参与互动!
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
私信列表
搜索