文章编号-AHK-J004
之前有位群友问我,如何才能"绕过中文输入法"发送文本,他是想用自动替换一键发送邮箱,但只要在中文输入法下就会先发送到输入法框中,需要手动点一次,非常麻烦。这是常见的问题,下面我会分享三个解决方案,希望能够帮到你。^_^
方案1:SendText方案
自从v1.1.27之后,Send命令中新增了{Text}这个功能,也就是“发送文本”,可以说几乎完美的解决了这个问题。(普通的Send是发送键击,所以会误触中文输入法)。
唯一的缺点是可能是版本太新了,如果发给朋友用的话,请先告诉他,升级到最新版。
小结:作为AHK官方的解决方案,在速度和兼容性上达到了很好的平衡,应优先考虑
这里给出一个示例(AHK-J004-示例1),程序设计目的是:按下热字串“/a”,在某文本的行首加上字符串“[AHK] ”。如果不使用SendText,那么在中文输入法下将无法正常发出。
;# AHK-J004-示例1::/a:: Send,{Home} SendText("[AHK] ")return;将命令封装为函数,便于程序维护SendText(var_string){ local SendInput {text}%var_string% return}
速度:★★☆
普适性:★★★便捷性:★★★
另外,值得注意的是
- 如果SendMode是Event(也就是默认),那么Send速度会很慢,建议使用SendInput。(速度 SendInput>SendEvent>SendPlay)
- 对于长文本来说,即使是SendInput的速度还是不如SendByClip(下一种将要介绍的方法),长文本建议使用SendByClip。
- 如果你是使用“热字串自动替换”,那么“自动替换”也可以通过选项T来实现“发送文本”的功能。
方案2:SendByClip
从名字上也能看得出来,其实这就是通过粘贴来实现文本发送,在1.1.27之前,这是最常见到的解决方案。
它的优点就是长文本输入速度快(你可以看到上面的方案唰唰的过程,但SendByClip不会有,像是凭空降临),因为SendByClip往往要在两端加上一些延迟(为了提高兼容性),所以说文本越长,它对比SendText的优势也越大。如果是小段文字,比如20字之内,那么SendText要快很多,也稳定得多。
这个方法还有个问题是误触,毕竟是发送 send ^v键击实现的(后面有函数代码),也难免,好在并不严重。
小结:SendByClip的优势在于“发送长文本时速度快”,当需要快速发送大量文本时,这是不二之选
这个函数就一定要自己封装了,程序本身是没有带的。
要特别强调的一点是,我们只是通过剪切板来发送,所以不能干扰之前的剪贴板内容,保存之前的剪贴板内容需要通过## 来实现,ClipBoard是没有格式的。sendbyclip(var_string){ ClipboardOld = %ClipboardAll% Clipboard =%var_string% sleep 100 send ^v sleep 100 Clipboard = %ClipboardOld% ; Restore previous contents of clipboard.}
速度:★★☆
普适性:★★☆便捷性:★★★方案3:ControlSetText 命令
ControlSetText , Control, NewText, WinTitle, WinText, ExcludeTitle, ExcludeText
如果能用Windows Spy探测到控件的ClassNN而且是发送确定的某段文本,那么这种方法的速度非常快,也很稳定。
由于这个命令的自身特点,所以它的缺点就是,普适性差,应用场景很有限。小结:该方案最大的问题是通用性差,若已知Text控件的Class时,这无疑是一个很好的选择,既快又稳
这里给出一个示例(AHK-J004-示例2)(在文章最末尾),程序设计目的是:按下某快捷键,复制当前选中文本并且跳转到Everthing(一款好用的搜索软件)进行搜索。
速度:★★★普适性:★☆☆便捷性:★☆☆技术总结
**三种方法各有优劣,需要根据不同的场景灵活使用。
发送小篇幅文本→SendText方案发送大篇幅文本→SendByClip方案给特定的text控件发送文本→ControlSetText命令**End
心如止水是Java/AHK的持续学习者,很欢迎您来和我探讨Java/AHK问题。 QQ:2531574300 ^_^
版本信息:
v2
①增加示例2②修改了部分说法,更简单易懂v3 - 11月15日①增加了更简洁易懂的示例3②"实例"改为描述更精准的"示例"v4 - 12月05日①增加了自动替换热字串的相关说明②增加了关于发送模式的相关说明v5 - 12月08日 更换示例1,删除部分冗余内容更多文章
问题解答:
版权声明:
该文章版权系“心如止水”所有,欢迎分享、转发,但如需转载,请联系QQ:2531574300,得到许可并标明出处和原链接后方可转载。未经授权,禁止转载。
;# AHK-J004-示例2;********************用"Everthing"搜索选中文字***************************!^f:: EverthingSearch()returnEverthingSearch(){ ;## 复制内容 try { OutNameNoExt:=SuperCopy(5) } catch { global yc InputBox,t2,复制失败,% "未能复制到内容,请输入文本`n`n`(按下取消程序就结束,输入文本按下Enter或OK会继续搜索`)",,,,,,,,%Clipboard% ;如果发现用户取消了,那么什么也不做 if (ErrorLevel=1){ return } else OutNameNoExt:=t2 } ;## 如果发现对应窗口存在则激活并且填入 IfWinExist %yc% { global yc,thispath WinActivate %yc% WinMaximize %yc% ;利用修改Everything输入栏控件文字的方式,填入剪切板的内容。 ControlSetText, %TextControl%, %OutnameNoExt%, %yc% } ;## 如果发现存在,开启之后激活并且填入 else { global yc,TextControl,thispath TrayTip,在Everthing内搜索,找不到Everthing的Class%yc%`n将会先启动Everthing,,1 try { Run, %thispath% } catch { MsgBox,16,错误,没有找到路径或没有权限运行`n路径如下`n%thispath% return } ;~ MsgBox,% ErrorLevel WinWait,%yc%,,3 if (ErrorLevel=1) { ;~ MsgBox,5 MsgBox,16,错误,路径存在,但Everthing窗口并未出现(或超时) return } WinActivate %yc% WinMaximize %yc% ControlSetText, %TextControl% , %OutnameNoExt%, %yc% return } return};--------------------------------------------------------------------------------------------------------------- ;# 超级复制 SuperCopy函数SuperCopy(fast:=15){ old := ClipboardAll Sleep 50 Clipboard :="" Sleep 50 Send ^c ;测试 ;## 只要发现fast不是0就开启快速模式,如果开启fast那么就可以通过循环控制这个触发时间 if(fast!=0){ loop,%fast%{ Sleep 10 ;### 检测剪切板上是否还有内容 theruslt:=(Clipboard=="") ;如果发现不为空(为1),立即跳出 if !(theruslt){ Sleep 15 show := Clipboard TrayTip,超级复制(Fast%fast% 模式),剪切出的内容为:`n%show%,,1 Clipboard := old Sleep 15 return %show% } } ;循环结束,如果没发现就throw Exception Clipboard = %old% Sleep 35 throw Exception("CopyFail") return};## 如果没有开启快速模式,那么等待1秒钟,如果剪切板没收到才会发送错误代码else ClipWait,1;防误触暂停Sleep 50if(ErrorLevel = 1){;~ TrayTip,超级复制,剪切失败,,1Clipboard = %old%Sleep 35;## 没复制到,那么就抛出异常throw Exception("CopyFail")return};防误触暂停Sleep 15show := ClipboardTrayTip,超级复制,剪切出的内容为:`n%show%,,1Clipboard := oldSleep 15return %show%}return