;# 母文章 https://zhuanlan.zhihu.com/p/48977298
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 脚本名称:函数对象初窥①_实例2 [直接可用版本] ; 脚本版本号 v0.2 ; AHK版本: 1.1.30 ; 语言:中文 ; 作者:心如止水<QQ:2531574300> <Autohotkey高手群(348016704)> /* # 脚本功能:放到知乎上面的代码本来就是个示例,因为还有一些外围的变量和函数没有写进去,所以不可能直接运行的。 有一位群友告诉我想直接能够用,那我就把相关的lib/标签,等等等干脆都放进来了。这个应该是直接就能用的,稍微改改就可以。 # 不过这一个是没有继续维护的计划的,可能有哪个地方就没搞好,但是不会更新了. */ ; ^_^: 如果您有什么新的想法和改进的建议,或者是发现了BUG,欢迎加我的QQ,一起探讨改进 :^_^ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;~ #Warn ;# 开启 变量相关警示 ; #Warn UseUnsetLocal,Off ;#禁用局部变量的空变量警告(算了吧) #NoEnv ; 不检查空变量是否为"环境变量",可以极大地提高效率 ; # 热字串设置 只是把空格作为终止符,(◎是我找了一个最偏门的来充数的,因为按照帮助,文档上所说是不能单独用空格的,最多是空格之外再加一个) #Hotstring EndChars ◎ ; # 热字串设置 c 区分大小写 o 删除停止符号 Z重置计数器 ?可以混在单词中 #Hotstring ? O Z ;让鼠标不打扰热字串触发(副作用是 "也阻止了热字串需要的鼠标钩子") #Hotstring NoMouse #Warn ClassOverwrite ;#类覆盖警告 SetTitleMatchMode 2 SendMode Input ;#Input: 让 Send, SendRaw, Click 和 MouseMove/Click/Drag 切换到 SendInput 方法. #SingleInstance force SetFormat,Float,0.2 ;--------------------------------------------------------------------------------------------------------------- ;# 主体内容 ^j:: ExActivateAndOpen("- 笔记.itmz",Func("JumpAndSearch").Bind("ahk_class EVERYTHING","Edit1","C:\Program Files\Everything\Everything.exe",1,"ahk_class EVERYTHING"," <"" - 笔记.itmz"">!<"".lnk""> ","Everthing"),,,,,,,true) return ;# 这是一个Word的例子,就是普通的"ExActivateAndOpen",用的最多 !^w:: ExActivateAndOpen("ahk_class OpusApp","C:\Program Files\Microsoft Office\Office16\WINWORD.EXE") return ;--------------------------------------------------------------------------------------------------------------- ;# 用到的两个函数 ;## ExActivateAndOpen函数
/*
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 脚本名称:ExActivateAndOpen 函数
; AHK版本: 1.1.30
; 语言:中文
; 作者:心如止水<QQ:2531574300> <AHK持续学习者沙龙(928220639)> <Autohotkey高手群(348016704)>
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; # ExActivateAndOpen 函数说明书
; ## 功能介绍:可以为窗口设置"激活"/"最小化"(之后还会加入"老板键/静音"模式)的快捷键/热字串(激活后可设置最大化)
如果发现对应窗口不存在,还可以通过Run/CMD/Function等多种方法拉起程序,有丰富的自定义功能,可以极大的提高程序切换效率。
; ## 参数介绍
; ### t 意思是title,指的是程序的标题或者class/exe
; ### p 意思是path,指的是程序的路径,如果程序不存在的话,就会Run运行(可以开启CMD/Function模式)
; ### ex 意思是排除的title,比如,如果你想给一个叫做"清单"的窗口设置一个激活的快捷键,那是你不希望激活"清单 - 搜索",那么你就可以添加"搜索"到ex中。
; ### option 指的"标题匹配选项",一共有三组,"1|2|RegEx"/"fast|slow"/"on|off",每组最多填写一个,也可以不填,那么就按照默认的方式查找
; ### NoMax 指的是非自动最大化的title,在激活程序之后,默认是要将窗口最大化的,你可以设置黑名单。支持通过|分隔实现多项检测,比如:"AutoHotKey|Lisr|Ra2"。
; ### WinDelay 指的窗口操作的延迟,如果不更改会依照默认来运行,如果未更改(自动执行端和该线程之前)那么默认就是100毫秒,-1是无延迟,具体请参阅帮助文档。
; # 之后的改进(通过OP开启):1,Run可以改为CMD模式2,老板键模式(通过OP开启),4,名字去掉Ex 5,支持NoRun模式(NoRun后,不只是Run,CMD也不能运行) 6,支持老板键隐藏静音模式 7,支持Ex通过(|)实现多参(通过外部方式,自己封装一个,函数函数,里面会先匹配出ex相关的布尔变量(local),可以直接调试,而不是内置命令方式,降低调试难度,命令太难用)
;#### 关于NoMax和AAOWinDelay,这是该方法的两个隐藏参数,因为这两个往往是全局性的,非要通过专门的方法来更改
;### EnableCMD/EnableFunction分别是开启CMD或函数模式(两个不能同时开)
;### EnableWinMAX 是否让窗口开启后最大化 。如果不填则"模式为CMD或Function时默认不是最大化,其他情况默认最大化"("Fully automatic")。
; ^_^: 如果您有什么新的想法和改进的建议,或者是发现了BUG,欢迎加我的QQ,一起探讨改进 :^_^
;# 以下是版本信息
v3.0 : 之前用这个函数用了好长时间了,但是一直都没整理出来,今天正好要分享,就把注释整理了一下,并且修复了一些问题
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
*/
ExActivateAndOpen(t,p,ex:="",option:="",UD_NoMax:="",UD_AAOWinDelay:="",WinWaitTime:="5",EnableCMD:=false,EnableFunction:=false,EnableWinMAX:="Fully automatic"){
;# 两个选项一般是全局的,很难想象针对某个热键单独定义NoMax或AOOWinDelay,所以没有给出单独定义的方案
global NoMax,AAOWinDelay ;NoMax,不自动最大化的窗口(可以使用‘|’分隔多个关键词);AOOWinDelay在该函数内设置窗口操作的延迟
;---------------------------------------------------------------------------------------------------------------
;# 检测最大化选项
;## 如果是默认值,那么根据其他选项给EnableWinMAX赋默认值
if (EnableWinMAX="Fully automatic"){
A1:=EnableFunction+EnableCMD
;## A1>=1说明开启了两个模式中的一个,那么EnableWinMAX关闭
if (A1)
EnableWinMAX:=false
else
EnableWinMAX:=true
}
;# 如果不是默认值,那就检测一下是否是true或者flase(0/1),如果都不是那么throw
else{
A2:=(EnableWinMAX=false)
A3:=(EnableWinMAX=true)
;# 如果一个都不是,那就是填错了,那就throw
if (A2+A3)=0
throw Exception("EnableWinMAX ParaMeter Error")
}
;---------------------------------------------------------------------------------------------------------------
;# 防止CMD和Function同时开启
if (EnableCMD+EnableFunction=2)
throw Exception("EnableCMD和EnableFunction不允许同时开启")
SetWinMaxMode:=true
SetWinDelayMode:=true
if (UD_NoMax="") AND (NoMax="")
SetWinMaxMode:=false
;## 用户是空的 全局不是 那么用全局
else if ((UD_NoMax="") AND (NoMax!=""))
UD_NoMax:=NoMax
;## 剩下的可能性就是都有,或者仅仅UD_NoMax有,都不用东
UD_NoMax:=t
;## 用户没填(为空) ##全局的没有(为空) 那么就什么也不动
if ((UD_AAOWinDelay="") AND (AAOWinDelay=""))
SetWinDelayMode:=false
;## 用户没填(为空) ##全局的有(不是没有) 那么就用全局的
else if ((UD_AAOWinDelay="") AND (AAOWinDelay!=""))
UD_AAOWinDelay:=AAOWinDelay
;## 用户填了 ##全局的有 那么用户的(什么也不用动)
;~ MsgBox,1
;## 设置WinDelay并且把原来的设置备份在Old_AAOWinDelay
if (SetWinDelayMode){
Old_AAOWinDelay:=A_WinDelay
SetWinDelay %UD_AAOWinDelay%
}
;---------------------------------------------------------------------------------------------------------------
;# 自定义"标题匹配选项"
;## 总入口,如果发现option为空,那么直接跳过这一大段
if (option!=""){
;#### 检查一下"1|2|RegEx"/"Fast|Slow"/"OFF|On" 每组选项不能超过1个,如果是那就备份好,到函数结尾之后还原,避免函数的运行,影响到之后的语句。
TMM:=(checkString(option,"1|2|RegEx",true))
if (TMM>1)
throw Exception("Too many(>1) TitleMatchMode Option")
else if (TMM=1){
TMM_O:=(checkString(option,"1|2|RegEx",,true))
OldTitleMatchMode:=A_TitleMatchMode
SetTitleMatchMode % TMM_O
}
TMMS:=(checkString(option,"fast|slow",true))
if (TMMS>1)
throw Exception("Too many(>1) TitleMatchModeSpeed Option")
else if (TMMS=1){
TMMS_O:=(checkString(option,"fast|slow",,true))
OldTitleMatchModeSpeed:=A_TitleMatchModeSpeed
SetTitleMatchMode % TMMS_O
}
DHW:=(checkString(option,"on|off",true))
if (DHW>1)
throw Exception("Too many(>1) DetectHiddenWindows Option")
else if (DHW=1){
DHW_O:=(checkString(option,"on|off",,true))
OldDetectHiddenWindows:=A_DetectHiddenWindows
DetectHiddenWindows % DHW_O
}
}
;---------------------------------------------------------------------------------------------------------------
;# 主函数"ExActivateAndOpen"
;## 先使用"ExActivate"检测对应窗口是否存在
;### 如果不存在那么直接运行,如果存在,就结束任务,需要提醒的是(ExActivate函数那会对窗口进行最小化,最大化等处理)
if (ExActivate(t,ex)=0)
{
;# 如果发现是cmd 那最小化运行
if InStr(p,".bat"){
;# 判断属于Run/CMD/Function中的哪一种
if (EnableCMD)
UseCMD(p)
else if (EnableFunction)
%p%()
else
Run,"%p%",,min
}
else {
if (EnableCMD)
UseCMD(p)
else if (EnableFunction)
%p%()
else
Run,"%p%"
}
;# 这个地方主要是为了窗口最大化
;## 只有EnableWinMAX开启才会最大化
;### 当模式为CMD或Function时默认不是最大化,其他情况默认是最大化
if (EnableWinMAX){
WinWait,%t%,,%WinWaitTime%,%ex%
if (ErrorLevel=1){
;# 这个总是提示蛮烦的,但是是一个很有用的东西,以后可以设置一个黑名单,也就是不弹出这个tip(但是前面的等待后面的激活不要管,没这个必要,激活去掉之后麻烦更多)
;~ TrayTip,,已等待超过%WinWaitTime%秒 但未找到窗口"%t%"`n可能是路径(p)设置错误`n或者该程序运行后不会立即打开对应窗口(这种情况如何符合要求忽视即可) 或程序运行后被杀死`n%p%
;~ MsgBox,1
}
;## 等待窗口出现,等待5秒,如果最后没出现就终止,如果出现了,先检查一下是否是活动窗口,如果不是的话,那就拉起,如果是的话,就直接最大化
if ! WinActive(t,,ex){
;8月27日:show是刚刚加上的出现意外就注释掉
if(A_DetectHiddenWindows="On"){
WinShow,%t%,,%ex%
}
WinActivate,%t%,,%ex%
;~ MsgBox,SetWinMaxMode%SetWinMaxMode%
;## 一旦发现有东西在UD_NoMax名单之中就不放大,什么时候全局不最大化?UD_NoMax为"UD_NoMax"时
if (SetWinMaxMode){
if !(checkString(t,UD_NoMax))
WinMaximize,%t%,,%ex%
}
else
WinMaximize,%t%,,%ex%
;# 只有不包含在UD_NoMax列表中的软件才会最大化
}
;## 如果窗口存在了,但是已经是被激活的状态,那就直接最大化
if (SetWinMaxMode){
if !(checkString(t,UD_NoMax))
WinMaximize,%t%,,%ex%
}
else
WinMaximize,%t%,,%ex%
}
}
;# return走之前都恢复一下之前的设置,避免对之后造成影响(设置还原)
;## 只要不是都没填就起作用
if (SetWinDelayMode){
SetWinDelay %Old_AAOWinDelay%
}
if (option!=""){
if (DHW=1)
DetectHiddenWindows %OldDetectHiddenWindows%
if (TMMS=1)
SetTitleMatchMode %OldTitleMatchModeSpeed%
if (TMM=1)
SetTitleMatchMode %OldTitleMatchMode%
}
return ;## 到这里整个函数就结束了
} ;## 这是这个函数的最后一个代码块
;---------------------------------------------------------------------------------------------------------------
;# ExActivate函数 (常常在"ExActivateAndOpen函数"内使用)
ExActivate(t,ex:=""){
;# 如果已经激活,就只是最小化
if WinActive(t,,ex){
WinMinimize,%t%,,%ex%
;# 返回"窗口存在"的信息
return true
}
;# 如果没有激活,但是存在,那么就激活
if WinExist(t,,ex){
;## 如果搜隐藏窗口就show,否则就不
if (A_DetectHiddenWindows="On") {
WinShow,%t%,,%ex%
}
WinActivate,%t%,,%ex%
;# 返回"窗口存在"的信息
return true
}
;# 没有激活也不存在,那就返回"窗口不存在的信息"
return false
}
;---------------------------------------------------------------------------------------------------------------
;## JumpAndSearch函数 /* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 脚本名称:一键跳转并搜索选中文字(JumpAndSearch)(用印象笔记作为例子) ; 脚本版本号 v2.0 ; AHK版本: 1.1.30 ; 语言:中文 ; 作者:心如止水<QQ:2531574300> <Autohotkey高手群(348016704)> ; 参考了 交流群里"九九归一"的《用Everything搜索选中文字》 ;# 灵感来自交流群里"九九归一"的《用Everything搜索选中文字》,我觉得印象笔记也需要这么一个热键,所以就简单移植了一下。 ;# 改进方面:采用了SuperCopy的函数,兼容性更好,更易用 ;# 提醒:1,默认参数是64位国内版,如果是其他版本,请自行修改参数(包括Class/控件名/路径等参数都要改) 2,默认热键是Win+A可以自行更改 # JumpAndSear函数说明书 AHK版本: 1.1.30 # 语言:中文 # 作者:心如止水<QQ:2531574300> <Autohotkey高手群(348016704)> ## 功能介绍(默认下) : 一键跳转并且填写文字到控件,可以用于Everthing/印象笔记等的一键搜索 ## 参数介绍 ### WinTitle 要跳转的窗口名称 ### TextControlClassNN 要发送点击并且填写文字的控件名称(ClassNN) ### ThisPath 程序路径(如果没有找到程序的话,先run程序) ### EnableInPutBox (是否在没有复制到文本的情况下弹出InputBox手动输入文本) ### TextOnInputBox (在InputBox上再加上一些字符串来说明) ### Prefix (在set到control的text之前可以加入前缀) ### TheSoftName 要跳转到的那个软件的名称(主要是为了TrayTip提示的方便) ### EnableOnlyClickMode 开启这个模式之后,在InputBox对话框中可以直接按下Ctrl/Alt跳转到对应的应用而不发送text到控件 ;--------------------------------------------------------------------------------------------------------------- ; ^_^: 如果您有什么新的想法和改进的建议,或者是发现了BUG,欢迎加我的QQ,一起探讨改进 :^_^ ;# 以下是版本信息 v1.5 Beta 1,Class和控件变量化 2,SuperCopy的fast参数改为5 3,TrayTip内容优化 4,注释掉"MsgBox,% path",调试用的,忘记注释了 5,路径变量化 6,对于错误的处理更好 v1.6 Beta 修复变量漏下忘记用导致的控件使用错误问题 v1.7 Beta 1,可以在字符串前面加内容,比如印象笔记中经常用到标题搜索"intitle:" 2,lib化 v2.0 1,修复了当程序不存在的时候开启后不 Set Text 的问题 2,增加OnlyClick模式 也就是说在没有复制的内容,而开启文本框之后,如果再按一下Ctrl或者Alt那么就直接跳转,而不填入内容(有时候我们只是需要跳转而已) 3,lib化,参数直接调用函数传入即可。 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */ #if WinActive("JumpAndSearch : 复制失败") #if JumpAndSearch(WinTitle,TextControlClassNN,ThisPath,EnableInPutBox:=1,TextOnInputBox:="",Prefix:="",TheSoftName:="",EnableOnlyClickMode:=true){ local if (EnableOnlyClickMode){ Hotkey, If, WinActive("JumpAndSearch : 复制失败") Hotkey,Ctrl,jtjt,T5 Hotkey, If, WinActive("JumpAndSearch : 复制失败") Hotkey,Alt,jtjt,T5 OnlyClick:=false } try { ;# 这就是故意开启"legacy",因为保留在剪贴板上是有用的,因为可能下一分钟你就需要了 TheText:=SuperCopy(5,,true) } catch { if(EnableInPutBox=1){ if (EnableOnlyClickMode) InputBox,t2,JumpAndSearch : 复制失败,% "未能复制到内容,请输入文本`r`n(按下取消程序就结束,输入文本按下Enter或OK会继续搜索`) `r`n`r`n 按下Ctrl/Alt可以仅仅跳转聚焦而不会把Text填入控件中" . TextOnInputBox,,,,,,,,%Clipboard% else InputBox,t2,JumpAndSearch : 复制失败,% "未能复制到内容,请输入文本`r`n(按下取消程序就结束,输入文本按下Enter或OK会继续搜索`) `r`n" . TextOnInputBox,,,,,,,,%Clipboard% ;如果发现用户取消了,那么什么也不做 if (ErrorLevel=1){ return } else { TheText:=t2 ;# 如果只是跳转聚焦的话,并且用户填入了EnableOnlyClickMode,那就开启这个 if (TheText="只是跳转聚焦") AND (EnableOnlyClickMode=true) OnlyClick:=true } } ;# 这里的意思是说,如果发现报错,但是box选项没开启,那就干脆直接清零,防止错误 else{ TheText:="" } } ; # 在这里加上前缀 if !(prefix="") TheText:=prefix TheText ;## 如果发现对应窗口存在则激活并且填入 ifwinexist %WinTitle% { WinActivate %WinTitle% WinMaximize %WinTitle% SetTextAndClick(WinTitle,TextControlClassNN,TheText,,OnlyClick) ;# 如果注册过热键,走之前应该全消除掉 if (EnableOnlyClickMode){ Hotkey,Ctrl,jtjt,Off Hotkey,Alt,jtjt,Off } } ;## 如果发现存在,开启之后激活并且填入 Else { TrayTip,在%TheSoftName%内搜索,找不到%TheSoftName%的Class%WinTitle%`n将会先启动%TheSoftName%,,1 try { Run, %thispath% } catch { MsgBox,16,错误,没有找到路径或没有权限运行`n路径如下`n%thispath% return } WinWait,%WinTitle%,,3 if (ErrorLevel=1) { ;~ MsgBox,5 MsgBox,16,错误,路径存在,但%TheSoftName%窗口并未出现(或超时) return } WinActivate %WinTitle% WinMaximize %WinTitle% ;# 如果窗口出现 则跳转并填入 SetTextAndClick(WinTitle,TextControlClassNN,TheText,,OnlyClick) ;# 如果注册过热键,走之前应该全消除掉 if (EnableOnlyClickMode){ Hotkey,Ctrl,jtjt,Off Hotkey,Alt,jtjt,Off } Return } Return } ;--------------------------------------------------------------------------------------------------------------- ;# EnableSleep是开启延迟(为了兼容性,默认开启) ;# OnlyClick是不给Control Set文本(默认是关闭,只在特殊情况下开启) SetTextAndClick(WinTitle,TextControlClassNN,TheText,EnableSleep:=true,OnlyClick:=false){ local if (EnableSleep) Sleep 100 ;# 如果并非只是点击,那么就setText if (OnlyClick=false) ControlSetText, %TextControlClassNN% , %TheText%, %WinTitle% if (EnableSleep) Sleep 100 ControlClick , %TextControlClassNN%,%WinTitle%,, L, 1, NA return } ;--------------------------------------------------------------------------------------------------------------- /* ;# checkString函数说明书 ;## 功能介绍(默认下) 检查某字符串中是否含有某关键词(可以是多个,用|隔开即可) 如果有则return 1,没有return 0 ;# 参数介绍 ; ## CaseSensitive 默认是不区分大小写的,可以通过更改CaseSensitive改变 ; ## ReturnKey 开启之后不返回1/0 如果检查到了之后,那就返回匹配的"TheKeys",否则就返回空"" ; ## ReturnNumber 开启之后在"ReturnKey"不开启的情况下可以返回"TheKeys"匹配成功的次数(因为如果开了返回次数,传过来的内容需要全部检查) ; ## 这个函数的最大优点就是简便快捷,检查多个检查关键词的时候不需要用到数组什么的 ;--------------------------------------------------------------------------------------------------------------- ;# 版本信息 v0.5 : 修复一个低级错误,由于true和false写翻了,所以在某些状况下,会出现结果正好相反的情况 */ checkString(WaitCheck,TheKeys,ReturnNumber:=false,ReturnKey:=false,CaseSensitive:=false){ ;# 默认不检查数量(速度快) ;## 如果不检查数量的话,那么就运行这个 if (ReturnNumber!=true){ ;## 按照分隔符‘|’解析输入的"关键词" Loop,parse,TheKeys,`| { ;#循环体开始 ;## 一旦发现匹配成功 if (InStr(WaitCheck,A_LoopField,CaseSensitive,1,1)){ ;## 要求返回字符串,那么就直接返回字符串 ,如果没有要求,那就返回 true if (ReturnKey){ return %A_LoopField% } else return %true% } } ;#循环体结束 ;## 跳出循环体,只有一个可能性就是所有的TheKeys都没有匹配上,这样的话就会返回""(空字符串)或者是false ; ## 如果检查不到就反空字串 if (ReturnKey) return,% "" return %false% } ;# 检查数量 一个是返回数量 只要返回数量了,就不能再返回(匹配到的字符串) (以后可以设置为返回数组,但是今天用不到,先算了吧) else{ Loop,parse,TheKeys,`| { if(InStr(WaitCheck,A_LoopField,CaseSensitive,1,1)) ReturnNumber++ } ;# 因为如果开启这个功能的话,默认值是1,所以最后输出的时候就-1 ReturnNumber-- return ReturnNumber } } ;--------------------------------------------------------------------------------------------------------------- ;~ ;## CMD命令支持模块(静默运行) UseCMD函数 UseCMD(command){ CMDreturn:="" cmdFN:="RunAnyCtrlCMD" try{ RunWait,% ComSpec " /C " command " > ""%Temp%\" cmdFN ".log""",, Hide FileRead, CMDreturn, %A_Temp%\%cmdFN%.log FileDelete,%A_Temp%\%cmdFN%.log }catch{} return CMDreturn } ;--------------------------------------------------------------------------------------------------------------- ;# 超级复制 SuperCopy函数 SuperCopy(fast:=20,EnableTaryTip:=true,LeaveInClip:=false){ ;# 循环中Sleep为10,所以默认是20,大概是300毫秒作用,大多场景以及足够 ;# 建立Exception SuperCopyExC:=Exception("CopyFail") Sleep 50 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 if (EnableTaryTip) ;# 如果不是传统模式,就不用把旧的内容放到剪切板上 if !(LeaveInClip) Clipboard := old Sleep 15 return %show% } } ;循环结束,如果没发现就throw Exception Clipboard = %old% Sleep 35 ;~ throw Exception("CopyFail") throw SuperCopyExC return } ;## 如果没有开启快速模式,那么等待1秒钟,如果剪切板没收到才会发送错误代码 else ClipWait,1 ;防误触暂停 Sleep 50 if(ErrorLevel = 1){ ;~ TrayTip,超级复制,剪切失败,,1 Clipboard = %old% Sleep 35 ;## 没复制到,那么就抛出异常 ;~ throw Exception("CopyFail") throw SuperCopyExC return } ;防误触暂停 Sleep 15 show := Clipboard if (EnableTaryTip) TrayTip,超级复制(普通模式),剪切出的内容为:`n%show%,,1 ;# 如果不是传统模式,就不用把旧的内容放到剪切板上 if !(LeaveInClip) Clipboard := old Sleep 15 return %show% } return ;--------------------------------------------------------------------------------------------------------------- jtjt(){ SendByClip("只是跳转聚焦") Sleep 50 Send,{Enter} return } ;--------------------------------------------------------------------------------------------------------------- ;# RestoreClip的意思是,"还原剪切板",因为通过这个方法复制的时候,需要从剪贴板里走,开启这个的话,那么剪切板就还原成没操作之前的样子(应该是完全一样的,格式也不会丢失,因为用的是ClipboardAll) SendByClip(var_string,HomeOrEnd:=0,LeftOrRight:=0,RestoreClip:=true){ local ;# 如果是在SciTE中,先退出可能存在的编辑模式 if WinActive("ahk_class SciTEWindow"){ Sleep 0 Send,{Esc} } ;## 简单模式:如果是简单模式的话(就是后面两个参数根本没填) 那就干脆直接发送并return 应该能节约不少时间 if ((HomeOrEnd+LeftOrRight)=0){ SendByClip_s1(var_string,RestoreClip) return } ;# 发送Home/End ;## 只有在不为零并且不为空的情况下才可以继续进行 if (HomeOrEnd!=0) AND (HomeOrEnd!=""){ ;## 如果是1或者"Home"发送"Home" if (HomeOrEnd=1) Or (HomeOrEnd="Home") send,{Home} ;## 如果是-1或者"End"发送"End" else if (HomeOrEnd=-1) Or (HomeOrEnd="End") send,{End} } ;# Home或End是在字符串没有发送之前send的 , Left或者Right是之后 SendByClip_s1(var_string,RestoreClip) ;# 发送LeftOrRight ;## 只有在不为零并且不为空的情况下才可以继续进行 if (LeftOrRight!=0) AND (LeftOrRight!=""){ ;## 检测一下输入的字符串符合哪种格式 L_RE := RegExMatch(LeftOrRight,"L[0-9]+") R_RE := RegExMatch(LeftOrRight,"R[0-9]+") ;## 如果两种格式均不匹配,那么就返回错误 if (L_RE+R_RE=0) throw Exception ("""LeftOrRight"" Parameter Error") ;## 如果有匹配的,那么就继续进行 ;### 下面else块的作用就是搞清楚到底Left还是Right被匹配了,如果匹配成功的话,那就按次数发送 else{ ;## 计算发送次数 ;### 删除可能的L或R(根据模式) if (L_RE){ times := StrReplace(LeftOrRight,"L", "") Send,{Left %times%} } else{ times := StrReplace(LeftOrRight,"R", "") Send,{Right %times%} } } } ;# 发送LeftOrRight结束 return } ;# 把纯发送单独拿出来了 SendByClip_s1(var_string,RestoreClip){ local ;# 先把剪切板上旧的给存起来 if (RestoreClip){ ClipboardOld = %ClipboardAll% } ;把需要粘贴的赋值到剪切板,赋值后检测是否一致 。如果一致的话,那就输出;如果不一致,那么就延长时间,尝试5次 Loop,5 { Sleep 35 Clipboard := "" ;至少停顿五毫秒,如果不行,那就延长时间 if(A_Index>1) { Sleep,% (A_Index*50) } Sleep 25 Clipboard := var_string ;~ 如果发现一致,就可以跳出循环 if(Clipboard=var_string) { break } } Sleep 5 ;~ ClipWait send ^v Sleep 150 ;这个停顿可能是非常关键的,因为在有些软件里按下^v后可能还没反应过来呢,剪切板就已经变回去了,导致发送失败 ;# 然后再把旧的给还原 if (RestoreClip){ Clipboard := ClipboardOld ; Restore previous contents of clipboard. } Sleep 5 return }