[基础] AHK函数对象初窥 ① _实例2_实际可用版

Posted xrvu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[基础] AHK函数对象初窥 ① _实例2_实际可用版相关的知识,希望对你有一定的参考价值。

;# 母文章 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 FilesEverythingEverything.exe",1,"ahk_class EVERYTHING"," <"" - 笔记.itmz"">!<"".lnk""> ","Everthing"),,,,,,,true) return ;# 这是一个Word的例子,就是普通的"ExActivateAndOpen",用的最多 !^w:: ExActivateAndOpen("ahk_class OpusApp","C:Program FilesMicrosoft OfficeOffice16WINWORD.EXE") return ;--------------------------------------------------------------------------------------------------------------- ;# 用到的两个函数 ;## ExActivateAndOpen函数 ExActivateAndOpen(t,p,ex:="",option:="",UD_NoMax:="",UD_AAOWinDelay:="",WinWaitTime:="5",EnableCMD:=false,EnableFunction:=false){ global NoMax,AAOWinDelay 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:=t if ((UD_AAOWinDelay="") AND (AAOWinDelay="")) SetWinDelayMode:=false else if ((UD_AAOWinDelay="") AND (AAOWinDelay!="")) UD_AAOWinDelay:=AAOWinDelay if (SetWinDelayMode){ Old_AAOWinDelay:=A_WinDelay SetWinDelay %UD_AAOWinDelay% } if (option!=""){ 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 } } if (ExActivate(t,ex)=0) { if InStr(p,".bat"){ if (EnableCMD) UseCMD(p) else if (EnableFunction) %p%() else Run,"%p%",,min } else { if (EnableCMD) UseCMD(p) else if (EnableFunction) %p%() else Run,"%p%" } WinWait,%t%,,%WinWaitTime%,%ex% if (ErrorLevel=1){ } if ! WinActive(t,,ex){ if(A_DetectHiddenWindows="On"){ WinShow,%t%,,%ex% } WinActivate,%t%,,%ex% if (SetWinMaxMode){ if !(checkString(t,UD_NoMax)) WinMaximize,%t%,,%ex% } else WinMaximize,%t%,,%ex% } if (SetWinMaxMode){ if !(checkString(t,UD_NoMax)) WinMaximize,%t%,,%ex% } else WinMaximize,%t%,,%ex% } if (SetWinDelayMode){ SetWinDelay %Old_AAOWinDelay% } if (option!=""){ if (DHW=1) DetectHiddenWindows %OldDetectHiddenWindows% if (TMMS=1) SetTitleMatchMode %OldTitleMatchModeSpeed% if (TMM=1) SetTitleMatchMode %OldTitleMatchMode% } return ;## 到这里整个函数就结束了 } ;## 这是这个函数的最后一个代码块 ExActivate(t,ex:=""){ if WinActive(t,,ex){ WinMinimize,%t%,,%ex% return } 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 }

 


以上是关于[基础] AHK函数对象初窥 ① _实例2_实际可用版的主要内容,如果未能解决你的问题,请参考以下文章

;~ 并发运行的AutoHotkey脚本真机实际测试模板参考20191010.ahk

013_面向对象_抽象类和接口

class类和构造函数在使用new创建实例对象时候都做了什么?

Python_面向对象基础

python之路——函数迭代,生成器

OOP的魔术方法