├── .gitignore ├── template ├── name.ahk └── name.test.ahk ├── Docs ├── BeanLib_CodingStandard.md ├── pic │ ├── image-20200827113157942.png │ └── image-20200827113431662.png ├── BeanLib_ACKNOWLEDGEMENT.md ├── AHKTest.md ├── IPA_EN.md ├── getCurrentTime.md ├── _EX.md ├── Analyze().md ├── _Map.md ├── TEMPLATE.md ├── MapFactory().md ├── MouseMoveToWin().md ├── ObjLoad.md ├── getClass().md ├── RegexAllMatch().md ├── MatchIndexList().md ├── getFunc.md ├── Instanof().md ├── Timer.md ├── TextFile.md ├── Type().md ├── RandomStr().md ├── AnalyzeClassName().md ├── FileToClipboard().md ├── UseCMD.md ├── RunningSpeedTest.md ├── assert().md ├── CLASSTEMPLATE.md ├── TypeClass.md ├── AnalyzeWin().md ├── Method.md ├── _GUI.md ├── bulkMoveFile.md ├── AutoBind().md ├── _Container.md ├── BeanEnum.md ├── loadMethod().md ├── TimeChecker.md ├── rawCall.md ├── showObj().md ├── Ini.md ├── AnalyzeWin.md ├── APPLocker.md ├── Stack.md ├── throwWithSt.md ├── HIGHLIGHTING.md ├── ObjDump.md ├── 新手指南(BEGINNER_GUIDE).md ├── AutoClassify.md ├── Function.md ├── Protect().md ├── Queue.md ├── MesToast.md ├── InstanceCheck().md ├── HotStringMaps.md ├── AutoInputBox.md ├── ExcelToList().md ├── README.md ├── HotString.md ├── BeanLib_CONTRIBUTING.md ├── JsonFile.md ├── InvisibleCharacter.md ├── LogPrintln().md ├── UMSS.md ├── JSON.md ├── Script.md ├── _Wins.md ├── Switcher.md ├── Type.md ├── BeanLib_FQA.md ├── Everything.md ├── ObservableObj.md ├── PathObj.md ├── _Win.md ├── 更新历史(CHANGELOG).md ├── AccWrapper.md ├── WinEvent.md ├── StringMethod.md └── ObservableMap.md ├── cover.jpg ├── test.xlsx ├── EverthingDLL ├── Everything.dll └── Everything64.dll ├── Test ├── LibTest_PathObj.ReName().txt ├── LibTest_PathObj.ReName() │ └── file.txt ├── LibTest_TextFile.replace().txt ├── LibTest_TextFile.replace().txt.bak ├── LibTest_switcher.ahk ├── Lib.ahk ├── LibTest_PathObj.ReName()_folder.ahk ├── LibTest_PathObj.ReName().ahk ├── LibTest__Wins.ahk ├── LibTest_String.insert(insert,pos=1).ahk ├── LibTest_new PathObj().ahk ├── LibTest_replaceAll().ahk ├── LibTest_TextFile.replace().ahk ├── LibTest_AutoInputBox{}.ahk ├── LibTest_Type().ahk ├── LibTest_accDoDefaultAction().ahk ├── LibTest_InvisibleCharacter.count(aStr).ahk ├── LibTest__Acc.ahk ├── TPDD_getSourceTreeAccWrapper.ahk ├── LibTest_InvisibleCharacter.clear(aStr).ahk ├── LibTest_PathObj.ahk ├── LibTestAccWrapper.ahk ├── LibTest__Acc._Sourcetree.ahk ├── LibTest_AccWrapper.ObjectFromWindow().ahk ├── LibTest_toString().ahk └── LibTest_Stack.ahk ├── book.json ├── Core ├── getClass().ahk ├── Queue.ahk ├── _Map.ahk ├── Instanof().ahk ├── RegexAllMatch().ahk ├── AHKTest.ahk ├── RegexAllMatch().test.ahk ├── Method.ahk ├── ObservableObj.ahk ├── Analyze().ahk ├── Timer.ahk ├── _EX.ahk ├── InvisibleCharacter.ahk ├── Stack.ahk ├── Bean.ahk ├── _toString.ahk ├── ObservableMap.ahk └── PathObj.ahk ├── APP ├── IPA_EN.json ├── IPA_EN.test.ahk ├── RunningSpeedTest.ahk ├── IPA_EN.ahk ├── APPLocker.ahk ├── TimeChecker.ahk ├── AutoClassify.ahk ├── Script.ahk └── switcher.ahk ├── head.tds.ahk ├── GUI ├── BeanControl.ahk ├── AutoGUI.ahk ├── AutoInputBox.ahk ├── _GUI.ahk ├── _Wins.ahk └── WinEvent.ahk ├── Spliter.ahk ├── IO ├── TextFile.ahk ├── Example_JSON.ahk ├── Example_JsonFile.ahk ├── ExcelToList().ahk └── Ini.ahk ├── FuncObj ├── BeanEnum.ahk └── Condition.ahk ├── BeanLib.ahk ├── HotString.ahk ├── SUMMARY.md ├── Meta_Script.ahk ├── UMSS.ahk ├── Everything.ahk └── style └── website.css /.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /template/name.ahk: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Docs/BeanLib_CodingStandard.md: -------------------------------------------------------------------------------- 1 | # BeanLib 编码规范 2 | 3 | ## 伪常量 4 | 5 | -------------------------------------------------------------------------------- /cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andy-AO/BeanLib/HEAD/cover.jpg -------------------------------------------------------------------------------- /test.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andy-AO/BeanLib/HEAD/test.xlsx -------------------------------------------------------------------------------- /EverthingDLL/Everything.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andy-AO/BeanLib/HEAD/EverthingDLL/Everything.dll -------------------------------------------------------------------------------- /EverthingDLL/Everything64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andy-AO/BeanLib/HEAD/EverthingDLL/Everything64.dll -------------------------------------------------------------------------------- /Docs/pic/image-20200827113157942.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andy-AO/BeanLib/HEAD/Docs/pic/image-20200827113157942.png -------------------------------------------------------------------------------- /Docs/pic/image-20200827113431662.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Andy-AO/BeanLib/HEAD/Docs/pic/image-20200827113431662.png -------------------------------------------------------------------------------- /Test/LibTest_PathObj.ReName().txt: -------------------------------------------------------------------------------- 1 | 2 | #Warn All , StdOut 3 | #Warn ClassOverwrite , MsgBox 4 | #Warn LocalSameAsGlobal, Off 5 | -------------------------------------------------------------------------------- /Test/LibTest_PathObj.ReName()/file.txt: -------------------------------------------------------------------------------- 1 | 2 | #Warn All , StdOut 3 | #Warn ClassOverwrite , MsgBox 4 | #Warn LocalSameAsGlobal, Off 5 | -------------------------------------------------------------------------------- /Test/LibTest_TextFile.replace().txt: -------------------------------------------------------------------------------- 1 | 2 | #Warn All , StdOut 3 | #Warn ClassOverwrite , MsgBox 4 | #Warn LocalSameAsGlobal, Off 5 | -------------------------------------------------------------------------------- /Test/LibTest_TextFile.replace().txt.bak: -------------------------------------------------------------------------------- 1 | 2 | #Warn All , StdOut 3 | #Warn ClassOverwrite , MsgBox 4 | #Warn LocalSameAsGlobal, Off 5 | -------------------------------------------------------------------------------- /template/name.test.ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\ahk_lib 2 | #Include head.tds.ahk 3 | 4 | #Include %A_ScriptDir% 5 | #Include name.ahk 6 | 7 | AHKTest.eq("","") 8 | -------------------------------------------------------------------------------- /Docs/BeanLib_ACKNOWLEDGEMENT.md: -------------------------------------------------------------------------------- 1 | # 鸣谢 2 | - [GenDocs @fincs](https://github.com/yoke233/genSets) 3 | - [AHK References](https://sites.google.com/site/ahkref/) -------------------------------------------------------------------------------- /Docs/AHKTest.md: -------------------------------------------------------------------------------- 1 | # AHKTest Class 2 | 3 | 1. 性质:静态类 4 | 2. 开发目的:进行简单的单元测试,如果断言失败就会用 throwWithSt 抛出异常 5 | 6 | 断言 7 | 8 | - eq(a,b) 值相等 9 | - throw(FuncObj) 抛出异常 10 | 11 | -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "highlight", 4 | "copy-code", 5 | "comment" 6 | ], 7 | "pdf": { 8 | "paperSize": "a5" 9 | } 10 | } -------------------------------------------------------------------------------- /Docs/IPA_EN.md: -------------------------------------------------------------------------------- 1 | # IPA_EN Class 2 | 3 | 1. 性质:静态类 4 | 2. 开发目的:进入英文IPA输入状态 5 | 6 | - Hook() 开启 IPA_EN 模式 7 | 8 | - UnHook() 关闭 IPA_EN 模式 9 | 10 | - ToggleHook() 在开启和关闭之间切换 IPA_EN 模式 11 | 12 | -------------------------------------------------------------------------------- /Core/getClass().ahk: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 获取对象的 Class 4 | */ 5 | 6 | getClass(Obj){ 7 | 8 | Type.assertObj(Obj) 9 | 10 | theBase:=Obj.base 11 | if(Type.isClass(theBase)) 12 | return theBase 13 | else return false 14 | 15 | } 16 | -------------------------------------------------------------------------------- /APP/IPA_EN.json: -------------------------------------------------------------------------------- 1 | { 2 | "G": "æ", 3 | "W": "ɜ", 4 | "E": "ə", 5 | "A": "ɑ", 6 | "O": "ɔ", 7 | "B": "ɒ", 8 | "U": "ʊ", 9 | "I": "ɪ", 10 | "Z": "ð", 11 | "R": "ʒ", 12 | "S": "ʃ", 13 | ":": "ː" 14 | } 15 | -------------------------------------------------------------------------------- /Docs/getCurrentTime.md: -------------------------------------------------------------------------------- 1 | 获取用于检查时间的字符串 2 | 3 | ```autohotkey 4 | getCurrentTime() 5 | ``` 6 | 7 | ### 返回 Returns: 8 | 4位数字,主要用于判断时间 9 | 10 | 1100就表示上午11:00;1300就表示下午1:00 11 | 12 | ### 示例 Example 13 | ```autohotkey 14 | theTime:=getCurrentTime() 15 | ``` -------------------------------------------------------------------------------- /APP/IPA_EN.test.ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\ahk_lib 2 | #Include head.tds.ahk 3 | ;获取数据 4 | IPA_EN.LoadData() 5 | AHKTest.eq(IPA_EN.Data["Z"],"ð") 6 | 7 | ;hook 8 | IPA_EN.Hook() 9 | 10 | return 11 | ;unhook 12 | ^u:: 13 | IPA_EN.ToggleHook() 14 | return 15 | -------------------------------------------------------------------------------- /Docs/_EX.md: -------------------------------------------------------------------------------- 1 | # \_EX 2 | 3 | 1. 是一个**静态类**, 不提供构造器 4 | 2. 提供各种常见 Exception Message 字符串。 5 | 6 | ## 域 Field 7 | 8 | 这个域变化太快,并不需要增加其他的注解就能够明白意思,也没有实现自动化的文件生成,所以不再维护,直接查阅对应源代码中的字面量就可以。 9 | 10 | ## 方法 Method 11 | 12 | ### isRuntimeException(ex) 13 | 14 | 通过`return (ex.Message = 1)`检查是否为运行时异常 -------------------------------------------------------------------------------- /Core/Queue.ahk: -------------------------------------------------------------------------------- 1 | class Queue{ 2 | __New(){ 3 | this.items := Object() 4 | } 5 | 6 | push(item){ 7 | this.items.Insert(item) 8 | } 9 | 10 | pop(){ 11 | return this.items.Remove(1) 12 | } 13 | 14 | size(){ 15 | return (this.items.MaxIndex() ? this.items.MaxIndex() : 0) 16 | } 17 | } -------------------------------------------------------------------------------- /Docs/Analyze().md: -------------------------------------------------------------------------------- 1 | **分析对象(Object)的继承(extends)关系:** 2 | 3 | ```autohotkey 4 | Analyze(Obj) 5 | ``` 6 | 7 | ### 参数 Parameters: 8 | 9 | - Obj - 任意对象 10 | 11 | ### 返回 Returns: 12 | Object SimpleArray 13 | ### 抛出异常 Throws: 14 | - afObj() 15 | ### 示例 Example 16 | ```autohotkey 17 | Analyze(Type.AA) 18 | ``` -------------------------------------------------------------------------------- /Docs/_Map.md: -------------------------------------------------------------------------------- 1 | # _Map Class 2 | 3 | 1. 性质:静态类 4 | 2. 开发目的:用于操作Map 5 | 6 | ## 方法 Method 7 | 8 | ### merge(aFirMap,aSecMap) 9 | 10 | **合并两个Map,如果元素有重合,那么aSecMap将覆盖aFirMap** 11 | 12 | #### 参数 Parameters: 13 | 14 | - aFirMap - 第1个Map 15 | - aSecMap- 第2个Map 16 | 17 | #### 返回 Returns: 18 | 19 | Map 20 | 21 | -------------------------------------------------------------------------------- /Docs/TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **%功能介绍%:** 2 | 3 | ```autohotkey 4 | %方法头% 5 | ``` 6 | 7 | ### 参数 Parameters: 8 | 9 | - %参数% - %参数说明% 10 | 11 | ### 返回 Returns: 12 | %返回说明% 13 | ### 抛出异常 Throws: 14 | - %异常说明% 15 | ### 示例 Example 16 | ```autohotkey 17 | %示例% 18 | ``` 19 | ### 测试 Test 20 | 21 | LibTest_AccWrapper.ObjectFromWindow().ahk -------------------------------------------------------------------------------- /Core/_Map.ahk: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 说明:Map的工具静态类 4 | */ 5 | 6 | class _Map{ 7 | /*! 8 | 合并两个Map,如果元素有重合,那么aSecMap将覆盖aFirMap 9 | */ 10 | merge(aFirMap,aSecMap){ 11 | result := Object() 12 | for i,v in aFirMap { 13 | result[i]:=v 14 | } 15 | for i,v in aSecMap { 16 | result[i]:=v 17 | } 18 | return result 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Docs/MapFactory().md: -------------------------------------------------------------------------------- 1 | **用于进行有关类型的测试:** 2 | 3 | ```autohotkey 4 | MapFactory(aMap,aKeyFunc:="",aValueFunc:="") 5 | ``` 6 | ### 参数 Parameters: 7 | aMap是需要测试的Map,aKeyFunc/aValueFunc是操作 8 | 9 | ### 返回 Returns: 10 | 返回aKeyFunc/aValueFunc两个函数返回值的拼接字符串 11 | 12 | ### 抛出异常 Throws: 13 | - Type.assertObj(aKeyFunc),Type.assertObj(aValueFunc) 14 | -------------------------------------------------------------------------------- /Docs/MouseMoveToWin().md: -------------------------------------------------------------------------------- 1 | **%功能介绍%:**依据偏移量,确定相对窗口坐标,并移动鼠标 2 | 3 | ```autohotkey 4 | 5 | MouseMoveToWin(winTitle) 6 | ``` 7 | 8 | ### 参数 Parameters: 9 | 10 | - winTitle 11 | 12 | ### 返回 Returns: 13 | null 14 | ### 抛出异常 Throws: 15 | - null 16 | ### 示例 Example 17 | ```autohotkey 18 | MouseMoveToWin(MyiFlyVoice.theWinTitle) 19 | ``` 20 | -------------------------------------------------------------------------------- /Docs/ObjLoad.md: -------------------------------------------------------------------------------- 1 | **读取被序列化的对象:** 2 | 3 | ```autohotkey 4 | 从内存(变量)读取对象 5 | Obj := ObjLoad(Address) 6 | 从硬盘(文件)读取对象 7 | Obj := ObjLoad(FilePath) 8 | ``` 9 | 10 | ### 返回 Returns: 11 | 被序列化的对象 12 | ### 示例 Example 13 | ```autohotkey 14 | 同ObjDump() 15 | ``` 16 | 17 | From: 18 | 19 | -------------------------------------------------------------------------------- /Docs/getClass().md: -------------------------------------------------------------------------------- 1 | **获取对象的 Class:** 2 | 3 | ```autohotkey 4 | getClass(Obj) 5 | ``` 6 | 7 | ### 参数 Parameters: 8 | 9 | - Obj - 对象 10 | 11 | ### 返回 Returns: 12 | 13 | 返回对象的 Class 14 | 15 | 如果对象没有继承自 Class,则返回Boolean 16 | ### 抛出异常 Throws: 17 | - Type.assertObj(Obj) 18 | ### 示例 Example 19 | ```autohotkey 20 | getClass(type.BB) 21 | ``` -------------------------------------------------------------------------------- /Docs/RegexAllMatch().md: -------------------------------------------------------------------------------- 1 | ```autohotkey 2 | RegexAllMatch(String,NeedleRegEx) 3 | ``` 4 | 5 | 返回所有正则表达式匹配对象。 6 | 7 | 要注意的是需要在选项中开启`O`,否则是获取不到匹配对象的! 8 | 9 | ### 参数 Parameters: 10 | 11 | - Haystack - 被匹配的字符串 12 | - NeedleRegEx - 匹配所用的模式 13 | 14 | ### 返回 Returns: 15 | 返回正则表达式匹配对象数组,如果没有匹配成功,则返回空数组 16 | ### 抛出异常 Throws: 17 | - 如果没有在最前面的选项中发现`O`,会直接抛出异常 18 | 19 | -------------------------------------------------------------------------------- /Docs/MatchIndexList().md: -------------------------------------------------------------------------------- 1 | **检查数组中的每个元素,返回符合正则的 Index:** 2 | 3 | ```autohotkey 4 | Match(list,aRegEx) 5 | ``` 6 | 7 | ### 参数 Parameters: 8 | 9 | - list - 待检查数组 10 | - aRegEx - 正则 11 | 12 | ### 返回 Returns: 13 | 由每一个符合正则的元素 index 组成的 list 14 | ### 抛出异常 Throws: 15 | ### 示例 Example 16 | ```autohotkey 17 | indexList:=_List.Match(ListTilteAndPageNumber,"[0-9]+") 18 | ``` -------------------------------------------------------------------------------- /Docs/getFunc.md: -------------------------------------------------------------------------------- 1 | **如果扑空会抛出异常的 FuncObj 获取器:** 2 | 3 | ```autohotkey 4 | getFunc(aFuncName) 5 | ``` 6 | 7 | ### 参数 Parameters: 8 | 9 | - aFuncName - 函数名 10 | 11 | ### 返回 Returns: 12 | %返回说明% 13 | ### 抛出异常 Throws: 14 | - Exception(_Ex.NoExistFunctionName) 15 | ### 示例 Example 16 | ```autohotkey 17 | funcObj := getFunc("Println") 18 | 19 | %funcObj%("Hello") 20 | 21 | ``` -------------------------------------------------------------------------------- /Core/Instanof().ahk: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 主要用来核对继承关系 4 | */ 5 | 6 | Instanof(Obj,Super){ 7 | theList:="" 8 | if(Not(IsObject(Obj))) 9 | return false 10 | if (Type.isStr(Super)){ 11 | theList:=AnalyzeClassName(Obj) 12 | return _Container.Contains(theList,Super) 13 | } 14 | else { 15 | theList:=Analyze(Obj) 16 | return _Container.Contains(theList,Super) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Docs/Instanof().md: -------------------------------------------------------------------------------- 1 | **指出对象是否是特定类的一个实例:** 2 | 3 | ```autohotkey 4 | Instanof(Obj,Super) 5 | ``` 6 | 7 | ### 参数 Parameters: 8 | 9 | - Obj - 对象 10 | - Super - 类 :可以接受任何类型,如果是字符串,那么就检查类名 11 | 12 | ### 返回 Returns: 13 | Boolean 14 | ### 抛出异常 Throws: 15 | - null 16 | ### 示例 Example 17 | ```autohotkey 18 | re:=Instanof(type.AA,type.CC) 19 | re:=Instanof(type.BB,"Type.DD") 20 | ``` -------------------------------------------------------------------------------- /Docs/Timer.md: -------------------------------------------------------------------------------- 1 | # Timer Class 2 | 3 | 1. 性质:/实例类 4 | 2. 开发目的: 5 | 6 | 已经有了SetTimer()方法,没办法对计时器进行精确管理;有了精确管理的需求之后,准备做一个类。 7 | 8 | 9 | ## 方法 Methods 10 | ### set() 11 | 开始计时 12 | ### off() 13 | 暂停计时 14 | ### on() 15 | 重启计时 16 | ### delete() 17 | 删除计时器 18 | ### __New(aFunc,aPeriod := "250",isSingle:=false) 19 | - aFunc:需要定时运行的函数对象 20 | - aPeriod:计时器运行周期 21 | 22 | - isSingle: 只执行一次 23 | -------------------------------------------------------------------------------- /Docs/TextFile.md: -------------------------------------------------------------------------------- 1 | # TextFile Class 2 | 3 | 1. 性质:实例类 4 | 2. 开发目的:用于操作文本文件 5 | 6 | 默认编码为`UTF-8` 7 | 8 | ## 域 Fields 9 | 10 | Encoding := "UTF-8" 11 | 12 | ## 方法 Methods 13 | 14 | ### __New(aPathObj) 15 | 16 | - aPathObj - 被操作对象的Path对象 17 | 18 | ### get() 19 | 20 | 获取文本 21 | 22 | ### Set(aText) 23 | 24 | 写入文本 25 | 26 | ### replace(SearchText,ReplaceText, Limit := -1) 27 | 28 | 替换文本 -------------------------------------------------------------------------------- /Docs/Type().md: -------------------------------------------------------------------------------- 1 | **获取值的具体类型:** 2 | 3 | - 这个函数在AHK2中有,AHK_L还没有,所以自己写了一个。 4 | 5 | 6 | ```autohotkey 7 | Type(Everthing) 8 | ``` 9 | 10 | ### 参数 Parameters: 11 | 12 | - Everthing - 任意值 13 | 14 | ### 返回 Returns: 15 | String 16 | 17 | - 返回一个正整数,具体值请看 `Type Class` 的常量,里面定义了这些正整数 18 | 19 | ### 抛出异常 Throws: 20 | - null 21 | ### 示例 Example 22 | ```autohotkey 23 | Type("Everthing") 24 | ``` -------------------------------------------------------------------------------- /Docs/RandomStr().md: -------------------------------------------------------------------------------- 1 | **生成随机字符串** 2 | 3 | ```autohotkey 4 | RandomStr(aLength = 16, aLowestAsc = 48, aHighestAsc = 122) 5 | ``` 6 | 7 | ### 参数 Parameters 8 | 9 | - aLength - 随机数长度 10 | - aLowestAsc - Asc值下限 11 | - aHighestAsc - Asc值上限 12 | 13 | ### 返回 Returns 14 | 15 | 随机字符串 16 | 17 | ### 抛出异常 Throws 18 | - 无 19 | ### 示例 Example 20 | ```autohotkey 21 | MsgBox, % RandomStr() 22 | MsgBox, % RegExReplace(RandomStr(), "\W", "i") ; only alphanum. 23 | ``` -------------------------------------------------------------------------------- /Docs/AnalyzeClassName().md: -------------------------------------------------------------------------------- 1 | **分析对象(Object)的继承(extends)关系:** 2 | 3 | - 和 `Analyze()` 的区别主要在于,前者是返回`Base`对象本身,后者则是返回其 `.__Class` 属性,也就是类名,如果没有类名,则返回字符串`"Not Class"`。 4 | 5 | ```autohotkey 6 | AnalyzeClassName(Obj) 7 | ``` 8 | 9 | ### 参数 Parameters: 10 | 11 | - Obj - 任意对象 12 | 13 | ### 返回 Returns: 14 | 15 | StrList 16 | 17 | ### 抛出异常 Throws: 18 | 19 | - afObj() 20 | 21 | ### 示例 Example 22 | 23 | ```autohotkey 24 | AnalyzeClassName(Type.AA) 25 | ``` -------------------------------------------------------------------------------- /Docs/FileToClipboard().md: -------------------------------------------------------------------------------- 1 | **FileToClipboard:** 将指定文件复制到剪切板 2 | 3 | 不知道为什么,这个函数在我这里经常会失效,并不稳定 4 | 5 | ```autohotkey 6 | FileToClipboard(PathToCopy) 7 | ``` 8 | 9 | ### 参数 Parameters: 10 | 11 | - PathToCopy -路径 12 | 13 | ### 返回 Returns: 14 | null 15 | ### 抛出异常 Throws: 16 | - null 17 | ### 示例 Example 18 | 19 | From:[how to copy a file to the clipboard - Ask for Help - AutoHotkey Community](https://autohotkey.com/board/topic/23162-how-to-copy-a-file-to-the-clipboard/) 20 | 21 | -------------------------------------------------------------------------------- /Docs/UseCMD.md: -------------------------------------------------------------------------------- 1 | **静默执行WindowsCMD命令行** 2 | 3 | ```autohotkey 4 | UseCMD(command) 5 | ``` 6 | 7 | ### 参数 Parameters: 8 | 9 | - command - 命令字符串 10 | 11 | ### 返回 Returns: 12 | 可以读取并返回信息 13 | ### 抛出异常 Throws: 14 | 无 15 | 16 | ### 示例 Example 17 | ```autohotkey 18 | AndroidApiSearch= 19 | ( 20 | start "" %360chromePath% "https://www.google.com/search?gws_rd=cr&gl=us&q=%SearchKey%`%20site:developer.android.com" 21 | exit 22 | ) 23 | 24 | UseCMD(AndroidApiSearch) 25 | ``` -------------------------------------------------------------------------------- /Core/RegexAllMatch().ahk: -------------------------------------------------------------------------------- 1 | 2 | 3 | RegexAllMatch(Haystack,NeedleRegEx){ 4 | if(RegExMatch(NeedleRegEx,"^[``A-Za-z]*O[``A-Za-z]*\)")){ 5 | TheMatchObjArray := [] 6 | StartPos := 1 7 | while(FoundPos := RegExMatch(Haystack, NeedleRegEx,TheMatchObj,StartPos)) { 8 | StartPos := FoundPos + StrLen(TheMatchObj.Value(0)) 9 | TheMatchObjArray.Push(TheMatchObj) 10 | } 11 | return TheMatchObjArray 12 | } 13 | else 14 | throwWithSt("The O option was not found in " NeedleRegEx) 15 | } 16 | -------------------------------------------------------------------------------- /Core/AHKTest.ahk: -------------------------------------------------------------------------------- 1 | 2 | ;用来进行极其简单的单元测试,可用于TDD或TDS,如果发现断言失败,就会抛出异常,弹出MsgBox提醒 3 | Class AHKTest{ 4 | ;断言两个值相等 5 | eq(a,b){ 6 | if(a!=b){ 7 | throwWithSt("⚠test failed⚠:" toString(a) " != " toString(b)) 8 | } 9 | } 10 | ;断言会抛出异常(堆栈跟踪信息去不掉) 11 | throw(FuncObj){ 12 | HadException:=false 13 | try { 14 | FuncObj.Call() 15 | } catch e { 16 | HadException:=true 17 | } 18 | if(NOT HadException){ 19 | throwWithSt("⚠test failed⚠:No exceptions were thrown.") 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Docs/RunningSpeedTest.md: -------------------------------------------------------------------------------- 1 | # RunningSpeedTest Class 2 | 3 | 1. 性质:实例类 4 | 2. 开发目的:高精度计时 5 | 6 | ## 域 Field 7 | 8 | freq 9 | 10 | CounterBefore 11 | 12 | ## 方法 Method 13 | 14 | Start() 15 | 16 | End() - 返回 `Start()到End()` 的时间差,单位是毫秒 17 | 18 | ## 示例 19 | 20 | ```autohotkey 21 | Obj := new RunningSpeedTest() 22 | Obj.Start() 23 | Sleep 1000 24 | LogPrintln(Obj.End(),A_LineFile "(" A_LineNumber ")" " : " "Obj.End() >>> `r`n") 25 | return 26 | ``` 27 | 28 | From:https://wyagd001.github.io/zh-cn/docs/commands/DllCall.htm#QPC -------------------------------------------------------------------------------- /head.tds.ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 21 | 22 | ExitAppForHotKeyAltQ(){ 23 | ExitApp 24 | return 25 | } 26 | 27 | Hotkey, !q , ExitAppForHotKeyAltQ 28 | -------------------------------------------------------------------------------- /Docs/assert().md: -------------------------------------------------------------------------------- 1 | **断言:** 2 | 3 | - 当表达式值为 `false` 时触发throw,断言可以让程序更壮硕,更能够接受异常数据。 4 | 5 | ```autohotkey 6 | assert(Boolean,Mes:="No Info") 7 | ``` 8 | 9 | ### 参数 Parameters: 10 | 11 | - Boolean - 表达式(布尔值) 12 | - Mes - throw 时,附加的信息 13 | 14 | ### 返回 Returns: 15 | `Boolean` 16 | 17 | ### 抛出异常 Throws: 18 | - ```autohotkey 19 | ExMes:=_EX.assertfirm . " Mes : " . Mes 20 | throwWithSt(ExMes) 21 | ``` 22 | ### 示例 Example 23 | ```autohotkey 24 | Str:="MyString" 25 | assert(Str!="") ;断言被触发 26 | 27 | Str:=assert 28 | af(Str!="") ;断言不被触发,返回 true 29 | ``` -------------------------------------------------------------------------------- /Docs/CLASSTEMPLATE.md: -------------------------------------------------------------------------------- 1 | # ??? Class 2 | 3 | 1. 性质:静态类/单例类/实例类 4 | 2. 开发目的: 5 | 6 | ## 域 Fields 7 | 8 | ## 示例 Examples 9 | ```AutoHotKey 10 | inputBox:=new AutoInputBox(aTitle,aPrompt) 11 | 12 | inputBox.SetDeFaultText("Func") 13 | 14 | inputBox.SetAlwaysOnTop(true) 15 | 16 | userInput := inputBox.start() 17 | ``` 18 | 19 | ## 方法 Methods 20 | 21 | ### ?方法头?(?) 22 | 23 | **?描述?** 24 | 25 | #### 参数 Parameters 26 | 27 | - ?- ? 28 | 29 | #### 返回 Returns 30 | 31 | ?返回值类型? 32 | 33 | #### 抛出异常 Throws 34 | 35 | - ?异常类型? 36 | 37 | #### 测试 Test 38 | 39 | LibTest_AccWrapper.ObjectFromWindow().ahk -------------------------------------------------------------------------------- /GUI/BeanControl.ahk: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | 说明:Control对象 5 | */ 6 | class BeanControl{ 7 | win:="",classNN:="" 8 | ;---------------------------------------------------------------------- 9 | __New(aWin,aClassNN){ 10 | this.win := aWin 11 | this.classNN := aClassNN 12 | return this 13 | } 14 | ;---------------------------------------------------------------------- 15 | setText(aNewText){ 16 | ControlSetText , % this.classNN, %aNewText%, % this.win.title 17 | return aNewText 18 | } 19 | ;---------------------------------------------------------------------- 20 | 21 | } ;---------class BeanControl End -------------------------------------------------------------------------------- /Docs/TypeClass.md: -------------------------------------------------------------------------------- 1 | # TypeClass Class 2 | 3 | 1. 性质:实例类 4 | 2. 开发目的:提供与Type有关的测试对象 5 | 6 | ## 域 Fields 7 | 8 | ```AutoHotKey 9 | Class TypeClass{ 10 | static staticPath := "D:\AHKs\ahk_lib\Test\LibTest_toString().ahk" 11 | ComObj := AccWrapper.ObjectFromPoint(vChildId).get() 12 | Obj := Object() 13 | Class := AutoInputBox 14 | FuncObj := new Function("toString") 15 | Exception := Exception(_Ex.IndexOutOfBounds) 16 | Path := Str := TypeClass.staticPath 17 | NS := "" 18 | Number := "123456789" 19 | Boolean := false 20 | FileObj := FileOpen(TypeClass.staticPath,"r") 21 | } 22 | 23 | TypeClassInstance := new TypeClass() 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /Docs/AnalyzeWin().md: -------------------------------------------------------------------------------- 1 | **获取窗口参数,可用于窗口操作和调试:** 2 | 3 | ```autohotkey 4 | AnalyzeWin(InputWinTitle,EnableWinText:=false) 5 | ``` 6 | 7 | ### 参数 Parameters: 8 | 9 | - InputWinTitle - 目标窗口的 `WinTitle` 10 | - EnableWinText - 是否检测 `WinText` 11 | 12 | ### 返回 Returns: 13 | Obj 或者 false 14 | 15 | - 如果窗口不存在,那么就返回 `false` 16 | 17 | - 包含以下 Key 18 | 19 | ```autohotkey 20 | WinTitle := "WinTitle: " WinTitle 21 | WinClass := "ahk_class " WinClass 22 | Winexe := "ahk_exe " Winexe 23 | WinPId := "ahk_id " WinId 24 | WinPath := "WinPath: " WinPath 25 | ``` 26 | 27 | ### 抛出异常 Throws: 28 | 29 | - null 30 | ### 示例 Example 31 | ```autohotkey 32 | Obj:=AnalyzeWin(WinTitle) 33 | ``` -------------------------------------------------------------------------------- /Spliter.ahk: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 说明:字符串分割器 4 | */ 5 | 6 | class Spliter{ 7 | text:="",delimiters:="" 8 | 9 | elementTrim:=" `t" 10 | deleteBlankelement:=true 11 | ;---------------------------------------------------------------------- 12 | __New(text,delimiters){ 13 | this.text := text 14 | this.delimiters := delimiters 15 | return this 16 | } 17 | ;---------------------------------------------------------------------- 18 | split(){ 19 | theList:= StrSplit(this.text , this.delimiters,this.elementTrim) 20 | newList:=[] 21 | for i,v in theList { 22 | if(v!="") 23 | newList.Push(v) 24 | } 25 | return newList 26 | } 27 | } 28 | ;--------class Spliter End -------------------------------------------------------------------------------- /Core/RegexAllMatch().test.ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\ahk_lib 2 | #Include head.tds.ahk 3 | 4 | #Include %A_ScriptDir% 5 | #Include RegexAllMatch().ahk 6 | 7 | /* 8 | 返回匹配对象数组 9 | */ 10 | 11 | MatchObjectArray := RegexAllMatch(Haystack:="ABC`r`nDEF`r`n", NeedleRegEx:="Om)^(\w)(\w)") 12 | AHKTest.eq(MatchObjectArray[1].Value(0),"AB") 13 | AHKTest.eq(MatchObjectArray[2].Value(0),"DE") 14 | 15 | /* 16 | 如果没有匹配到,那么返回空数组 17 | */ 18 | AHKTest.eq(RegexAllMatch(Haystack:="123", NeedleRegEx:="Om)^abc").Length(),0) 19 | 20 | 21 | /* 22 | 如果没有O选项,会抛出异常 23 | */ 24 | funcobj_1(){ 25 | RegexAllMatch(Haystack:="123", NeedleRegEx:="m).") 26 | } 27 | AHKTest.throw(Func("funcobj_1")) 28 | 29 | 30 | -------------------------------------------------------------------------------- /Docs/Method.md: -------------------------------------------------------------------------------- 1 | # Method Class 2 | 3 | 1. 性质:符合 FunObj 的实例类,并含有 static Function 4 | 2. 开发目的:主要用于从类中提取可用的 Func 对象 5 | 6 | 在AHK中并没有「实例方法」这种概念,如果从 Class 中直接抽取方法,那么带有 this 参数,使用起来有诸多不便。 7 | 8 | 最简单的方法是对 FuncObj 使用 bind,但是 bind 对象内部完全是不可见的,就为调试带来了诸多麻烦,Method 方法就是为了解决这一问题而生的,它的内部通透性非常好。 9 | 10 | 通过 __New 方法的最后一个可变参数,提供Bind()功能。 11 | 12 | ## 关于绑定 13 | 14 | 对象没有.bind()方法,在new的参数列表中直接绑定即可. 15 | 16 | ## 静态方法 Static Method 17 | 18 | ### for(Func) 19 | 20 | 用于事实上不需要 this 参数的实例方法 21 | 22 | - FuncObj - 需要被封装的实例方法 23 | 24 | ## 方法 Method 25 | 26 | ### __New(aFunc,aFuncThis,aBindParas*) 27 | 28 | 用于带有 this 参数的实例方法 29 | 30 | - aFunc - 需要被封装的实例方法 31 | - aFuncThis - aFunc 的 this 参数 32 | - aBindParas - 需要绑定的参数 -------------------------------------------------------------------------------- /Docs/_GUI.md: -------------------------------------------------------------------------------- 1 | # _GUI Class 2 | 3 | 1. 性质:静态类 4 | 5 | ## 子类 Subclass 6 | 7 | ### c 8 | 9 | 用于包装GUI的SubCommand 10 | 11 | #### 示例 12 | 13 | ```AutoHotKey 14 | winHwnd = 0xc12fc 15 | 16 | Gui,% _Gui.c.show(winHwnd) 17 | 18 | ``` 19 | 20 | ### t 21 | 22 | 用于包装GUI的WinTitle 23 | 24 | #### 示例 25 | 26 | ```AutoHotKey 27 | winHwnd = 0xc12fc 28 | 29 | WinActive(_Gui.t.ahk_id(winHwnd)) 30 | ``` 31 | 32 | ## 方法 Methods 33 | 34 | ### AddAnimatedGIF(imagefullpath , x="", y="", w="", h="", guiname = "1") 35 | 36 | **为GUI添加GIF动图** 37 | 38 | #### 参数 Parameters 39 | 40 | - ?- ? 41 | 42 | #### 返回 Returns 43 | 44 | ? 45 | 46 | #### 抛出异常 Throws 47 | 48 | - ? 49 | 50 | #### 测试 Test 51 | 52 | 无 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /APP/RunningSpeedTest.ahk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | class RunningSpeedTest{ 5 | freq := DllCall("QueryPerformanceFrequency", "Int64*", freq) 6 | ;------------------------------ 7 | __New(){ 8 | return this 9 | } 10 | ;------------------------------ 11 | Start(){ 12 | DllCall("QueryPerformanceCounter", "Int64*", CounterBefore) 13 | this.CounterBefore := CounterBefore 14 | return 15 | } 16 | ;------------------------------ 17 | End(){ 18 | DllCall("QueryPerformanceCounter", "Int64*", CounterAfter) 19 | result := ((CounterAfter - this.CounterBefore) / (this.freq * 1000)) 20 | this.CounterBefore := "" 21 | return result 22 | } 23 | } 24 | ;~ From:https://wyagd001.github.io/zh-cn/docs/commands/DllCall.htm#QPC 25 | -------------------------------------------------------------------------------- /Docs/bulkMoveFile.md: -------------------------------------------------------------------------------- 1 | **批量移动文件:** 2 | 3 | ```autohotkey 4 | bulkMoveFile(aPathList,DestPattern) 5 | ``` 6 | 7 | ### 参数 Parameters: 8 | 9 | - aPathList - 文件路径数组 10 | 11 | 不支持文件夹 12 | 13 | - DestPattern - 目标路径 14 | 15 | ### 返回 Returns: 16 | - aPathList.length() 17 | 18 | ### 抛出异常 Throws: 19 | - _EX.MoveFailed 20 | ### 示例 Example 21 | ```autohotkey 22 | ;把桌面上所有的pdf文件移动到相应的文件夹中 23 | Obj:=new Everything() 24 | 25 | thekey="D:\MyDesktop\" .PDF 26 | Obj.Setkey(thekey) 27 | Obj.Search() 28 | 29 | searchResultList:=Obj.getSearchResultList() 30 | DeBugDeepPrintln(searchResultList,"searchResultList >>> ") 31 | 32 | 33 | DestPattern:="D:\MyDesktop\A\" 34 | 35 | bulkMoveFile(searchResultList,DestPattern) 36 | ``` -------------------------------------------------------------------------------- /Docs/AutoBind().md: -------------------------------------------------------------------------------- 1 | **自动为Func绑定参数:** 2 | 3 | ```autohotkey 4 | AutoBind(aFunc,aParaList,aFirstPara:="") 5 | ``` 6 | 7 | ### 参数 Parameters: 8 | 9 | - aFunc 10 | - aParaList 11 | - 如果绑定的 Func 从属于某一个对象,则需要需要传入 `this` 参数,这个就是为这种情况准备的。 12 | 13 | ### 返回 Returns: 14 | - BoundFuncObj 15 | 16 | BoundFuncObj 本身只有 `call()`方法,不能再次绑定参数了。 17 | 18 | ### 抛出异常 Throws: 19 | - TooManyParas 20 | - TooFewParas 21 | - afObj 22 | ### 示例 Example 23 | ```autohotkey 24 | 25 | class myClass{ 26 | println(Mes){ 27 | println(Mes) 28 | LogPrintln(Mes,"Mes >>>") 29 | return 30 | } 31 | } 32 | 33 | aFunc:=myClass.println 34 | 35 | aParaList:=[myClass,"HellWorld"] 36 | 37 | resultObj:=AutoBind(aFunc,aParaList) 38 | resultObj.Call() 39 | ``` -------------------------------------------------------------------------------- /Docs/_Container.md: -------------------------------------------------------------------------------- 1 | # \_Container Class 2 | 3 | 1. **静态类** 4 | 2. 主要包含对于容器(List和Map的统称)各种增强操作 5 | 4. 提供一些测试用对象 6 | 4. **还有大量的方法没有被写成文档**,其中有一些很难复用,需要特殊处理。 7 | 8 | ## 域 Field 9 | 10 | - static LetterAndNumberMap := Object("A","1","B","2","C","3","D","4","E","5","F","6","G","7","H","8","I","9","J","0") 11 | 12 | ## 方法 13 | 14 | ### Contains(ListorMap,value) 15 | 16 | **检查容器内是否包含某值:** 17 | 18 | 19 | #### 参数 Parameters: 20 | 21 | - ListorMap - 容器 22 | - value - 任意类型值 23 | 24 | #### 返回 Returns: 25 | Boolean 26 | #### 抛出异常 Throws: 27 | - null 28 | #### 示例 Example 29 | ```autohotkey 30 | Result1:=_Container.Contains(_List.LetterList,"A") 31 | ;true 32 | Result2:=_Container.Contains(_List.LetterList,"0") 33 | ;false 34 | ``` 35 | -------------------------------------------------------------------------------- /Docs/BeanEnum.md: -------------------------------------------------------------------------------- 1 | # BeanEnum Class 2 | 3 | 1. 性质:实例类 4 | 2. 开发目的:用于自定义元函数_NewEnum 5 | 6 | ## 方法 Method 7 | 8 | ### __New(aMap) 9 | 10 | **创建一个自定义的_NewEnum枚举器** 11 | 12 | #### 参数 Parameters: 13 | 14 | - aMap - 需要被枚举返回的Map 15 | 16 | #### 返回 Returns: 17 | 18 | _NewEnum 19 | 20 | #### 示例 Example 21 | 22 | 适用于一切与自定义枚举相关的内容,最常见的就是对枚举操作隐藏某些数据域。 23 | 24 | 在 Method Class 的设计中,有域 FuncThis,但是当 Method 实例被放入 aFuncThi s本身时,会因为枚举原因造成死循环,所以通过自定义枚举器,让枚举器不返回域 FuncThis,从而解决了这一问题。 25 | 26 | ```autohotkey 27 | class Method{ 28 | func := Object() 29 | funcThis := Object() 30 | bindParas := Object() 31 | 32 | ...... 33 | 34 | _NewEnum(){ 35 | return new BeanEnum(Object("func",this.func,"bindParas",this.bindParas)) 36 | } 37 | } ;---------class Method End 38 | 39 | ``` 40 | 41 | -------------------------------------------------------------------------------- /Docs/loadMethod().md: -------------------------------------------------------------------------------- 1 | **在对象中生成 Method 数组:** 2 | 3 | - 把该对象 base 中的所有 FuncObj 与 当前 this 作为参数生成 Method,并且形成 MethodMap 写入当前对象。 4 | - 默认不生成Meta方法。 5 | - 主要用于函数式编程中传递方法。 6 | 7 | ```autohotkey 8 | loadMethod(this) 9 | ``` 10 | 11 | ### 参数 Parameters: 12 | 13 | - this - 方法的this参数 14 | 15 | ### 返回 Returns: 16 | null 17 | ### 抛出异常 Throws: 18 | - null 19 | ### 示例 Example 20 | ```autohotkey 21 | class Test{ 22 | mes := "Test!" 23 | __New(){ 24 | loadMethod(this) 25 | return this 26 | } 27 | A(){ 28 | LogPrintln(this.mes,"this.mes >>>") 29 | } 30 | } 31 | 32 | theObj := new Test() 33 | theObj.Method.A() 34 | theAct:=theObj.Method.A 35 | %theAct%() 36 | 37 | ``` 38 | 39 | ```autohotkey 40 | "InitFunc运行中" >>>InitFunc运行中 41 | this.mes >>>Test! 42 | this.mes >>>Test! 43 | ``` -------------------------------------------------------------------------------- /Core/Method.ahk: -------------------------------------------------------------------------------- 1 | class Method{ 2 | func := Object() 3 | funcThis := Object() 4 | bindParas := Object() 5 | ;------------------------------ 6 | for(obj){ 7 | Type.assertObj(Obj) 8 | return new Method(Obj,Obj) 9 | } 10 | ;------------------------------ 11 | __New(aFunc,aFuncThis,aBindParas*){ 12 | this.func := aFunc 13 | this.funcThis := aFuncThis 14 | this.bindParas := aBindParas 15 | return this 16 | } 17 | ;------------------------------ 18 | call(aCallParas*){ 19 | paras := _List.merge(this.bindParas,aCallParas) 20 | return SmartCallForFunction(this.func,this.funcThis,paras*) 21 | } 22 | ;------------------------------ 23 | _NewEnum(){ 24 | return new BeanEnum(Object("func",this.func,"bindParas",this.bindParas)) 25 | } 26 | } ;---------class Method End 27 | -------------------------------------------------------------------------------- /APP/IPA_EN.ahk: -------------------------------------------------------------------------------- 1 | class IPA_EN{ 2 | static config_path := "D:\AHKs\ahk_lib\APP\IPA_EN.json" 3 | static Data := "" 4 | static Hooked := false 5 | LoadData(){ 6 | this.Data := new JsonFile(this.config_path).load() 7 | } 8 | ToggleHook(){ 9 | if(this.Hooked){ 10 | this.UnHook() 11 | } 12 | else{ 13 | this.Hook() 14 | } 15 | } 16 | Hook(){ 17 | if(Not this.Hooked){ 18 | if(this.Data == ""){ 19 | this.LoadData() 20 | } 21 | this.Hooked := true 22 | for Key,NewKey in this.Data { 23 | TheFuncObj:=func("SendText").bind(NewKey) 24 | Hotkey,+%Key%,%TheFuncObj%,On 25 | } 26 | } 27 | } 28 | 29 | UnHook(){ 30 | if(this.Hooked){ 31 | this.Hooked := false 32 | for Key,NewKey in this.Data { 33 | Hotkey,+%Key%,Off 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Core/ObservableObj.ahk: -------------------------------------------------------------------------------- 1 | 2 | class ObservableObj{ 3 | listenerList := [] 4 | ;------------------------------ 5 | __New(aObj){ 6 | this.Obj := aObj 7 | return this 8 | } 9 | ;------------------------------ 10 | get(){ 11 | return this.obj 12 | } 13 | ;------------------------------ 14 | set(aObj){ 15 | if(this.Obj != aObj){ 16 | this.Obj := aObj 17 | this.callListener(this, this.Obj, aObj) 18 | } 19 | return aObj 20 | } 21 | ;------------------------------ 22 | addListener(aMethod){ 23 | this.listenerList.push(aMethod) 24 | return 25 | } 26 | ;------------------------------ 27 | callListener(observableObj, oldChange, newChange){ 28 | for i,v in this.listenerList { 29 | v.call(observableObj, oldChange, newChange) 30 | } 31 | return 32 | } 33 | } ;---------class ObservableObj End -------------------------------------------------------------------------------- /Docs/TimeChecker.md: -------------------------------------------------------------------------------- 1 | # TimeChecker Class 2 | 3 | 1. 性质:实例类 4 | 2. 开发目的:检查当前时间是否位于规定范围内。 5 | 比如,黑名单设为[1100,1200],那么在这个时间段内调用都会返回 `flase`,反之则会返回`true`。 6 | 另外,还有类似的白名单机制。 7 | 8 | ## 域 Field 9 | 10 | **以下是存放黑白名单的两个数组,为了检查类型,使用属性实现** 11 | 12 | BlackList 13 | 14 | WhiteList 15 | 16 | ## 方法 Method 17 | 18 | **分别是采用黑、白名单检查当前时间** 19 | 20 | CheckByBlackList() 21 | 22 | CheckByWhiteList() 23 | 24 | ## 示例 25 | 26 | APPLock中的时间检查,已经通过`TimeChecker `实现。 27 | 28 | ```autohotkey 29 | TheTimeChecker := new TimeChecker() 30 | TheTimeChecker.WhiteList := [1255,1300] ;命中的时候应该启用 1 31 | WhiteListResult := TheTimeChecker.CheckByWhiteList() 32 | TheTimeChecker := new TimeChecker() 33 | TheTimeChecker.BlackList := [1222,1600] ;命中的时候应该禁用 0 34 | BlackListResult := TheTimeChecker.CheckByBlackList() 35 | ``` 36 | 37 | 38 | -------------------------------------------------------------------------------- /Docs/rawCall.md: -------------------------------------------------------------------------------- 1 | **绕过_Call()元函数调用Method:** 2 | 3 | 因为AHK的OOP设计问题,方法并不会加载到对象中。 4 | 5 | 在元编程的过程中,如果使用了 __Call() ,那么是无法直接调用对象中的方法的,通过这种方式就可以调用。 6 | 7 | 机制很简单,就是直接从 base 中拿到 Func。 8 | 9 | ```autohotkey 10 | rawCall(aMethodName,aThis,aParams*) 11 | ``` 12 | 13 | ### 参数 Parameters: 14 | 15 | - aMethodName - 方法名 16 | - aThis - 执行Method的this环境 17 | - aParams* - 参数列表 18 | 19 | ### 返回 Returns: 20 | 直接返回方法的返回值 21 | ### 抛出异常 Throws: 22 | - %异常说明% 23 | ### 示例 Example 24 | ```autohotkey 25 | class Method{ 26 | 27 | initFunc(){ 28 | return "initFunc" 29 | } 30 | ;----------------------------- 31 | __call(aMethodName,aParams*){ 32 | return "__call" 33 | } 34 | ;----------------------------- 35 | __New(aFuncThis,aFunc){ 36 | rawCall(this,"initFunc",aFuncThis,aFunc) 37 | return this 38 | } 39 | } ;---------class Method End 40 | ``` -------------------------------------------------------------------------------- /Docs/showObj().md: -------------------------------------------------------------------------------- 1 | **用于展示对象中的内容:** 2 | 3 | - 主要用于展示对象中的内容。 4 | 比如,展示 WinObj 中的 title 字段等等。 5 | - 如果对象中含有 『__toString』 字段,那么 toString() 函数会优先使用该方法处理对象,而不是使用默认的枚举器。 6 | - 如果『__toString』 字段是数组那么就当它为 aList 参数传入。 7 | 8 | ```autohotkey 9 | showObj(aObj,aList:="") 10 | ``` 11 | 12 | ### 参数 Parameters: 13 | 14 | - aObj - 需要展示的 Object 15 | - aList - 字段名数组 16 | 17 | ### 返回 Returns: 18 | 默认会返回 base 中所有的 FuncObj 转换成的 String 。 19 | 20 | 如果也想展示其他的字段,在 aList 中加入即可。 21 | 22 | ### 抛出异常 Throws: 23 | - null 24 | ### 示例 Example 25 | ```autohotkey 26 | winObj := new Win("春我部防卫队") 27 | 28 | act := new Method(winObj.equal,winObj) 29 | 30 | act.assertter := Bean.true 31 | act.before := Bean.False 32 | 33 | map := showObj(act) 34 | LogPrintln(map,"map >>>") 35 | ``` 36 | 37 | ```autohotkey 38 | map >>>{__Class:Method,after:Bean.true,before:Bean.false,func:Win.equal} 39 | ``` -------------------------------------------------------------------------------- /Docs/Ini.md: -------------------------------------------------------------------------------- 1 | # Ini Class 2 | 3 | 1. 更方便地读取 Ini 文件 4 | 5 | 6 | 7 | [TOC] 8 | 9 | ## Section Class 10 | 11 | ### __New(aIni,aSection) 12 | 13 | 构造方法 14 | 15 | ### read(aKey,aDefault:="") 16 | 17 | 依照 key 读取 value,完全用 IniRead 命令实现 18 | 19 | - aDefault,是当 key 没有找到时,所填的默认值。如果没有填写默认值,数据又找不到,那么就会 throw Key-Value is not Exsit. 20 | 21 | ### readInMap(aMap,aKey,aDefault:="") 22 | 23 | 读取 key 并且放入 一个 Map 中 24 | 25 | ### getMap(aKeys*) 26 | 27 | 按照 keyList 批量读取 Value ,并且以 Map 形式返回。 28 | 29 | ```autohotkey 30 | aIniPath:=A_ScriptDir "\test.ini" 31 | aSection:="test" 32 | newIni:=new Ini(aIniPath) 33 | newSection:=newIni.getSection(aSection) 34 | 35 | theMap:=newSection.getMap("A","B","C","F") 36 | 37 | LogPrintln(theMap,"theMap >>>") 38 | ``` 39 | 40 | ```autohotkey 41 | A_ScriptName >>> TDD_getMap().ahk 42 | theMap >>>{A:1,B:2,C:3,F:*NS*} 43 | 44 | ``` -------------------------------------------------------------------------------- /Docs/AnalyzeWin.md: -------------------------------------------------------------------------------- 1 | **获取窗口参数,可用于窗口操作和调试:** 2 | 3 | ```autohotkey 4 | AnalyzeWin(InputWinTitle,EnableWinText:=false,InputDetectHiddenWindows:="") 5 | ``` 6 | 7 | ### 参数 Parameters: 8 | 9 | - InputWinTitle - 目标窗口的 `WinTitle` 10 | - EnableWinText - 是否检测 `WinText` 11 | - InputDetectHiddenWindows - 是否检测隐藏窗口 12 | - 不会影响全局设置 13 | - 如果不填或者为 NullString ,那么就按照全局设置来执行 14 | - AutoHotKey 自带的信息窗口属于隐藏窗口 15 | 16 | ### 返回 Returns: 17 | Obj 18 | 19 | - 包含以下 Key 20 | 21 | ```autohotkey 22 | WinTitle := "WinTitle: " WinTitle 23 | WinClass := "ahk_class " WinClass 24 | Winexe := "ahk_exe " Winexe 25 | WinPID := "ahk_id " WinPID 26 | WinPath := "WinPath: " WinPath 27 | ``` 28 | 29 | ```autohotkey 30 | Str 上面所有信息加入换行符,并变为字符串输出。主要是为了调试时,直接查看信息的方便。 31 | ``` 32 | 33 | ### 抛出异常 Throws: 34 | 35 | - null 36 | ### 示例 Example 37 | ```autohotkey 38 | Obj:=AnalyzeWin(WinTitle) 39 | Str:=Obj.Str 40 | ``` -------------------------------------------------------------------------------- /Docs/APPLocker.md: -------------------------------------------------------------------------------- 1 | # AppLocker Class 2 | 3 | 简单的应用锁。 4 | 5 | - 检查机制:每隔一分钟检查一次时间,如果匹配就开锁,不匹配就上锁。 6 | - 上锁机制:echo Y|cacls %path% /p everyone:N 7 | - 开锁机制:echo Y|cacls %path% /p everyone:F 8 | 9 | ## 域 Field 10 | 11 | - asPath:=[""] 12 | 13 | 路径必须带英文引号 "" 14 | 15 | - asUnLockTime:=["",""] 16 | 17 | 允许应用被打开的时间段。["1100","1300"] 就表示上午11:00到下午1:00 18 | 19 | - sCheckIntervalMin:=1 20 | 21 | 检查频率,单位是分钟 22 | 23 | ## 方法 Method 24 | 25 | ### Lock() 26 | 27 | 上锁 28 | 29 | ### UnLock() 30 | 31 | 开锁 32 | 33 | ### AutoLock() 34 | 35 | 根据时间段执行上锁或者开锁 36 | 37 | ### CheckTime(targetTime,asUnLockTime) 38 | 39 | 检查当前时间是否在允许时间段内 40 | 41 | ### SetTimer() 42 | 43 | 每分钟执行一次AutoLock() 44 | 45 | ## 示例 46 | 47 | ```autohotkey 48 | ;给QQ上锁 49 | QQPath="F:\腾讯QQV3\QQ\Bin\QQ.exe" 50 | QQAppLocker:=new AppLocker(QQPath,[1650,1730]) 51 | QQAppLocker.AutoLock() 52 | QQAppLocker.SetTimer() 53 | ``` 54 | 55 | -------------------------------------------------------------------------------- /Docs/Stack.md: -------------------------------------------------------------------------------- 1 | # Stack Class 2 | 3 | 一个堆栈实例类 4 | 5 | > “栈”通常是指“后进先出”(LIFO)的容器。有时栈也被称为叠加栈,因为最后“压入”栈的元素,第一个“弹出”栈。经常用来类比栈的事物是装有弹簧的储放器中的自助餐托盘,最后装入的托盘总是最先拿出使用的。 6 | > 7 | > ——《Java编程思想_第4版》 8 | 9 | ## 方法 Methods 10 | 11 | ### get() 12 | 13 | 获取内置List 14 | 15 | ### set(aList) 16 | 17 | 设置内置List(复制而非引用) 18 | 19 | ### length() 20 | 21 | ### __New(aList := "") 22 | 23 | 调用set(aList)建立实例 24 | 25 | ### empty() 26 | 27 | ### peek() 28 | 29 | 获取顶端元素 30 | 31 | ### pop() 32 | 33 | 获取顶端元素并删除 34 | 35 | ### push(aElement) 36 | 37 | 压入 38 | 39 | ### search(aElement) 40 | 41 | 从顶端搜索并返回index 42 | 43 | ### getEnum() 44 | 45 | 获取枚举器 46 | 47 | ```AutoHotKey 48 | theStack := new Stack(_List.LetterList) 49 | 50 | theEnum := theStack.getEnum() 51 | 52 | while(theEnum.next(v)){ 53 | LogPrintln(v,A_LineFile "(" A_LineNumber ")" " : " "v >>> `r`n") 54 | } 55 | ``` 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Docs/throwWithSt.md: -------------------------------------------------------------------------------- 1 | ## throwWithSt 2 | 3 | 生成堆栈追踪 stdout 4 | 5 | ```autohotkey 6 | throwWithSt(Mes) 7 | ``` 8 | 9 | ### 参数 Parameters: 10 | 11 | - Mes - 堆栈追踪字符串开头的提示信息,和Exception中的 Mes。 12 | - EnableEx - 可选的Exception,默认开启 13 | 14 | ### 返回 Returns: 15 | 堆栈追踪字符串 16 | ### 抛出异常 Throws: 17 | 第 2 参数可选开启 Exception 18 | 19 | ### 示例 Example 20 | 21 | ![控制台](https://raw.githubusercontent.com/Oilj/GitHubPictureBed/master/20190712064758.png) 22 | 23 | ```autohotkey 24 | ;属于throw的增强,可以在第 2 参数中开启真正的throw(为了catch),也可以不加 25 | try 26 | f() 27 | return 28 | 29 | 30 | f() { 31 | a() 32 | } 33 | 34 | 35 | a() { 36 | b() 37 | } 38 | 39 | b() { 40 | c() 41 | } 42 | 43 | c() { 44 | 45 | throwWithSt("StackTrace_Test") 46 | return 47 | } 48 | 49 | return 50 | 51 | ;~ From:https://www.autohotkey.com/boards/viewtopic.php?t=6001 52 | 53 | ``` 54 | 55 | ### 直接依赖 Direct Dependency 56 | 57 | StackTrace() -------------------------------------------------------------------------------- /Docs/HIGHLIGHTING.md: -------------------------------------------------------------------------------- 1 | # HIGHLIGHTING(语法高亮) 2 | 3 | ## 当前的支持情况 4 | 5 | 准备支持 `SciTE4AutoHotkey` 的语法高亮和自动完成。 6 | 7 | 现在只是初步的支持,对于一些常用的类和函数做了最简单的适配。 8 | 9 | ## 使用方法 10 | ### SciTE4AutoHotkey 语法高亮机制 11 | 12 | `SciTE4AutoHotkey` 的自动完成和语法高亮分别由 `ahk.api` `ahk.keywords.properties` 两个文件负责。 13 | 14 | 其中 `ahk.api` 是 AHK 格式文件,使用`;`作为注释符号;`properties`则使用`#`为注释符号,且高亮信息仅支持英文小写字母。 15 | ### 可以使用 mlink 建立链接使用 16 | 两个文件都放在项目的根目录中。Clone 之后可以使用 `mlink` 命令在 Git仓库 和 SciTE根目录 间建立文件软链接,从而实现联动。 17 | 18 | 比如 19 | 20 | ```CMD 21 | mklink "F:\AutoHotkey\SciTE\ahk.api" "D:\AHKs\ahk_lib\ahk.api" 22 | ``` 23 | 24 | 这个的意思就是,在 "F:AutoHotkey\SciTE\ahk.api" 建立一个指向 "D:\AHKs\ahk_lib\ahk.api" 的软链接。 25 | 26 | 该命令使用时,应保证 "F:AutoHotkey\SciTE\ahk.api" 路径没有被占用。 27 | 28 | ### 软硬链接的区别 29 | 30 | 硬链接只支持在同卷中建立,仅支持给文件建立。硬链接相当于同一个文件拥有两个目录,他们是完全平等的。 31 | 32 | 软链接可以在任意位置间建立,同时支持文件和文件夹。软链接类似于快捷方式,软链接被删除,不会影响硬链接。 33 | 34 | [了解更多](https://blog.csdn.net/x534119219/article/details/79111936)。 -------------------------------------------------------------------------------- /Docs/ObjDump.md: -------------------------------------------------------------------------------- 1 | **序列化对象到内存或硬盘** 2 | 3 | *Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化 deserialization 是一种将这些字节重建成一个对象的过程。* 4 | 5 | ```autohotkey 6 | 保存对象到内存(变量) 7 | size := ObjDump(Object,Variable,DumpBuffer) 8 | 保存对象到硬盘(文件) 9 | size := ObjDump(FilePath,Object,DumpBuffer) 10 | 11 | ``` 12 | 13 | 从内存(变量)读取对象 14 | Obj := ObjLoad(Address) 15 | 从硬盘读取对象 16 | Obj := ObjLoad(FilePath) 17 | 18 | ### 返回 Returns: 19 | size 文件大小(字节) 20 | ### 示例 Example 21 | ```autohotkey 22 | theMap := Object("A","a","B","1234") 23 | StartTime := A_TickCount 24 | FilePath := "D:\AHKs\Dev\SerializationTest.Obj" 25 | size := ObjDump(FilePath,theMap) 26 | LogPrintln(size,A_LineFile "(" A_LineNumber ")" " : " "size >>> `r`n") 27 | SerializationTestObj := ObjLoad(FilePath) 28 | LogPrintln(SerializationTestObj,A_LineFile "(" A_LineNumber ")" " : " "SerializationTestObj >>> `r`n") 29 | 30 | ``` 31 | 32 | From: -------------------------------------------------------------------------------- /Docs/新手指南(BEGINNER_GUIDE).md: -------------------------------------------------------------------------------- 1 | 在此之前,确保 2 | 3 | 安装 [AutoHotKey](https://autohotkey.com) 的 Unicode-32 版本 和 [SciTE4AutoHotkey](https://autohotkey.com/boards/viewtopic.php?t=62) 4 | 5 | # 1. 下载 6 | 在 [GitHub](https://github.com/Andy-AO/BeanLib) 中[打包下载](https://github.com/Andy-AO/BeanLib/archive/master.zip),然后解压到需要使用BeanLib的脚本的同级目录。 7 | 8 | ![image-20200827113431662](pic/image-20200827113431662.png) 9 | 10 | # 2. 导入 11 | 12 | 1. 打开 SciTE4AutoHotkey,按下 Ctrl+N 新建文件,输入以下代码 13 | 14 | ```autohotkey 15 | #Include BeanLib\BeanLib.ahk 16 | logPrintln("Hello World !") 17 | ``` 18 | 1. 将这个脚本保存到,BeanLib文件夹的同级别文件夹,并按下 F5 运行脚本。 19 | 如无意外,出现 HelloWorld 表示库已经部署成功。 20 | 21 | 22 | ![image-20200827113157942](pic/image-20200827113157942.png)) 23 | 24 | # 3. 后续 25 | - 在需要导入的脚本的最顶部加入 `#Include` ,即可调用库类和函数,具体详见 `#Include` 官方文档。 26 | - 使用库时,遇到问题请先先查阅文档,大多数的问题都已经有解决方案。如果无法解决也可以联系我。 27 | - 可以导入代码高亮,如果不导入也不影响库的使用,相关内容请查看[语法高亮(HIGHLIGHTING)](HIGHLIGHTING.md)的说明文档。 -------------------------------------------------------------------------------- /Docs/AutoClassify.md: -------------------------------------------------------------------------------- 1 | # AutoClassify Class 2 | 3 | 文件自动分类(依赖 Everything Class) 4 | 5 | ## 域 Field 6 | 7 | - sSearchCriteria - 搜索关键词字符串 8 | 9 | - sDestPattern - 文件存放目录 10 | 11 | - searchResultList - 用于存放文件路径的数组 12 | 13 | - EverthingObj - 用于执行搜索的Everything对象 14 | 15 | - sCheckIntervalMin:= 执行搜索的间隔(分钟) 16 | 17 | 默认 0.5 分钟 18 | 19 | ## 方法 Method 20 | 21 | ### __New(sSearchCriteria,sDestPattern) 22 | 23 | 构造对象 24 | 25 | ### BuildSearchObj() 26 | 27 | 建立EverthingObj 28 | 29 | ### Search() 30 | 31 | 搜索文件 32 | 33 | ### SearchAndRemove() 34 | 35 | 搜索并且移动文件到目标文件夹 36 | 37 | ### SetTimer(sCheckIntervalMin) 38 | 39 | 定时执行SearchAndRemove() 40 | 41 | ## 示例 42 | 43 | ```autohotkey 44 | ;电子书自动分类:每两分钟把电子书移动到对应文件夹 45 | SearchCriteria="G:\MyDownload\" .mobi|.azw|.epub 46 | DestPattern:="X:\MyLibrary" 47 | 48 | azwClassify:=new AutoClassify(SearchCriteria,DestPattern) 49 | azwClassify.SearchAndRemove() 50 | azwClassify.SetTimer(0.3) 51 | ``` 52 | 53 | -------------------------------------------------------------------------------- /Test/LibTest_switcher.ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | 24 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 25 | 26 | 27 | #If WinActive(A_ScriptName) 28 | ;可以按下Alt+L查看最近运行的行 29 | 30 | /* 31 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 32 | ListLines 33 | return 34 | 35 | !^h:: 36 | KeyHistory 37 | return 38 | 39 | !a:: 40 | send,{F5} 41 | return 42 | 43 | !^s:: 44 | ListVars 45 | return 46 | */ 47 | 48 | 49 | #If 50 | 51 | 52 | !q:: 53 | ExitApp 54 | return 55 | 56 | +!q:: 57 | Pause 58 | return 59 | -------------------------------------------------------------------------------- /Test/Lib.ahk: -------------------------------------------------------------------------------- 1 | Class TypeClass{ 2 | static staticPath := "D:\AHKs\ahk_lib\Test\LibTest_toString().ahk" 3 | ComObj := AccWrapper.ObjectFromPoint(vChildId).get() 4 | Obj := Object() 5 | Class := AutoInputBox 6 | FuncObj := new Function("toString") 7 | Exception := Exception(_Ex.IndexOutOfBounds) 8 | Path := Str := TypeClass.staticPath 9 | NS := "" 10 | Number := "123456789" 11 | Boolean := false 12 | FileObj := FileOpen(TypeClass.staticPath,"r") 13 | } 14 | 15 | TypeClassInstance := new TypeClass() 16 | 17 | 18 | ;------------------------------ 19 | 20 | MapFactory(aMap,aKeyFunc:="",aValueFunc:=""){ 21 | theReturn := "",Type.assertObj(aKeyFunc),Type.assertObj(aValueFunc) 22 | for k,v in aMap { 23 | theKeyStr := theValueStr := "" 24 | theKeyStr := aKeyFunc.call(k) 25 | theValueStr := aValueFunc.call(v) 26 | theResult := theKeyStr ":" theValueStr 27 | theReturn .= theResult "`r`n" 28 | } 29 | return theReturn 30 | } 31 | -------------------------------------------------------------------------------- /Docs/Function.md: -------------------------------------------------------------------------------- 1 | # Fuction Class 2 | 3 | 1. 性质:实例类 4 | 2. 开发目的:主要用于代替普通Func对象的Bind()方法 5 | 6 | ## 方法 Method 7 | 8 | ### __New(aMethodName,aBindParas*) 9 | 10 | **新建一个带有参数绑定的 Function 对象:** 11 | 12 | #### 参数 Parameters: 13 | 14 | - aMethodName - 已存在的Function名 15 | - aBindParas - 需要绑定的参数 16 | 17 | #### 返回 Returns: 18 | 19 | 根据原来的方法而定 20 | 21 | #### 抛出异常 Throws: 22 | 23 | - 根据原来的方法而定 24 | 25 | ```autohotkey 26 | testLogPrintln(text,text2){ 27 | LogPrintln(text) 28 | LogPrintln(text2) 29 | return 30 | } 31 | 32 | 33 | text := "A!" 34 | 35 | theFunc := new Function("testLogPrintln",text) 36 | 37 | LogPrintln(theFunc,A_LineFile "(" A_LineNumber ")" " : " "theFunc >>> `r`n") 38 | 39 | theFunc.call("B!") 40 | 41 | Hotkey,^r,% theFunc 42 | 43 | ``` 44 | 45 | ### call(aCallParas*) 46 | **Func对象的Call方法:** 47 | 作为一个Func对象,必须拥有Call方法 48 | 49 | #### 参数 Parameters: 50 | 51 | - aCallParas- 调用参数 52 | 53 | #### 返回 Returns: 54 | 55 | 根据原来的方法而定 56 | 57 | #### 抛出异常 Throws: 58 | 59 | - 根据原来的方法而定 60 | -------------------------------------------------------------------------------- /Docs/Protect().md: -------------------------------------------------------------------------------- 1 | **对任意对象添加 读/写/调用 保护:** 2 | 3 | 让不存在的值,不能被读写;不存在的方法,不能被调用。主要目的是减轻 DeBug 的负担。 4 | 5 | - Call 不存在的方法 `throwWithSt(_EX.NoExistMethod)` 6 | - Set/Get 不存在的值 `throwWithSt(_EX.NoExistVariate)` 7 | - 是通过元编程(继承)实现的,所以如果对象本身就是元编程实现的,那么该方法对其无效。 8 | 9 | ```autohotkey 10 | Protect(Obj) 11 | ``` 12 | 13 | ### 参数 Parameters: 14 | 15 | - Obj - 任意对象 16 | 17 | ### 返回 Returns: 18 | null 19 | ### 抛出异常 Throws: 20 | - type.assertObj(Obj) 21 | ### 示例 Example 22 | ```autohotkey 23 | ;给任意对象添加保护 24 | 25 | _EX.t ;没有保护前,不会有任何警告 26 | protect(_EX) 27 | _EX.t ;保护之后抛出异常 28 | 29 | ``` 30 | 31 | ```autohotkey 32 | ;给任意类的构造器添加保护,这样之后,类生成的对象都会有保护 33 | 34 | Obj:=new cl() 35 | 36 | ;均触发了保护 37 | Obj.set:="" 38 | Obj.Call() 39 | Obj.get 40 | 41 | ;调用已存在的值,均不会触发保护 42 | Obj.set1:="x" 43 | Obj.Call1() 44 | Obj.get1 45 | 46 | return 47 | 48 | Class cl{ 49 | 50 | get1:="get1" 51 | set1:="set1" 52 | 53 | call1(){ 54 | return "call1" 55 | } 56 | 57 | __New(){ 58 | protect(this) ;this返回前,给其添加保护 59 | return this 60 | } 61 | 62 | } 63 | ``` -------------------------------------------------------------------------------- /Docs/Queue.md: -------------------------------------------------------------------------------- 1 | # Queue Class 2 | 3 | 1. 性质:实例类 4 | 2. 开发目的:通过Array编写的先进先出(FIFO)的数据结构,常被称为'队列'. 5 | 6 | From:[A Queue in AutoHotkey? - Ask for Help - AutoHotkey Community](https://autohotkey.com/board/topic/94062-a-queue-in-autohotkey/) 7 | 8 | ## 域 Fields 9 | 10 | null 11 | 12 | ## 示例 Examples 13 | ```AutoHotKey 14 | q := new queue() 15 | q.push("1") 16 | q.push("2") 17 | q.push("3") 18 | msgbox % "pop: " q.pop() "`nnewsize: " q.size() ;pop = 1, newsize = 2 {2,3} 19 | q.push("4") 20 | msgbox % "pop: " q.pop() "`nnewsize: " q.size() ;pop = 2, newsize = 2 {3,4} 21 | msgbox % "pop: " q.pop() "`nnewsize: " q.size() ;pop = 3, newsize = 1 {4} 22 | q.push("5") 23 | msgbox % "pop: " q.pop() "`nnewsize: " q.size() ;pop = 4, newsize = 1 {5} 24 | msgbox % "pop: " q.pop() "`nnewsize: " q.size() ;pop = 5, newsize = 0 {} 25 | msgbox % "pop: " q.pop() "`nnewsize: " q.size() ;pop = "", newsize = 0 {} 26 | ``` 27 | 28 | ## 方法 Methods 29 | 30 | ### push(item) 31 | 32 | 放入队列 33 | 34 | ### Pop() 35 | 36 | 从队列尾部中取出元素并删除 37 | 38 | ### size() 39 | 40 | 获取队列中的元素数 -------------------------------------------------------------------------------- /IO/TextFile.ahk: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 说明:操作文本文档 4 | */ 5 | 6 | class TextFile{ 7 | 8 | static path := Object() 9 | ,Encoding := "UTF-8" 10 | 11 | replace(SearchText,ReplaceText, Limit := -1){ 12 | theResult := StrReplace(this.get(), SearchText , ReplaceText, OutputVarCount, Limit) 13 | this.Set(theResult) 14 | return OutputVarCount 15 | } 16 | 17 | __New(aPathObj){ 18 | Type.assertObj(aPathObj) 19 | this.path := aPathObj 20 | } 21 | 22 | get(){ 23 | this.path.assertExist() 24 | thePath := this.path.getPath() 25 | FileRead, theText, %thePath% 26 | return theText 27 | } 28 | 29 | FileAppend(aText){ 30 | dir := this.path.dir 31 | dirExist := FileExist(dir) 32 | if(NOT(dirExist)){ 33 | FileCreateDir, %dir% 34 | } 35 | FileAppend,% aText, % this.path.getPath(),% this.Encoding 36 | return ErrorLevel 37 | } 38 | 39 | Set(aText){ 40 | if(FileExist(this.path.getPath())) 41 | FileDelete,% this.path.getPath() 42 | this.FileAppend(aText) 43 | return aText 44 | } 45 | 46 | 47 | } ;---------class TextFile EndTextFile 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Test/LibTest_PathObj.ReName()_folder.ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | 24 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 25 | 26 | thePathObj := new PathObj("D:\AHKs\ahk_lib\Test\LibTest_PathObj.ReName()") 27 | 28 | thePathObj.reName("folder") 29 | 30 | #If WinActive(A_ScriptName) 31 | ;可以按下Alt+L查看最近运行的行 32 | 33 | /* 34 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 35 | ListLines 36 | return 37 | 38 | !^h:: 39 | KeyHistory 40 | return 41 | 42 | !a:: 43 | send,{F5} 44 | return 45 | 46 | !^s:: 47 | ListVars 48 | return 49 | */ 50 | 51 | 52 | #If 53 | 54 | 55 | !q:: 56 | ExitApp 57 | return 58 | 59 | +!q:: 60 | Pause 61 | return 62 | -------------------------------------------------------------------------------- /Docs/MesToast.md: -------------------------------------------------------------------------------- 1 | # MesToast Class 2 | 3 | 1. 性质:实例类 4 | 2. 开发目的: 5 | 高度定制化的消息弹窗/消息通知/消息框 6 | ## 自动计时并销毁通知 7 | 1. 弹出通知后,键鼠无动作不计时。 8 | 2. 位于顶层才计时。 9 | 3. 鼠标在窗口上方不计时。 10 | 11 | ## 透明 12 | 计时器`<5s`的时候,窗口开始逐渐透明 13 | 14 | ## 方法 Methods 15 | 16 | ### __New(aTitle,aText,aDuration := "",AllowPlay := true) 17 | - aTitle:标题 18 | - aText:内容 19 | - aDuration:窗口存活时间 20 | - AllowPlay : 允许弹出窗口时播放提示音 21 | 22 | ### reset() 23 | 重置Toast,计数器回到原始状态 24 | ### show() 25 | - 显示Toast 26 | 27 | 鼠标悬停在上面会停止计时 28 | 29 | ### destroyAll() 30 | 31 | 静态方法,用于销毁所有的 Toast。 32 | 33 | 要注意的是,只能消除本进程内由 `Toast` 静态类托管的 Toast 34 | 35 | ### CloseAll() 36 | 37 | 静态方法,用于关闭所有的 Toast。 38 | 39 | 这个能够消除所有 WinTitle 中窗口名有默认后缀 ` - Toast`,窗口类是 `ahk_class AutoHotkeyGUI` 的窗口。 40 | 41 | ## 示例 42 | ```AutoHotKey 43 | MesToast.setSoundFile(new PathObj(Filename)) 44 | 45 | theText := "A1" 46 | theTitle := "title" 47 | 48 | theMesToast_1 := new MesToast(theTitle,theText) 49 | theMesToast_1.show() 50 | 51 | 52 | theText := "A2" 53 | theTitle := "title" 54 | 55 | theMesToast_2 := new MesToast(theTitle,theText) 56 | theMesToast_2.show() 57 | ``` -------------------------------------------------------------------------------- /Test/LibTest_PathObj.ReName().ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | 24 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 25 | 26 | thePathObj := new PathObj("D:\AHKs\ahk_lib\Test\LibTest_PathObj.ReName().txt") 27 | 28 | result := thePathObj.reName("theFile.txt") 29 | 30 | #If WinActive(A_ScriptName) 31 | ;可以按下Alt+L查看最近运行的行 32 | 33 | /* 34 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 35 | ListLines 36 | return 37 | 38 | !^h:: 39 | KeyHistory 40 | return 41 | 42 | !a:: 43 | send,{F5} 44 | return 45 | 46 | !^s:: 47 | ListVars 48 | return 49 | */ 50 | 51 | 52 | #If 53 | 54 | 55 | !q:: 56 | ExitApp 57 | return 58 | 59 | +!q:: 60 | Pause 61 | return 62 | -------------------------------------------------------------------------------- /Test/LibTest__Wins.ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | 24 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 25 | 26 | 27 | LogPrintln(_Wins.AnalyzeOnMap("ahk_exe Typora.exe"),A_LineFile "(" A_LineNumber ")" " : " "_Wins.AnalyzeOnMap(""ahk_exe Typora.exe"") >>> `r`n") 28 | 29 | #If WinActive(A_ScriptName) 30 | ;可以按下Alt+L查看最近运行的行 31 | 32 | /* 33 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 34 | ListLines 35 | return 36 | 37 | !^h:: 38 | KeyHistory 39 | return 40 | 41 | !a:: 42 | send,{F5} 43 | return 44 | 45 | !^s:: 46 | ListVars 47 | return 48 | */ 49 | 50 | 51 | #If 52 | 53 | 54 | !q:: 55 | ExitApp 56 | return 57 | 58 | +!q:: 59 | Pause 60 | return 61 | -------------------------------------------------------------------------------- /Docs/InstanceCheck().md: -------------------------------------------------------------------------------- 1 | # InstanceCheck 2 | 3 | 在单例类的New方法中调用,目的是保证类的对象唯一。(单例模式) 4 | 5 | 通常的调用方法如下: 6 | 7 | ```autohotkey 8 | __New(){ 9 | InstanceCheck(this.base) 10 | return this 11 | } 12 | ``` 13 | 14 | ### 抛出异常 Throws: 15 | - %异常说明% 16 | ### 示例 Example 17 | ```autohotkey 18 | 19 | Double.base := new Double_Base() 20 | ;~ Double.base := new Double_Base() 21 | 22 | class Double{ 23 | } 24 | class Double_Base{ 25 | ;~ static InstanceExist := false ;这个可写可不写 26 | 27 | ;------------------------------ 28 | 29 | __New(){ 30 | InstanceCheck(this.base) 31 | return this 32 | } 33 | 34 | } ;---------class Double_Base End 35 | 36 | 37 | ``` 38 | 39 | ```autohotkey 40 | ;实例化次数>1会导致 41 | -Stack Trace ~ ~~ Mes:Instance Singleton Class 实例化单例类. 42 | 43 | D:\AHKs\ahk_lib\Function.ahk(480) : ==> offset:-1 caller:StackTrace 44 | D:\AHKs\ahk_lib\Function.ahk(490) : ==> offset:-2 caller:throwWithSt 45 | D:\AHKs\ahk_lib\Function.ahk(504) : ==> offset:-3 caller:throw 46 | D:\AHKs\Dev\TPDD_单例类测试.ahk(50) : ==> offset:-4 caller:InstanceCheck 47 | D:\AHKs\Dev\TPDD_单例类测试.ahk(34) : ==> offset:-5 caller:Double_Base.__New 48 | ``` -------------------------------------------------------------------------------- /IO/Example_JSON.ahk: -------------------------------------------------------------------------------- 1 | #Include %A_LineFile%\..\JSON.ahk 2 | 3 | json_str = 4 | ( 5 | { 6 | "str": "Hello World", 7 | "num": 12345, 8 | "float": 123.5, 9 | "true": true, 10 | "false": false, 11 | "null": null, 12 | "array": [ 13 | "Auto", 14 | "Hot", 15 | "key" 16 | ], 17 | "object": { 18 | "A": "Auto", 19 | "H": "Hot", 20 | "K": "key" 21 | } 22 | } 23 | ) 24 | 25 | parsed := JSON.Load(json_str) 26 | 27 | parsed_out := Format(" 28 | (Join`r`n 29 | String: {} 30 | Number: {} 31 | Float: {} 32 | true: {} 33 | false: {} 34 | null: {} 35 | array: [{}, {}, {}] 36 | object: {{}A:""{}"", H:""{}"", K:""{}""{}} 37 | )" 38 | , parsed.str, parsed.num, parsed.float, parsed.true, parsed.false, parsed.null 39 | , parsed.array[1], parsed.array[2], parsed.array[3] 40 | , parsed.object.A, parsed.object.H, parsed.object.K) 41 | 42 | stringified := JSON.Dump(parsed,, 4) 43 | stringified := StrReplace(stringified, "`n", "`r`n") ; for display purposes only 44 | 45 | ListVars 46 | WinWaitActive ahk_class AutoHotkey 47 | ControlSetText Edit1, [PARSED]`r`n%parsed_out%`r`n`r`n[STRINGIFIED]`r`n%stringified% 48 | WinWaitClose 49 | return -------------------------------------------------------------------------------- /Core/Analyze().ahk: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 用于分析对象(Object)的继承(extends)关系 4 | */ 5 | 6 | ;---------------------------------------------------------------------- 7 | 8 | AnalyzeClassName(Obj){ ;返回Obj的所有Base的ClassName 9 | StrList:=[],ObjList:=Analyze(Obj) 10 | for i,Obj in ObjList{ 11 | TheStr:=Obj.__Class 12 | if((isObject(Obj))AND(TheStr="")) 13 | StrList.Push("*NotClass*") 14 | else if(TheStr="") 15 | StrList.Push("*NS*") 16 | else 17 | StrList.Push(TheStr) 18 | } 19 | return StrList 20 | } 21 | ;---------------------------------------------------------------------- 22 | Analyze(Obj){ ;返回元素的所有Base 23 | List:=[],ObjList:=[],ObjList[1]:=Obj,StrList:=[],StrList[1]:=Obj.__Class,counter:=1 24 | type.assertObj(Obj) 25 | loop{ 26 | TheBase:=ObjList[A_Index].base 27 | if(counter>1) 28 | return ObjList 29 | if(TheBase="") OR (TheBase.__Class=""){ ;除了检查base之外,还必须检查其__Class 30 | counter++ 31 | continue 32 | } 33 | 34 | else 35 | counter:=1 36 | 37 | ObjList.push(TheBase) 38 | 39 | } 40 | 41 | return ObjList 42 | } 43 | 44 | ;---------------------------------------------------------------------- 45 | -------------------------------------------------------------------------------- /Core/Timer.ahk: -------------------------------------------------------------------------------- 1 | 2 | class Timer{ 3 | 4 | static Priority := 50000 5 | ,Periodbase := "250",func := "",isSingle := false 6 | 7 | Period[] 8 | { 9 | get { 10 | if(this.isSingle = ""){ 11 | this.isSingle := false 12 | } 13 | 14 | if(this.isSingle){ 15 | return ("-" Abs(this.Periodbase)) 16 | } 17 | else{ 18 | return Abs(this.Periodbase) 19 | } 20 | 21 | } 22 | set { 23 | return this.Periodbase := Abs(value) 24 | } 25 | } 26 | 27 | set(){ 28 | Priority := Timer.Priority 29 | ,FuncObj := this.func 30 | ,aMSec := this.Period 31 | SetTimer,%FuncObj%,%aMSec%, %Priority% 32 | return ErrorLevel 33 | } 34 | off(){ 35 | FuncObj := this.func 36 | SetTimer,%FuncObj%,off 37 | } 38 | On(){ 39 | FuncObj := this.func 40 | SetTimer,%FuncObj%,On 41 | } 42 | delete(){ 43 | FuncObj := this.func 44 | SetTimer,%FuncObj%,Delete 45 | } 46 | __New(aFunc,aPeriod := "250",isSingle := false){ 47 | Type.assertNumber(aPeriod) 48 | Type.assertObj(aFunc) 49 | this.func := aFunc,this.Period := aPeriod,this.isSingle := isSingle 50 | } 51 | } ;---------class Timer End 52 | -------------------------------------------------------------------------------- /FuncObj/BeanEnum.ahk: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | 说明:自定义的枚举器 5 | */ 6 | class BeanEnum { 7 | ;---------------------------------------------------------------------- 8 | Map := "" 9 | MaxIndex:="" 10 | CurrentIndex:=1 11 | ;---------------------------------------------------------------------- 12 | __New(aMap){ 13 | this.Map := _Container.mapToList(aMap) 14 | this.MaxIndex := this.Map.key.length() 15 | this.next:=this.base.next 16 | return this 17 | } 18 | ;---------------------------------------------------------------------- 19 | __Call(methodName,byref k:="", byref v:=""){ 20 | if(methodName = "")or(methodName="next") 21 | return this.next(k,v) 22 | else 23 | throwWithSt(_Ex.NoExistMethod) 24 | } 25 | ;---------------------------------------------------------------------- 26 | next(byref k:="", byref v:=""){ 27 | if (this.CurrentIndex > this.MaxIndex) 28 | return false 29 | else{ 30 | v := this.map.value[this.CurrentIndex] 31 | k := this.map.key[this.CurrentIndex] 32 | this.CurrentIndex++ 33 | return true 34 | } 35 | 36 | } 37 | ;---------------------------------------------------------------------- 38 | } -------------------------------------------------------------------------------- /Test/LibTest_String.insert(insert,pos=1).ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | 24 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 25 | 26 | 27 | assert("1x23456" == "123456".insert("x",2)) 28 | assert("12345x6" == "123456".insert("x",6)) 29 | assert("123456x" == "123456".insert("x",7)) 30 | assert("123456x" == "123456".insert("x",8)) 31 | 32 | 33 | #If WinActive(A_ScriptName) 34 | ;可以按下Alt+L查看最近运行的行 35 | 36 | /* 37 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 38 | ListLines 39 | return 40 | 41 | !^h:: 42 | KeyHistory 43 | return 44 | 45 | !a:: 46 | send,{F5} 47 | return 48 | 49 | !^s:: 50 | ListVars 51 | return 52 | */ 53 | 54 | 55 | #If 56 | 57 | 58 | !q:: 59 | ExitApp 60 | return 61 | 62 | +!q:: 63 | Pause 64 | return 65 | -------------------------------------------------------------------------------- /Test/LibTest_new PathObj().ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | 24 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 25 | 26 | 27 | 28 | thePathObj := new PathObj("Test\",new PathObj("D:\AHKs\ahk_lib\")) 29 | 30 | thePath := thePathObj.getPath() 31 | 32 | LogPrintln(thePath,A_LineFile "(" A_LineNumber ")" " : " "thePath >>> `r`n") 33 | 34 | 35 | #If WinActive(A_ScriptName) 36 | ;可以按下Alt+L查看最近运行的行 37 | 38 | /* 39 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 40 | ListLines 41 | return 42 | 43 | !^h:: 44 | KeyHistory 45 | return 46 | 47 | !a:: 48 | send,{F5} 49 | return 50 | 51 | !^s:: 52 | ListVars 53 | return 54 | */ 55 | 56 | 57 | #If 58 | 59 | 60 | !q:: 61 | ExitApp 62 | return 63 | 64 | +!q:: 65 | Pause 66 | return 67 | -------------------------------------------------------------------------------- /Docs/HotStringMaps.md: -------------------------------------------------------------------------------- 1 | # HotStringMaps Class 2 | 3 | 1. 静态类 4 | 2. 开发目的:接收并组织 `HotString` 对象,提供 有序的 String-HotString 关联数组。 5 | 6 | ## 域 7 | 8 | List 放置 String-HotString 关联数组 。 9 | 10 | 语境约束的生效与否,取决于注册的先后顺序,所以安排注册的顺序是有必要的。 11 | 12 | 如果有控制顺序和生成 String-HotString 关联数组的需求,生成 HotString 对象之后,请将其加入该数组。 13 | 14 | ## 方法 Method 15 | 16 | ### ExtractAndMerge() :根据 List 生成 String-HotString 关联数组 17 | 18 | ![](https://raw.githubusercontent.com/Oilj/GitHubPictureBed/master/20190709100419.png) 19 | 20 | ```autohotkey 21 | HotStringMaps.List := [SciTE,FileLocator,TotalControl] 22 | 23 | HotStringMaps.List[2]["SearchInAHKWithOutTTD"] := HotString.create(Trigger := "::;ahknd" 24 | ,FuncObj:=HotStringMaps.List[2].OpenInTheTab.bind("ahk","H:\MyLibrary\FileLocator搜索条件\搜索非TDD的AHK内容.srf") 25 | ,Remarks:= "搜索非TDD的AHK内容" 26 | ,HotStringMaps.List[2].when) 27 | 28 | HotStringMaps.List[2]["SearchInAHK"] := HotString.create(Trigger := "::;ahk" 29 | ,FuncObj:=HotStringMaps.List[2].OpenInTheTab.bind("ahknd","H:\MyLibrary\FileLocator搜索条件\搜索AHK文件中的内容.srf") 30 | ,Remarks:= "搜索AHK文件中的内容" 31 | ,HotStringMaps.List[2].when) 32 | 33 | 34 | HotStringMaps.ExtractAndMerge() 35 | ``` 36 | 37 | ## 高度相关类 38 | 39 | HotString 40 | 41 | -------------------------------------------------------------------------------- /Docs/AutoInputBox.md: -------------------------------------------------------------------------------- 1 | # AutoInputBox Class 2 | 3 | 1. 性质:实例类 4 | 2. 开发目的:固定宽度,且自动根据 prompt 换行的InputBox 5 | 6 | ## 域 Fields 7 | 8 | static aTextPrefix:="" 9 | 10 | static deFaultText:=["UseClipBoard"] 11 | 12 | static AlwaysOnTop:=false 13 | 14 | ## 示例 Examples 15 | ```AutoHotKey 16 | inputBox:=new AutoInputBox(aTitle,aPrompt) 17 | 18 | inputBox.SetDeFaultText("Func") 19 | 20 | inputBox.SetAlwaysOnTop(true) 21 | 22 | userInput := inputBox.start() 23 | ``` 24 | 25 | ## 方法 Methods 26 | 27 | ### __New(aTitle,aPrompt) 28 | **构造方法** 29 | 30 | #### 参数 Parameters: 31 | 32 | - aTitle - 窗口标题 33 | - aPrompt - 窗口内容 34 | 35 | #### 返回 Returns: 36 | 37 | AutoInputBox Object 38 | 39 | 40 | ### SetAlwaysOnTop(aStr) 41 | **让窗口置顶/非置顶(默认)** 42 | 43 | #### 参数 Parameters: 44 | 45 | - aStr - 只接受布尔值 46 | 47 | #### 返回 Returns: 48 | 49 | aStr 50 | 51 | ### SetDeFaultText(aStr) 52 | 53 | **设置窗口输入框默认文本(默认为ClipBoard)** 54 | 55 | #### 参数 Parameters: 56 | 57 | - aStr - 文本 58 | 59 | #### 返回 Returns: 60 | 61 | aStr 62 | 63 | ### start() 64 | 65 | **弹出带有输入框的窗口** 66 | 67 | #### 参数 Parameters: 68 | 69 | - null 70 | 71 | #### 返回 Returns: 72 | 73 | String - 用户输入的 74 | 75 | #### 抛出异常 Throws: 76 | 77 | - UserCancelled 78 | -------------------------------------------------------------------------------- /Docs/ExcelToList().md: -------------------------------------------------------------------------------- 1 | **转 Excel 文件为 List:** 2 | 3 | ```autohotkey 4 | ExcelToList(FileName, nSheet := 1, last_row := "", last_column := "") 5 | ``` 6 | 7 | ### 参数 Parameters: 8 | 9 | - FileName - 文件名 10 | - nSheet - 工作表名 11 | - last_row - 截止行(数字) 12 | - last_column - 截止列(数字) 13 | 14 | ### 返回 Returns: 15 | List 16 | ### 抛出异常 Throws: 17 | - _Ex.NoExistFile 18 | ### 示例 Example 19 | 20 | - 测试文件 `test.xlsx` 放在根目录了 21 | 22 | ```autohotkey 23 | ;全参数示例 24 | arr := ExcelToList("test.xlsx","Sheet2","3","1") 25 | ``` 26 | 27 | ```autohotkey 28 | ;自带示例(绘制出了GUI) 29 | #NoEnv 30 | #SingleInstance Force 31 | SetBatchLines -1 32 | #Include ExcelToArray.ahk 33 | 34 | Gui, Add, ListView, xm w700 r10 Grid, A|B|C|D|E|F|G|H|I 35 | Loop, 9 36 | LV_ModifyCol(A_Index, 75) 37 | Gui, Show,, Get Listview data from excel 38 | 39 | SplashTextOn, , , Loading... 40 | Gosub, ImportData 41 | SplashTextOff 42 | Return 43 | 44 | ImportData: 45 | arr := ExcelToList("test.xlsx") 46 | 47 | for i, dat in arr 48 | LV_Add("", dat*) 49 | Return 50 | 51 | GuiClose: 52 | ExitApp 53 | ``` 54 | 55 | Form:https://github.com/tmplinshi/ExcelToArray 56 | 57 | **对原作进行了改动** 58 | 59 | - 使用 Local 变量之前先进行了声明,防止 `#Warn` 报警 60 | - test.xlsx增加 Sheet2 以便测试更多参数 61 | - 改名为 ExcelToList() -------------------------------------------------------------------------------- /Docs/README.md: -------------------------------------------------------------------------------- 1 | # [BeanLib](https://www.kancloud.cn/xrvu_zen/ahk_lib/902301) 2 | 3 | ![](https://raw.githubusercontent.com/Oilj/GitHubPictureBed/master/%E5%B0%8F%E8%80%8C%E7%BE%8E%E7%9A%84%E4%B8%AD%E6%96%87AHKLib%E6%A8%AA%E5%B9%85_BeanLib.png) 4 | 5 | ## 特点 6 | 7 | - BeanLib是环保的,不会占用全局变量,不会干扰自动执行段。 8 | 9 | ## 使用说明 10 | 11 | ### [Lib是什么?](https://wyagd001.github.io/zh-cn/docs/Functions.htm#include) 12 | 13 | Lib是可以重复使用的代码,您可以把他们和自己的代码相结合,来创造新的功能。 14 | BeanLib 最低兼容 [AutoHotKey 1.1.30.00](https://wyagd001.github.io/zh-cn/docs/AHKL_ChangeLog.htm),仅确保对 Unicode-32bit 版本的支持。 15 | 16 | ### 更新平台 17 | 18 | - 请在 [看云(KanCloud)](https://www.kancloud.cn/xrvu_zen/ahk_lib/content) 阅读文档 19 | 20 | - [GitHub](https://github.com/Oilj/BeanLib) 作为 **提交issue, 发起Pull Request , 下载** 之用。 21 | 22 | 23 | ### 如何使用? 24 | 25 | - 先下载:从 [GitHub](https://github.com/Oilj/BeanLib) 直接 Clone。 26 | 27 | - 之后导入:使用 [#Include](https://wyagd001.github.io/zh-cn/docs/Functions.htm#include) 命令导入 `BeanLib.ahk` 即可。默认只导入`Core`包,其他包按需导入。 28 | 29 | - 可选项:也可以为 BeanLib 中的函数添加语法高亮,不过这并非必须,详见『语法高亮』章节。 30 | 31 | 如果你是新手,可以戳[新手指南(BEGINNER_GUIDE)](%E6%96%B0%E6%89%8B%E6%8C%87%E5%8D%97(BEGINNER_GUIDE).md)查看详细的图文教程。 32 | 33 | BeanLib 的函数之间可能是相互依赖的,不建议拆分使用。 34 | 35 | ### 所有贡献者 36 | 37 | [GitHub](https://github.com/Oilj/BeanLib/graphs/contributors) -------------------------------------------------------------------------------- /Docs/HotString.md: -------------------------------------------------------------------------------- 1 | # HotString Class 2 | 3 | 1. 实例类 4 | 2. 全面接管HotString,以便于实现自动化提示等等等,高度自定义的内容。 5 | 底部有自动化效果图,要注意的是,左侧的悬浮窗并没有包括在这个类中,提供数据(有序的 String-HotString 关联数组)的机制,在`HotStringMaps` 这个类中。 6 | 7 | ## 方法 Method 8 | 9 | ### isHotString(Obj):判断一个对象是不是HotString类的实例 10 | 11 | ### create(Trigger,behavior,Remarks,Premise):注册热键并返回HotString对象 12 | 13 | Trigger: Str 触发器字符串,例如"::sm" 14 | 15 | behavior : Func 触发之后的行为 16 | 17 | Remarks : Str 备注 18 | 19 | Premise :Func 语境约束。与 #if 的效果一样 20 | 21 | 22 | 23 | 24 | ![](https://raw.githubusercontent.com/Oilj/GitHubPictureBed/master/20190709100419.png) 25 | 26 | ```autohotkey 27 | HotStringMaps.List := [SciTE,FileLocator,TotalControl] 28 | 29 | HotStringMaps.List[2]["SearchInAHKWithOutTTD"] := HotString.create(Trigger := "::;ahknd" 30 | ,FuncObj:=HotStringMaps.List[2].OpenInTheTab.bind("ahk","H:\MyLibrary\FileLocator搜索条件\搜索非TDD的AHK内容.srf") 31 | ,Remarks:= "搜索非TDD的AHK内容" 32 | ,HotStringMaps.List[2].when) 33 | 34 | HotStringMaps.List[2]["SearchInAHK"] := HotString.create(Trigger := "::;ahk" 35 | ,FuncObj:=HotStringMaps.List[2].OpenInTheTab.bind("ahknd","H:\MyLibrary\FileLocator搜索条件\搜索AHK文件中的内容.srf") 36 | ,Remarks:= "搜索AHK文件中的内容" 37 | ,HotStringMaps.List[2].when) 38 | 39 | 40 | HotStringMaps.ExtractAndMerge() 41 | ``` 42 | 43 | ## 高度相关类 44 | 45 | HotStringMaps -------------------------------------------------------------------------------- /Test/LibTest_replaceAll().ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | 24 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 25 | 26 | 27 | "ABCDEFG".replaceAll("ACG".ToList(),"") 28 | 29 | LogPrintln("ACG".ToList(),A_LineFile "(" A_LineNumber ")" " : " """ACG"".ToList() >>> `r`n") 30 | 31 | LogPrintln("ABCDEFG".replaceAll("ACG".ToList(),""),A_LineFile "(" A_LineNumber ")" " : " """ABCDEFG"".replaceAll(""ACG"".ToList(),"""") >>> `r`n") 32 | 33 | ;~ replaceAll("[/\\:*?<>|]","") 34 | 35 | #If WinActive(A_ScriptName) 36 | ;可以按下Alt+L查看最近运行的行 37 | 38 | /* 39 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 40 | ListLines 41 | return 42 | 43 | !^h:: 44 | KeyHistory 45 | return 46 | 47 | !a:: 48 | send,{F5} 49 | return 50 | 51 | !^s:: 52 | ListVars 53 | return 54 | */ 55 | 56 | 57 | #If 58 | 59 | 60 | !q:: 61 | ExitApp 62 | return 63 | 64 | +!q:: 65 | Pause 66 | return 67 | -------------------------------------------------------------------------------- /Test/LibTest_TextFile.replace().ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | 24 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 25 | 26 | theTextFileObj := new TextFile(new PathObj("LibTest_TextFile.replace().txt")) 27 | 28 | LogPrintln(theTextFileObj.get(),A_LineFile "(" A_LineNumber ")" " : " "theTextFileObj.get() >>> `r`n") 29 | 30 | theTextFileObj.replace("#","AAA") 31 | 32 | LogPrintln(theTextFileObj.get(),A_LineFile "(" A_LineNumber ")" " : " "theTextFileObj.get() >>> `r`n") 33 | 34 | #If WinActive(A_ScriptName) 35 | ;可以按下Alt+L查看最近运行的行 36 | 37 | /* 38 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 39 | ListLines 40 | return 41 | 42 | !^h:: 43 | KeyHistory 44 | return 45 | 46 | !a:: 47 | send,{F5} 48 | return 49 | 50 | !^s:: 51 | ListVars 52 | return 53 | */ 54 | 55 | 56 | #If 57 | 58 | 59 | !q:: 60 | ExitApp 61 | return 62 | 63 | +!q:: 64 | Pause 65 | return 66 | -------------------------------------------------------------------------------- /APP/APPLocker.ahk: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | 说明:简单的应用锁 5 | */ 6 | class AppLocker{ 7 | asPath := [""] 8 | sCheckIntervalSec := "5".MinToMsec() 9 | TimeCheckerObj:="" 10 | ;---------------------------------------------------------------------- 11 | __New(aPath,asUnLockTime){ 12 | this.TimeCheckerObj :=new TimeChecker() 13 | this.TimeCheckerObj.WhiteList := asUnLockTime 14 | this.asPath[1]:=aPath 15 | return this 16 | } 17 | 18 | ;---------------------------------------------------------------------- 19 | UnLock(){ 20 | Commends:="echo Y|cacls " this.asPath[1] " /p everyone:" "F" 21 | UseCmd(Commends) 22 | return 23 | } 24 | 25 | ;---------------------------------------------------------------------- 26 | Lock(){ 27 | Commends:="echo Y|cacls " this.asPath[1] " /p everyone:" "N" 28 | UseCmd(Commends) 29 | return 30 | } 31 | ;---------------------------------------------------------------------- 32 | 33 | AutoLock(){ 34 | isUnLockTime:=this.TimeCheckerObj.CheckByWhiteList() 35 | if(isUnLockTime) 36 | this.unlock() 37 | else 38 | this.Lock() 39 | return 40 | } 41 | 42 | ;---------------------------------------------------------------------- 43 | SetTimer(){ 44 | FuncObj:=this.AutoLock.Bind(this) 45 | theTimer := new Timer(FuncObj,this.sCheckIntervalSec),theTimer.set() 46 | return 47 | } 48 | } 49 | ;AppLocker Class End 50 | -------------------------------------------------------------------------------- /Docs/BeanLib_CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # ![*](https://raw.githubusercontent.com/Oilj/GitHubPictureBed/master/AHK%E5%B0%8F%E5%9B%BE%E6%A0%87_20190105183041.png)贡献指南 CONTRIBUTING 2 | 3 | [欢迎提交代码,任何贡献者都会被铭记。](#jumpGX) 4 | 5 | ## 如何贡献? 6 | 7 | 去 GitHub 提出 拉取申请(pull request) 8 | 9 | **代码应符合以下要求:** 10 | 11 | - 已经在项目中使用过。 12 | - 为保证质量,不要提交未使用的代码。 13 | - 不使用 #Include ,只使用 BeanLib 中的已有函数。 14 | - 为保证其他人可以正常使用,应在独立环境中测试。 15 | - 不污染公共空间。 16 | - 不使用全局变量(类对象/函数除外),不干扰自动执行。 17 | - 之所以类对象和函数可以除外,是因为占用这些是安全的。函数被重复定义,会发出警告;类复写在 `#Warn` 中有单独警告。 18 | - 有简单的介绍。 19 | - 至少有功能/输入/返回值介绍,最好有示例,请使用MD语法,可参考[文档模板](https://www.kancloud.cn/xrvu_zen/ahk_lib/902299)。 20 | - 支持 AHK_L 21 | - 请不要使用其他分支的特有语法或函数。 22 | - 禁止触发除 `LocalSameAsGlobal` 外的任何 `#Warn` 警告 23 | - 之所以 `LocalSameAsGlobal` 可以,是因为这个实在是太操蛋了。谁用这玩意?简直反人类,我一般都关掉。 24 | - 禁止使用一切 `魔法数值` 。 25 | - 魔法数值,指的是没有实现定义的任何数值。 26 | - 使用魔法数值会损害可读性。 27 | 28 | ### 一些建议和提醒 29 | 30 | - 维护者和贡献者,应在关键决策上,尽可能征询公共意见。 31 | - 如有借鉴他人代码,提供出处。 32 | - 尽可能使用函数语法。 33 | - 代码将在 LGPLv3 协议的保护下被发布。 34 | - LGPLv3是使用最广泛的开源协议。![*](https://raw.githubusercontent.com/Oilj/GitHubPictureBed/master/LGPLv3_20190105183651.png) 35 | 36 | ## 贡献者信息在哪? 37 | - [GitHub页面的 Insights/contributors](https://github.com/Oilj/BeanLib/graphs/contributors) 。 38 | - [码云 的"贡献者"页面](https://gitee.com/xrvu_zen/BeanLib/repository/stats/master)。 -------------------------------------------------------------------------------- /APP/TimeChecker.ahk: -------------------------------------------------------------------------------- 1 | 2 | class TimeChecker{ 3 | __New(){ 4 | return this 5 | } 6 | 7 | BlackList_Base := "",WhiteList_Base := "" 8 | ;------------------------------ 9 | BlackList[index:=""] 10 | { 11 | get { 12 | if(index="") 13 | return this.BlackList_Base 14 | else 15 | return this.BlackList_Base[index] 16 | } 17 | set { 18 | Type.assertList(value) 19 | return this.BlackList_Base:=value 20 | } 21 | } 22 | 23 | ;------------------------------ 24 | WhiteList[index:=""] 25 | { 26 | get { 27 | if(index="") 28 | return this.WhiteList_Base 29 | else 30 | return this.WhiteList_Base[index] 31 | } 32 | set { 33 | Type.assertList(value) 34 | return this.WhiteList_Base:=value 35 | } 36 | } 37 | ;------------------------------ 38 | CheckByBlackList(){ 39 | Type.assertList(this.BlackList) 40 | currentTime:=getCurrentTime() 41 | b1:=currentTimethis.BlackList[2] 43 | if(b1 OR b2) 44 | return true 45 | else 46 | return false 47 | } 48 | ;------------------------------ 49 | CheckByWhiteList(){ 50 | Type.assertList(this.WhiteList) 51 | currentTime:=getCurrentTime() 52 | b1:=currentTime>=this.WhiteList[1] 53 | b2:=currentTime<=this.WhiteList[2] 54 | if(b1 AND b2) 55 | return true 56 | else 57 | return false 58 | } 59 | } ;---------class TimeCheck End -------------------------------------------------------------------------------- /Docs/JsonFile.md: -------------------------------------------------------------------------------- 1 | # JsonFile Class 2 | 3 | 1. 性质:实例类 4 | 2. 开发目的:Json对象的读写 5 | 6 | ## 方法 Method 7 | 8 | ### _New(path) 9 | 10 | - path - JsonFile文件的路径 11 | 12 | 会先检查路径是否合法:如果路径不合法,会抛出异常。 13 | 14 | ### load() 15 | 16 | 从JsonFile文件中加载JsonObject,文件不存在,会加载空`json`。 17 | 18 | ### init(aDefaultObject) 19 | 20 | 使用默认Object,对JSON进行初始化。 21 | 22 | 也就是检查出JSON中所有的缺失项,并填入默认值。 23 | 24 | ### store(jsonObj) 25 | 26 | 向JsonFile文件中存储JsonObject 27 | 28 | 29 | 30 | ```Java 31 | path := "D:\AHKs\Dev\APPBookMarkGroup\MyTomato.json" 32 | 33 | jf := new JsonFile(path) 34 | 35 | array := jf.load() 36 | 37 | LogPrintln(array,A_LineFile "(" A_LineNumber ")" " : " "array >>> `r`n") 38 | 39 | array[3] := "New" 40 | 41 | content := jf.store(array) 42 | 43 | LogPrintln(content,A_LineFile "(" A_LineNumber ")" " : " "content >>> `r`n") 44 | ``` 45 | 46 | 47 | 48 | ```AutoHotKey 49 | >"F:\gUAPP\AutoHotkey32Bit\SciTE\..\AutoHotkey.exe" /ErrorStdOut "D:\AHKs\ahk_lib\IO\Example_JsonFile.ahk" 50 | A_ScriptName >>> Example_JsonFile.ahk 51 | D:\AHKs\ahk_lib\IO\Example_JsonFile.ahk(38) : array >>> 52 | [{title:MyGridPane [D:\JavaProject\MyGridPane]},{title:MyTomato [D:\JavaProject\MyTomato]},New] 53 | D:\AHKs\ahk_lib\IO\Example_JsonFile.ahk(44) : content >>> 54 | [{"title":"MyGridPane [D:\\JavaProject\\MyGridPane]"},{"title":"MyTomato [D:\\JavaProject\\MyTomato]"},"New"] 55 | 56 | ``` 57 | 58 | -------------------------------------------------------------------------------- /Docs/InvisibleCharacter.md: -------------------------------------------------------------------------------- 1 | # InvisibleCharacter Class 2 | 3 | 1. 性质:静态类 4 | 2. 开发目的:用于处理不可见字符(不确定所列出的不可见字符是否完全,感觉已经覆盖了绝大多数情况,列表来自[JAVA过滤掉String中的不可见UNICODE字符_qq_42673507的博客-CSDN博客](https://blog.csdn.net/qq_42673507/article/details/104486357)) 5 | 6 | ## 域 Fields 7 | 8 | ```AutoHotKey 9 | static CodeList := [0x200b,0x0200c,0x0200d,0x0200e,0x200f 10 | ,0x202a,0x202b,0x202c,0x202d,0x202e 11 | ,0x2066,0x2067,0x2068,0x2069 12 | ,0xfeff 13 | ,0x06ec] 14 | ``` 15 | 16 | ## 属性 Attribute 17 | 18 | ### List[] 19 | 20 | 无参,返回不可见字符组成的List 21 | 22 | ### Regex[] 23 | 24 | 无参,返回匹配不可见字符的正则表达式,假设不可见字符为A、B和C,表达式为`m)(*ANYCRLF)[A|B|C]`。 25 | 26 | 可用于从字符串中替换(清除)不可见字符。 27 | 28 | ## 方法 Methods 29 | 30 | ### count(aStr) 31 | 32 | 用于统计字符串中不可见字符的数量 33 | 34 | #### 参数 Parameters 35 | 36 | - aStr - 被统计字符串 37 | 38 | #### 返回 Returns 39 | 40 | int 41 | 42 | #### 抛出异常 Throws 43 | 44 | - assertStr() 45 | 46 | #### 测试 Test 47 | 48 | 有 49 | 50 | 51 | ### contain(aStr) 52 | 53 | 检查字符串中是否含有不可见字符? 54 | 55 | #### 参数 Parameters 56 | 57 | - aStr - 被检查的字符串 58 | 59 | #### 返回 Returns 60 | 61 | Boolean 62 | 63 | #### 抛出异常 Throws 64 | 65 | - assertStr() 66 | 67 | #### 测试 Test 68 | 69 | 无 70 | 71 | 72 | ### clear(aStr) 73 | 74 | 清除掉字符串中的不可见字符 75 | 76 | #### 参数 Parameters 77 | 78 | - aStr - 被清除的字符串 79 | 80 | #### 返回 Returns 81 | 82 | String 83 | 84 | #### 抛出异常 Throws 85 | 86 | - assertStr() 87 | 88 | #### 测试 Test 89 | 90 | 有 -------------------------------------------------------------------------------- /Docs/LogPrintln().md: -------------------------------------------------------------------------------- 1 | **将任何对象转换为字符串,并且打印到标准输出:** 2 | 3 | 主要用于调试。执行的必要条件是 `Bean.LogEnable = true`,默认值为 `false`。 4 | 5 | - count = 0 的 Object 会显示 {\*Object\*} 6 | - NullString 会显示 \*NS\* 7 | - count = length 的Object(List) ,用 [] 包裹 8 | - count != length 的Object ,用 {} 包裹 9 | 10 | ```autohotkey 11 | LogPrintln(Obj:="",prefix:="",postfix:="") 12 | ``` 13 | 14 | ### 参数 Parameters: 15 | 16 | - Obj - 需要打印的对象 17 | 18 | - prefix - 打印的前缀字符串 19 | 20 | - postfix- 打印的后缀字符串 21 | 22 | 前后缀主要用于打印时解释对象,详见示例 23 | 24 | ### 返回 Returns: 25 | 26 | null 27 | 28 | ### 抛出异常 Throws: 29 | ### 示例 Example 30 | ```autohotkey 31 | theList:=Object(_List.TheList1,[_List.TheList2,"D"],[],"D") 32 | LogPrintln(theList,"theList >" ">> ") 33 | ``` 34 | 35 | ![运行效果](https://raw.githubusercontent.com/Oilj/GitHubPictureBed/master/image_4.png) 36 | 37 | ```autohotkey 38 | #If WinActive("ahk_exe SciTE.exe") Or WinActive(".ahk - Notepad++") 39 | 40 | ;一键生成调试语句 41 | ^RButton:: 42 | TheName:=SuperCopy(20,0),TheNameAfterEscape:=StrReplace(TheName,"""","""""") 43 | ;主要是为了防止清理调试语句时候被清除,所以用两端分开再合起来的办法 44 | logPosfix1="%TheNameAfterEscape% > 45 | logPosfix2=>>" 46 | logPosfix:=logPosfix1 . logPosfix2 47 | OutString=LogPrintln(%TheName%,%logPosfix%) 48 | ClipBoard:=OutString 49 | firstPara = 一键生成调试语句 50 | secondPara = %TheName% 的 DeepPrintln 形式已经放到剪切板中了. 51 | theMesToast := new MesToast(firstPara,secondPara),theMesToast.show() 52 | return 53 | #If 54 | ``` -------------------------------------------------------------------------------- /GUI/AutoGUI.ahk: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 说明:用于GUI自动化的类 4 | */ 5 | 6 | class AutoGUI{ 7 | 8 | mainFunc:="",List_condition:={} 9 | 10 | ;---------------------------------------------------------------------- 11 | 12 | Check(){ 13 | List_condition := this.List_condition 14 | for i,v in List_condition { 15 | type.assertObj(v) 16 | result := v.Call() 17 | if(Not(result)){ 18 | throwWithSt("条件" i "不符合.") 19 | } 20 | } 21 | return 22 | } 23 | ;---------------------------------------------------------------------- 24 | 25 | CheckAnd(){ 26 | List_condition := this.List_condition 27 | for i,v in List_condition { 28 | type.assertObj(v) 29 | result := v.Call() 30 | if(Not(result)){ 31 | throwWithSt("第" i "个条件不符合.") 32 | } 33 | } 34 | 35 | return 36 | } 37 | ;---------------------------------------------------------------------- 38 | 39 | __New(aMainFunc){ 40 | this.mainFunc := aMainFunc 41 | return this 42 | } 43 | 44 | ;---------------------------------------------------------------------- 45 | 46 | start(){ 47 | type.assertObj(this.mainFunc) 48 | result := this.mainFunc.Call() 49 | return result 50 | } 51 | 52 | ;---------------------------------------------------------------------- 53 | 54 | } ;---------class AutoGUI End 55 | 56 | 57 | ;---------------------------------------------------------------------- 58 | 59 | ;---------------------------------------------------------------------- 60 | -------------------------------------------------------------------------------- /Docs/UMSS.md: -------------------------------------------------------------------------------- 1 | # UMSS Class 2 | 3 | 1. 实例类 4 | 2. 让 Tab/Space 等,并非修饰键的按键,拥有修饰键的类似效果。 5 | 6 | ## 方法 Method 7 | 8 | ### __New(key) 9 | 10 | **UMSS组合按键的特性** 11 | 12 | 构造中会执行 this.registerNewKey()。该函数会让按键「修饰化」,按键会变成「单发」。 13 | 14 | 如果没有按下「组合热键」,原按键会在Up之后发送;否则就触发「组合按键」的FuncObj,原按键不发送。 15 | 16 | 这有利于对其设置组合热键。 17 | 18 | **延迟问题** 19 | 20 | 任何修饰键方案,都会导致原按键发送变慢,这是很难避免的。 21 | 22 | 设置 Space 等按键的时候,打字会有拖沓的感觉,注意取舍。 23 | 24 | ### register(keyName,theFunc,Options:="") 25 | 26 | - keyName :组合中,另一个按键的keyName 27 | - theFunc : 组合按键触发的Func 28 | - Options:HotKey 的设置,详见AutoHotKey帮助文件 29 | 30 | 务必要通过这种方法注册。不要直接使用语境约束,会导致组合按键出现BUG。 31 | 32 | 在不同的 AHK 程序中注册热键,会出现竞争关系,谁后注册谁生效,而其余的则失效。 33 | 34 | 在同一 AHK 程序中注册热键时,会将对象保存在 UMSS 类的静态 keys Map 中,如果注册热键时,发现之前已经注册,那么就会直接返回之前的 Object,而不会重新注册。这是为了解决「UMSS多次申请同一热键时,除第一次申请外,目标修饰键会在按下时发送的BUG」。 35 | 36 | ### Unregister(keyName) 37 | 38 | 删除某个注册热键 39 | 40 | - keyName :组合中,另一个按键的keyName 41 | 42 | ### destroy() 43 | 44 | 删除所有注册过的热键 45 | 46 | 47 | 48 | 示例:注册组合热键 Tab & j 和 Tab & . 49 | 50 | ```autohotkey 51 | class Print{ 52 | P1(){ 53 | LogPrintln(A_ThisFunc,A_LineFile "(" A_LineNumber ")" " : " "A_ThisFunc >>> `r`n") 54 | } 55 | P2(){ 56 | LogPrintln(A_ThisFunc,A_LineFile "(" A_LineNumber ")" " : " "A_ThisFunc >>> `r`n") 57 | } 58 | } ;---------class Print End 59 | 60 | TabUMSS := new UMSS("Tab") 61 | TabUMSS.register("j",new Method(Print.P1,Print)) 62 | TabUMSS.register(".",new Method(Print.P2,Print)) 63 | ``` -------------------------------------------------------------------------------- /Test/LibTest_AutoInputBox{}.ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | 24 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 25 | 26 | theBox:=new AutoInputBox("aTitle","aPrompt") 27 | theBox.SetAlwaysOnTop(true) 28 | 29 | thePage := theBox.start() 30 | 31 | LogPrintln(thePage,A_LineFile "(" A_LineNumber ")" " : " "thePage >>> `r`n") 32 | 33 | 34 | theBox_2:=new AutoInputBox("aTitle","aPrompt") 35 | theBox_2.SetAlwaysOnTop(true) 36 | 37 | theBox_2.SetDeFaultText("TestText") 38 | 39 | thePage_2 := theBox_2.start() 40 | 41 | 42 | LogPrintln(thePage_2,A_LineFile "(" A_LineNumber ")" " : " "thePage_2 >>> `r`n") 43 | 44 | #If WinActive(A_ScriptName) 45 | ;可以按下Alt+L查看最近运行的行 46 | 47 | /* 48 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 49 | ListLines 50 | return 51 | 52 | !^h:: 53 | KeyHistory 54 | return 55 | 56 | !a:: 57 | send,{F5} 58 | return 59 | 60 | !^s:: 61 | ListVars 62 | return 63 | */ 64 | 65 | 66 | #If 67 | 68 | 69 | !q:: 70 | ExitApp 71 | return 72 | 73 | +!q:: 74 | Pause 75 | return 76 | -------------------------------------------------------------------------------- /Docs/JSON.md: -------------------------------------------------------------------------------- 1 | # JSON Class 2 | 3 | 1. 性质:静态类 4 | 2. 开发目的:JSON String 的序列化与反序列化 5 | 6 | 7 | 8 | From: https://github.com/cocobelgica/AutoHotkey-JSON 9 | 10 | ## 方法 Method 11 | 12 | ### JSON.Load(json_str) 13 | 14 | 反序列化JSON String 15 | 16 | ### JSON.Dump(json_obj) 17 | 18 | 序列化JSON Obj 19 | 20 | ```AutoHotKey 21 | #Include %A_LineFile%\..\JSON.ahk 22 | 23 | json_str = 24 | ( 25 | { 26 | "str": "Hello World", 27 | "num": 12345, 28 | "float": 123.5, 29 | "true": true, 30 | "false": false, 31 | "null": null, 32 | "array": [ 33 | "Auto", 34 | "Hot", 35 | "key" 36 | ], 37 | "object": { 38 | "A": "Auto", 39 | "H": "Hot", 40 | "K": "key" 41 | } 42 | } 43 | ) 44 | 45 | parsed := JSON.Load(json_str) 46 | 47 | parsed_out := Format(" 48 | (Join`r`n 49 | String: {} 50 | Number: {} 51 | Float: {} 52 | true: {} 53 | false: {} 54 | null: {} 55 | array: [{}, {}, {}] 56 | object: {{}A:""{}"", H:""{}"", K:""{}""{}} 57 | )" 58 | , parsed.str, parsed.num, parsed.float, parsed.true, parsed.false, parsed.null 59 | , parsed.array[1], parsed.array[2], parsed.array[3] 60 | , parsed.object.A, parsed.object.H, parsed.object.K) 61 | 62 | stringified := JSON.Dump(parsed,, 4) 63 | stringified := StrReplace(stringified, "`n", "`r`n") ; for display purposes only 64 | 65 | ListVars 66 | WinWaitActive ahk_class AutoHotkey 67 | ControlSetText Edit1, [PARSED]`r`n%parsed_out%`r`n`r`n[STRINGIFIED]`r`n%stringified% 68 | WinWaitClose 69 | return 70 | ``` 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /Docs/Script.md: -------------------------------------------------------------------------------- 1 | # Script Class 2 | 3 | 1. 用于对 AHK脚本 进行各种操作,比如,重启某个脚本,暂停某个脚本 4 | 5 | ### 已知问题 6 | 7 | 1. 发送消息的脚本,如果是通过 `#SingleInstance force` 重启的,不会执行成功 8 | 2. 不支持 Unicode字符,原因未知,可能是 AHK元编程 的BUG 9 | 10 | [TOC] 11 | 12 | ## 域 Field 13 | 14 | **都是常量,写入会throw** 15 | 16 | ​ Static Msg := 0x111 17 | 18 | Static Open := 65300 ;打开窗口 19 | Static Reload := 65400 ;重启 20 | Static Edit := 65401 ;编辑 21 | Static Spy := 65402 ;Spy 22 | Static Pause := 65403 ;暂停 23 | Static Suspend := 65404 ;挂起 24 | Static Exit := 65405 ;退出 25 | 26 | Static Lines := 65406 ;最近运行 27 | Static Variable := 65407 ;变量信息 28 | Static HotKeys := 65408 ;热键信息 29 | Static KeyHistory := 65409 ;按键历史信息 30 | Static Refresh := 65410 ;刷新 信息窗口 31 | 32 | Static Help := 65411 ;打开CHM帮助文件 33 | Static WebSite := 65412 ;打开 https://www.autohotkey.com 34 | 35 | ## 方法 Method 36 | 37 | ### Open() 38 | 激活窗口 39 | ### Reload() 40 | 重启 41 | ### Edit() 42 | 编辑 43 | ### Spy() 44 | 打开窗口探测工具 45 | ### Pause () 46 | 暂停 47 | ### Suspend () 48 | 挂起 49 | ### Exit() 50 | 退出 51 | 52 | ### Lines() 53 | 显示最近运行Lines 54 | ### Variable() 55 | 显示打开变量信息 56 | ### HotKeys() 57 | 显示热键信息 58 | ### KeyHistory() 59 | 显示按键历史信息 60 | ### Refresh() 61 | 刷新信息窗口 62 | 63 | ### Help() 64 | 打开CHM帮助文件 65 | ### WebSite() 66 | 打开 https://www.autohotkey.com 67 | 68 | ## 示例 69 | 70 | ```autohotkey 71 | 72 | ScriptObj:=new Script("Reloader.ahk") 73 | ^p:: 74 | ScriptObj.Pause() 75 | return 76 | ^r:: 77 | ScriptObj.Reload() 78 | return 79 | ``` -------------------------------------------------------------------------------- /Test/LibTest_Type().ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | 24 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 25 | 26 | Type.assertNumber("1") 27 | Type.assertNumber("0.015") 28 | 29 | 30 | return 31 | 32 | theKeyFunc := Method.for(FuncClass.handleKey,FuncClass) 33 | theValueFunc := Method.for(FuncClass.handleValue,FuncClass) 34 | 35 | 36 | stdoutln(MapFactory(TypeClassInstance,theKeyFunc,theValueFunc)) 37 | 38 | 39 | Class FuncClass{ 40 | handleKey(aKey){ 41 | theStr = Type(%aKey%,true) 42 | return theStr 43 | } 44 | handleValue(aValue){ 45 | return Type(aValue,true) 46 | } 47 | } 48 | 49 | 50 | 51 | #If WinActive(A_ScriptName) 52 | ;可以按下Alt+L查看最近运行的行 53 | 54 | /* 55 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 56 | ListLines 57 | return 58 | 59 | !^h:: 60 | KeyHistory 61 | return 62 | 63 | !a:: 64 | send,{F5} 65 | return 66 | 67 | !^s:: 68 | ListVars 69 | return 70 | */ 71 | 72 | 73 | #If 74 | 75 | 76 | !q:: 77 | ExitApp 78 | return 79 | 80 | +!q:: 81 | Pause 82 | return 83 | -------------------------------------------------------------------------------- /IO/Example_JsonFile.ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | #Include D:\AHKs\Dev\_TempLib.ahk 3 | 4 | #Persistent ;不让脚本自动退出,以便查看调试信息 5 | #NoEnv 6 | Hotstring("EndChars"," ") 7 | #Hotstring ?0 O 8 | 9 | #Warn All , StdOut ;#全部开启 10 | #Warn ClassOverwrite , StdOut ;#无论如何也要开,类覆盖警告 11 | #Warn LocalSameAsGlobal, Off ;#一定关本地全局冲突警告 12 | 13 | 14 | #SingleInstance force 15 | FileEncoding , UTF-8 16 | SetTitleMatchMode 2 17 | SendMode Input 18 | Process, Priority,,High 19 | SetWorkingDir %A_ScriptDir% 20 | SetFormat,Float,0.2 21 | 22 | ThreadDuration := 2000 23 | Thread, Interrupt , %ThreadDuration% 24 | ControlDelay := 100 25 | SetControlDelay, %ControlDelay% 26 | 27 | Bean.LogEnable := true 28 | 29 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 30 | 31 | 32 | path := "D:\AHKs\Dev\APPBookMarkGroup\MyTomato.json" 33 | 34 | jf := new JsonFile(path) 35 | 36 | array := jf.load() 37 | 38 | LogPrintln(array,A_LineFile "(" A_LineNumber ")" " : " "array >>> `r`n") 39 | 40 | array[3] := "New" 41 | 42 | content := jf.store(array) 43 | 44 | LogPrintln(content,A_LineFile "(" A_LineNumber ")" " : " "content >>> `r`n") 45 | 46 | 47 | 48 | 49 | #If WinActive(A_ScriptName) 50 | ;可以按下Alt+L查看最近运行的行 51 | 52 | /* 53 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 54 | ListLines 55 | return 56 | 57 | !^h:: 58 | KeyHistory 59 | return 60 | 61 | !a:: 62 | send,{F5} 63 | return 64 | 65 | !^s:: 66 | ListVars 67 | return 68 | */ 69 | 70 | 71 | #If 72 | 73 | 74 | !q:: 75 | ExitApp 76 | return 77 | 78 | +!q:: 79 | Pause 80 | return 81 | -------------------------------------------------------------------------------- /GUI/AutoInputBox.ahk: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | 说明:固定宽度,且自动根据 prompt 换行的InputBox 5 | */ 6 | class AutoInputBox{ 7 | aTextPrefix := "" 8 | deFaultText := ["UseClipBoard"] 9 | AlwaysOnTop := false 10 | ;---------------------------------------------------------------------- 11 | __New(aTitle,aPrompt){ 12 | this.title:=aTitle 13 | this.prompt:=aPrompt 14 | return this 15 | } 16 | ;------------------------------ 17 | SetAlwaysOnTop(aStr){ 18 | Type.assertBoolean(aStr) 19 | return this.AlwaysOnTop := aStr 20 | } 21 | ;------------------------------ 22 | SetDeFaultText(aStr){ 23 | Type.assertStr(aStr) 24 | return this.deFaultText := aStr 25 | } 26 | ;---------------------------------------------------------------------- 27 | start(){ 28 | aTitle:=this.title 29 | aPrompt:=this.prompt 30 | aWeight:=375 31 | 32 | lineStringLength:="标题标题标题标题标题标题标题标题标题标题标题".length() 33 | line:= (aPrompt.length()) / lineStringLength 34 | 35 | ahight:=150 + (line*30) 36 | 37 | if (IsObject(this.deFaultText)){ 38 | theDeFaultText := Clipboard 39 | } 40 | else{ 41 | theDeFaultText := this.deFaultText 42 | } 43 | 44 | if(this.AlwaysOnTop){ 45 | Gui + LastFound + OwnDialogs + AlwaysOnTop 46 | } 47 | 48 | InputBox,UserInput,%aTitle%,%aPrompt%,,%aWeight%,%ahight%,,,,,%theDeFaultText% 49 | 50 | if (ErrorLevel=1){ ;必须立即判断,不能有间隔 51 | throwWithSt(_EX.UserCancelled) 52 | } 53 | UserInput:=this.aTextPrefix UserInput ;给用户输入的内容增加前缀 54 | Return UserInput 55 | } 56 | } 57 | ;------class AutoInputBox End 58 | -------------------------------------------------------------------------------- /Docs/_Wins.md: -------------------------------------------------------------------------------- 1 | # _Wins Class 2 | 3 | 1. 是一个**静态类**, 不提供构造器 4 | 2. 主要包含针对多个窗口的各种操作 5 | 6 | 7 | [TOC] 8 | 9 | ## 方法 Method 10 | 11 | ### getIdList(WinTitle,aDetectHiddenWindows:="") 12 | 13 | 获取数组形式窗口ID 14 | 15 | ### Analyze(aWinTitle,aDetectHiddenWindows:="") 16 | 17 | 获取多维数组形式的 _Win.Analyze() 18 | 19 | ### AnalyzeOnMap(aWinTitle,aDetectHiddenWindows:="") 20 | 21 | 获取Map形式的 _Win.Analyze(),Map的key是Id 22 | 23 | ### AnalyzeByPath(aWinPath,aDetectHiddenWindows:="") 24 | 25 | 通过路径 _Wins.Analyze() 26 | 27 | #### 返回 Returns: 28 | Obj 或者 false 29 | 30 | - 如果窗口不存在,那么就返回 `false` 31 | 32 | - 包含以下 Key 33 | 34 | ```autohotkey 35 | WinTitle := "WinTitle: " WinTitle 36 | WinClass := "ahk_class " WinClass 37 | Winexe := "ahk_exe " Winexe 38 | WinPId := "ahk_id " WinId 39 | WinPath := "WinPath: " WinPath 40 | ``` 41 | 42 | #### 示例 Example 43 | ```autohotkey 44 | Obj:=_Win.Analyze(WinTitle) 45 | ``` 46 | 47 | ### getIdByPath(aWinPath,aDetectHiddenWindows:="") 48 | 49 | 通过路径获取窗口ID 50 | 51 | ### SwapDetectHidden() 52 | 53 | 环保型“窗口隐藏设置”切换 54 | 55 | - 用于切换 `A_DetectHiddenWindows` 56 | - **那为什么不直接切换呢?** 57 | - 主要是可以实现:在某个方法中切换,但是不污染环境。也就是说方法执行完之后又改回原来的。 58 | - **那具体怎么操作呢?** 59 | - 需要在方法的头部和尾部分别使用两个语句。代码在后面的示例中有贴。 60 | 61 | ```autohotkey 62 | ;SwapDetectHidden()使用案例 63 | /* 64 | 获取窗口ID(HWND)列表收集器(数组形式) 65 | */ 66 | WinGetList(WinTitle,aDetectHiddenWindows:=""){ 67 | 68 | ;头 69 | aFuncId:=getFuncId(A_ThisFunc) 70 | _Win.SwapDetectHidden(aFuncId,aDetectHiddenWindows) 71 | 72 | ;.................... 73 | 74 | ;尾 _Win.SwapDetectHidden(aFuncId,aDetectHiddenWindows) 75 | 76 | return ... 77 | } 78 | 79 | ``` 80 | 81 | -------------------------------------------------------------------------------- /Docs/Switcher.md: -------------------------------------------------------------------------------- 1 | # Switcher Class 2 | 3 | 1. 性质:静态类、实例类 4 | 2. 开发目的:为软件提供切换快捷键 5 | 6 | ## 域 Field 7 | 8 | ### static Options := "Max" 9 | 10 | Run命令的Options,默认是"Max",也就是以最大化窗口形式运行。 11 | 12 | ## 方法 Method 13 | 14 | ### switch(aWinTitle,aPathOrFuncObj,aWait = 0,winPath:="") 15 | 16 | **切换窗口(软件)** 17 | 18 | 算法如下: 19 | 20 | 如果窗口存在{ 21 | 22 | ​ 如果窗口处于激活状态 23 | 24 | ​ 最小化 25 | 26 | ​ 否则,如果窗口未处于激活状态 27 | 28 | ​ 激活 29 | 30 | } 31 | 32 | 否则,如果窗口不存在{ 33 | 34 | ​ 以最大化窗口形式运行软件 35 | 36 | } 37 | 38 | 返回 winExist(aWinTitle) 39 | 40 | #### 参数 Parameters: 41 | 42 | - aWinTitle - 窗口的title 43 | - aPathOrFuncObj - 路径或者方法 44 | 如果是路径,则以最大化形式Run;否则,如果是方法,则直接运行方法 45 | - aWait - 最长等待时间。当程序窗口不存在的时候,会运行程序。当运行命令下达后,如果aWait不为零,则线程等待程序窗口存在后再运行。aWait为最长等待时间,默认参数为0,也就是不等待。 46 | 47 | #### 返回 Returns: 48 | 49 | 如果是路径,则以最大化形式Run命令的 OutputVarPID 变量;否则,如果是方法,则返回方法的结果。 50 | 51 | #### 抛出异常 Throws: 52 | 53 | - null 54 | 55 | #### 示例 Example 56 | 57 | ```autohotkey 58 | Switcher.switch("ahk_exe SourceTree.exe","C:\Users\Administrator\AppData\Local\SourceTree\app-3.1.2\SourceTree.exe") 59 | ``` 60 | 61 | ### toggle(aWinTitle,winPath:="") 62 | 63 | **切换窗口(软件)** 64 | 65 | 算法如下: 66 | 67 | 如果窗口存在{ 68 | 69 | ​ 如果窗口处于激活状态 70 | 71 | ​ 最小化 72 | 73 | ​ 否则,如果窗口未处于激活状态 74 | 75 | ​ 激活 76 | 77 | } 78 | 79 | 返回 winExist(aWinTitle) 80 | 81 | #### 参数 Parameters: 82 | 83 | - aWinTitle - 窗口的title 84 | 85 | #### 返回 Returns: 86 | 87 | null 88 | 89 | #### 抛出异常 Throws: 90 | 91 | - null 92 | 93 | #### 示例 Example 94 | 95 | ```autohotkey 96 | Switcher.toggle("ahk_exe SourceTree.exe","C:\Users\Administrator\AppData\Local\SourceTree\app-3.1.2\SourceTree.exe") 97 | ``` 98 | 99 | -------------------------------------------------------------------------------- /Core/_EX.ahk: -------------------------------------------------------------------------------- 1 | /*! 2 | Class: _EX 3 | 提供各种常见 Exception Message 字符串。 4 | 5 | 6 | Author: 7 | BeanLib 8 | 9 | https://www.kancloud.cn/xrvu_zen/ahk_lib/902301 10 | https://github.com/Oilj/BeanLib 11 | https://gitee.com/xrvu_zen/BeanLib 12 | 13 | License: 14 | LGPLv3 15 | 16 | */ 17 | 18 | ;~ Protect(_EX) 19 | 20 | Class _EX{ 21 | 22 | isRuntimeException(ex){ 23 | return (ex.Message = 1) 24 | } 25 | 26 | static IndexOutOfBounds := "Index Out Of Bounds.数组越界" 27 | ,NoExistVariate := "Variate is not Exsit.变量不存在" 28 | ,NoExistKey := "Key-Value is not Exsit. Key-Value不存在" 29 | ,NoExistMethod := "Call To Nonexistent Method.调用不存在的方法" 30 | ,NoExistFunctionName := "No Exist FunctionName.不存在的函数名" 31 | ,NoExistFile := "File is Not Exist.文件不存在" 32 | ,ExistFile := "File is Exist.文件已存在" 33 | ,NoExistWin := "Win is Not Exist.窗口不存在" 34 | ,ShownWin := "Win is Shown.窗口已经显示" 35 | ,getWinHwndFailed := "Get Win Hwnd Failed.获取窗口句柄失败" 36 | ,getControlHwndFailed := "Get Control Hwnd Failed.获取控件句柄失败" 37 | ,SetConst := "Set Const.写入常量" 38 | ,TooFewParas := "Too Few ParaMeters.参数过少" 39 | ,TooManyParas := "Too Many ParaMeters.参数过多" 40 | ,InvalidPara := "Invalid Para 无效参数" 41 | ,ParaIsEmpty := "Para Is Empty 参数为空" 42 | ,Assert := "Assert! 断言! " 43 | ,MoveFailed := "MoveFailed 文件移动失败" 44 | ,NotOverride := "theObj in Class is Not Override 类中对象未被复写" 45 | ,SingletonClass := "Instance Singleton Class 实例化单例类" 46 | ,UnknownType := "Unknown Type 未知类型" 47 | ,TypeError := "Type Error 类型错误" 48 | ,UserCancelled := "User cancelled 用户已取消" 49 | ,AccObjectException := "ACC object exception ACC 对象异常" 50 | ,CopyFail := "CopyFail 复制失败" 51 | ,DeserializationFailed := "Deserialization failed 反序列化失败" 52 | ,RetryFail := "Retry fail 重试失败" 53 | 54 | } 55 | 56 | /*! 57 | End of class 58 | */ 59 | -------------------------------------------------------------------------------- /Test/LibTest_accDoDefaultAction().ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | 23 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 24 | 25 | theWinTitle := "Sourcetree ahk_exe SourceTree.exe",theHWnd := "" 26 | WinGet, theHWnd, ID , %theWinTitle% 27 | theWinObj := _Win.Analyze("ahk_id " theHWnd) 28 | LogPrintln(theWinObj,A_LineFile "(" A_LineNumber ")" " : " "theWinObj >>> `r`n") 29 | 30 | theAccObj := AccWrapper.ObjectFromWindow(theHWnd, theIdObject := 0) 31 | 32 | theAccObj := theAccObj.ObjectFromPath("4.2.1.2.2.8") 33 | 34 | LogPrintln(theAccObj.Analyze(),A_LineFile "(" A_LineNumber ")" " : " "theAccObj.Analyze() >>> `r`n") 35 | 36 | vChildId := 0 37 | 38 | Insert:: 39 | result := theAccObj.getDefaultActionText(vChildId) 40 | returnValue := theAccObj.doDefaultAction(vChildId) 41 | LogPrintln(result,A_LineFile "(" A_LineNumber ")" " : " "result >>> `r`n") 42 | LogPrintln(returnValue,A_LineFile "(" A_LineNumber ")" " : " "returnValue >>> `r`n") 43 | return 44 | 45 | #If WinActive(A_ScriptName) 46 | ;可以按下Alt+L查看最近运行的行 47 | 48 | /* 49 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 50 | ListLines 51 | return 52 | 53 | !^h:: 54 | KeyHistory 55 | return 56 | 57 | !a:: 58 | send,{F5} 59 | return 60 | 61 | !^s:: 62 | ListVars 63 | return 64 | */ 65 | 66 | 67 | #If 68 | 69 | 70 | !q:: 71 | ExitApp 72 | return 73 | 74 | +!q:: 75 | Pause 76 | return 77 | -------------------------------------------------------------------------------- /Test/LibTest_InvisibleCharacter.count(aStr).ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | 23 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 24 | 25 | LogPrintln(toString(InvisibleCharacter.List),A_LineFile "(" A_LineNumber ")" " : " "toString(InvisibleCharacter.List) >>> `r`n") 26 | 27 | theCount := InvisibleCharacter.count(toString(InvisibleCharacter.List)) 28 | 29 | LogPrintln(theCount,A_LineFile "(" A_LineNumber ")" " : " "theCount >>> `r`n") 30 | 31 | LogPrintln(InvisibleCharacter.List.Length(),A_LineFile "(" A_LineNumber ")" " : " "InvisibleCharacter.List.Length() >>> `r`n") 32 | 33 | /* 34 | A_ScriptName >>> LibTest_InvisibleCharacter.count(aStr).ahk 35 | D:\AHKs\ahk_lib\Test\LibTest_InvisibleCharacter.count(aStr).ahk(25) : toString(InvisibleCharacter.List) >>> 36 | [​,‌,‍,‎,‏,‪,‫,‬,‭,‮,⁦,⁧,⁨,⁩,,۬] 37 | D:\AHKs\ahk_lib\Test\LibTest_InvisibleCharacter.count(aStr).ahk(29) : theCount >>> 38 | 16 39 | D:\AHKs\ahk_lib\Test\LibTest_InvisibleCharacter.count(aStr).ahk(31) : InvisibleCharacter.List.Length() >>> 40 | 16 41 | */ 42 | 43 | #If WinActive(A_ScriptName) 44 | ;可以按下Alt+L查看最近运行的行 45 | 46 | /* 47 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 48 | ListLines 49 | return 50 | 51 | !^h:: 52 | KeyHistory 53 | return 54 | 55 | !a:: 56 | send,{F5} 57 | return 58 | 59 | !^s:: 60 | ListVars 61 | return 62 | */ 63 | 64 | 65 | #If 66 | 67 | 68 | !q:: 69 | ExitApp 70 | return 71 | 72 | +!q:: 73 | Pause 74 | return 75 | -------------------------------------------------------------------------------- /Core/InvisibleCharacter.ahk: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 说明:用于处理不可见字符,不确定所列出的不可见字符是否完全,感觉已经覆盖了绝大多数情况 4 | */ 5 | 6 | 7 | 8 | class InvisibleCharacter{ 9 | static CodeList := [0x200b,0x0200c,0x0200d,0x0200e,0x200f 10 | ,0x202a,0x202b,0x202c,0x202d,0x202e 11 | ,0x2066,0x2067,0x2068,0x2069 12 | ,0xfeff 13 | ,0x06ec] 14 | ,List_Base := "" 15 | 16 | clear(aStr){ 17 | Type.assertStr(aStr) 18 | theNewStr := RegExReplace(aStr, InvisibleCharacter.Regex , Replacement := "") 19 | return theNewStr 20 | } 21 | 22 | Regex[] 23 | { 24 | get { 25 | theRegex := "m)(*ANYCRLF)[" 26 | 27 | for i,Chr in InvisibleCharacter.List { 28 | if(i = InvisibleCharacter.List.Length()) 29 | theRegex .= Chr "]" 30 | else 31 | theRegex .= Chr "|" 32 | } 33 | return theRegex 34 | } 35 | set { 36 | return 37 | } 38 | } 39 | 40 | List[] 41 | { 42 | get { 43 | if(InvisibleCharacter.List_Base = ""){ 44 | TheCharList := [],theCodeList := InvisibleCharacter.CodeList 45 | for i,v in theCodeList { 46 | TheCharList[i] := Chr(v) 47 | } 48 | InvisibleCharacter.List_Base := TheCharList 49 | } 50 | return InvisibleCharacter.List_Base 51 | } 52 | set { 53 | return 54 | } 55 | } 56 | 57 | count(aStr){ 58 | Type.assertStr(aStr) 59 | theCount := 0 60 | theStrArray := StrSplit(aStr) 61 | for i,char in theStrArray { 62 | if(_Container.Contains(InvisibleCharacter.List,char)){ 63 | theCount++ 64 | } 65 | } 66 | return theCount 67 | } 68 | 69 | contain(aStr){ 70 | Type.assertStr(aStr) 71 | theCount := 0 72 | theStrArray := StrSplit(aStr) 73 | for i,char in theStrArray { 74 | if(_Container.Contains(InvisibleCharacter.List,char)){ 75 | return true 76 | } 77 | } 78 | return false 79 | } 80 | 81 | } ;---------class InvisibleCharacter End 82 | -------------------------------------------------------------------------------- /GUI/_GUI.ahk: -------------------------------------------------------------------------------- 1 | 2 | class _GUI{ ;对GUI进行操作的静态类 3 | static c := new _GUI.c_base() 4 | ;SubCommand 5 | class c_base{ 6 | __Call(SubCommand,hwndOrName){ 7 | return hwndOrName ":" SubCommand 8 | } 9 | } ;---------class c End 10 | 11 | static t := new _GUI.t_base() 12 | ;WinTitle 13 | class t_base{ 14 | __Call(Prefix,content){ 15 | return Prefix " " content 16 | } 17 | } ;---------class c End 18 | ;------------------------------ 19 | 20 | ; **** AddAnimatedGIF function by boiler **** 21 | ; imagefullpath: must be the full path to the animated GIF image file 22 | ; x, y: optional strings containing position info that would normally follow x and y options, such as 10, "p+3", "m" 23 | ; w, h: optional width and height values that would normally follow w and h options; blank for full size image 24 | ; guiname: optional name of the gui to add the image to if not the main one 25 | ; 26 | ; function returns the name of the control that was added so that you can modify it (move, hide) with GuiControl 27 | ; can add up to animated GIF images. to increase the limit, add AG11,AG12,... to the global statement 28 | ; 29 | AddAnimatedGIF(imagefullpath , x="", y="", w="", h="", guiname = "1"){ 30 | global AG1,AG2,AG3,AG4,AG5,AG6,AG7,AG8,AG9,AG10 31 | static AGcount:=0, pic 32 | AGcount++ 33 | html := "" 34 | Gui, AnimGifxx:Add, Picture, vpic, %imagefullpath% 35 | GuiControlGet, pic, AnimGifxx:Pos 36 | Gui, AnimGifxx:Destroy 37 | Gui, %guiname%:Add, ActiveX, % (x = "" ? " " : " x" x ) . (y = "" ? " " : " y" y ) . (w = "" ? " w" picW : " w" w ) . (h = "" ? " h" picH : " h" h ) " vAG" AGcount, Shell.Explorer 38 | AG%AGcount%.navigate("about:blank") 39 | AG%AGcount%.document.write(html) 40 | return "AG" AGcount 41 | } 42 | 43 | ;------------------------------ 44 | 45 | } ;---------class GUI End 46 | 47 | -------------------------------------------------------------------------------- /FuncObj/Condition.ahk: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 说明:条件对象 Condition 4 | */ 5 | 6 | ;---------------------------------------------------------------------- 7 | 8 | class Condition{ 9 | check := "" 10 | repair := Bean.false 11 | ;---------------------------------------------------------------------- 12 | 13 | repairName[]{ 14 | get { 15 | theObj := this.repair 16 | if (type.isFuncObj(theObj)){ 17 | return theObj.name 18 | } 19 | else{ 20 | return toString(theObj) 21 | } 22 | } 23 | set { 24 | return False 25 | } 26 | } 27 | ;---------------------------------------------------------------------- 28 | 29 | checkName[]{ 30 | get { 31 | theObj := this.check 32 | if (type.isFuncObj(theObj)){ 33 | return theObj.name 34 | } 35 | else{ 36 | return "*NotFunc*:"toString(theObj) 37 | } 38 | } 39 | set { 40 | return False 41 | } 42 | } 43 | 44 | ;---------------------------------------------------------------------- 45 | 46 | toString(){ 47 | 48 | theCheckName := _toString.funcObj(this.Check) 49 | theRepairName := _toString.funcObj(this.Repair) 50 | 51 | theClassName := this.__Class 52 | resultString = {Type:%theClassName%,check:%theCheckName%,Repair:%theRepairName%} 53 | return resultString 54 | } 55 | ;---------------------------------------------------------------------- 56 | __New(aCheckObj,aRepairObj:=""){ 57 | Bean.assertFunc(aCheckObj) 58 | this.check := aCheckObj 59 | if(aRepairObj!=""){ 60 | Bean.assertFunc(aRepairObj) 61 | this.repair := aRepairObj 62 | } 63 | return this 64 | } 65 | ;---------------------------------------------------------------------- 66 | call(){ 67 | LogPrintln(this.check,"this.check >>>") 68 | checkResult := this.check() 69 | if(checkResult){ 70 | return checkResult 71 | } 72 | else{ 73 | repairResult := this.repair() 74 | } 75 | return repairResult 76 | } 77 | ;---------------------------------------------------------------------- 78 | 79 | } ;---------class Condition End 80 | -------------------------------------------------------------------------------- /Docs/Type.md: -------------------------------------------------------------------------------- 1 | # Type Class 2 | 3 | 1. 是一个**静态类**, 不提供构造器 4 | 2. 围绕着`类型`展开,目前支持 **9种类型** 的识别。另,提供类型的 Code 值,判断类型,断言类型等等。 5 | 3. 用元编程编写,所以这里只写出那些实际会用到的域和方法,大多数平常都用不到。 6 | 4. `Everthing` :代表可以接受任何类型的参数。 7 | 8 | ### 域 Field 9 | 10 | #### 常量 Const 11 | 12 | **如果写入,会 throw _Ex.SetConst** 13 | 14 | ```autohotkey 15 | Static StrEndCode := 19,NumberEndCode := 14 16 | 17 | Static Str:=10,NS:=11,Number:=12,Boolean:=13 18 | 19 | Static List:=130 20 | 21 | Static ObjEndCode := 199 22 | Static Obj:=100,Class:=110,FuncObj:=120,Method:=125 23 | 24 | Static FileObj:=150 25 | 26 | Static ComObj:=160 27 | ``` 28 | 29 | #### 变量 Variate 30 | 31 | ```autohotkey 32 | Static Switcher:=true 33 | ;只有当该变量值为 true 这时候,断言才会生效 34 | ``` 35 | ### 方法 Method 36 | 37 | #### ofCode(TypeCode) 38 | 39 | 获取 TypeCode 对应的 TypeString。 40 | 41 | #### assertOn()/assertOff() 42 | 43 | assertOn() - 把变量设为 true ,开启断言 44 | 45 | assertOff() - 把变量设为 false ,关闭断言 46 | 47 | #### is方法(类型判断方法) 48 | 49 | ##### isStr(Everthing) 50 | ##### isNS(Everthing) 51 | ##### isNumber(Everthing) 52 | 53 | 这里的「数字」指的是「非负有理数」。 54 | 55 | ##### isBoolean(Everthing) 56 | 57 | ##### isList(Everthing) 58 | ##### isObj(Everthing) 59 | ##### isClass(Everthing) 60 | ##### isFileObj(Everthing) 61 | ##### isFuncObj(Everthing) 62 | ##### isMethod(Everthing) 63 | ##### isComObj(Everthing) 64 | 65 | #### assert方法(断言方法) 66 | 67 | - assert方法都是**可变参数**,支持检测多个变量。 68 | 69 | - **类型断言方法是干什么的?** 70 | 比如,你设计一个给字符串数组排序的函数,你肯定不希望传入的参数是 `FuncObj`,由于`AHK`是弱类型,所以不会报任何错误,但是程序可能会有逻辑错误。 71 | 如果预先使用`Type.assertStr(Str)`,就可以避免此类问题,并告知你类型错误的细节。 72 | 73 | ##### assertStr(Everthing*) 74 | ##### assertNS(Everthing*) 75 | ##### assertNumber(Everthing*) 76 | 77 | ##### assertBoolean(Everthing*) 78 | 79 | ##### assertList(Everthing*) 80 | ##### assertObj(Everthing*) 81 | ##### assertClass(Everthing*) 82 | ##### assertFileObj(Everthing*) 83 | ##### assertFuncObj(Everthing*) 84 | ##### assertMethod(Everthing*) 85 | ##### assertComObj(Everthing*) 86 | 87 | #### ofCode(Type.List) 88 | 89 | 通过TypeCode反向查类型值 -------------------------------------------------------------------------------- /Docs/BeanLib_FQA.md: -------------------------------------------------------------------------------- 1 | # 常见问题(FAQ) 2 | 3 | ## 目录 4 | 5 | [TOC] 6 | 7 | ## 这个Lib的作用是什么? 8 | 9 | 为AHK补足基础功能。 10 | 11 | > AHK 没有官方自带或者第三方实现的完善的标准库,这样如果需要实现非内置的功能通常需要直接调用 Windows API 或寻找别人封装好的函数。AHK 语言本身并不强大,缺少很多现代语言所具备的高级特性,同时也缺乏对多线程等操作系统特性的支持。[-- 陌辞寒](https://segmentfault.com/a/1190000005006771) 12 | 13 | ### 为什么不叫标准库 stdlib ? 14 | 15 | 因为已经有叫这个名字了,还不止一个。 16 | 17 | ## 更多介绍一下"中心式导入"? 18 | 19 | ### BeanLib使用要求 20 | 21 | 将所有"子Lib"导入某脚本。 22 | 23 | "子Lib"指的是除了"BeanLib.ahk"之外的所有该项目下的 .ahk 文件。 24 | 25 | #### 为什么是 除了"BeanLib.ahk"之外 ? 26 | 27 | BeanLib.ahk 是"中心式导入" 的示例文件,你可以使用其中的固定地址,也可以自定义,并不是必须的。 28 | 29 | ### "中心式导入"具体是什么意思? 30 | 31 | 为了导入整个Lib库,先把所有"子Lib"导入一个"中心式"Lib文件。 32 | 33 | 其他想引用Lib的脚本,只需要导入"中心式"文件即可。 34 | 35 | 这样后期维护起来会非常的方便。 36 | 37 | ### 如果想使用"中心式导入",又无法使用示例中的地址该怎么办? 38 | 39 | Clone Git 之后,你可以建立一个属于自己的"中心式"Lib文件,然后将它添加到Git的忽略列表中。 40 | 41 | 这个方法的缺点在于,如果 "子Lib" 的结构有改变,你需要手动更改自己的"中心式"Lib文件。 42 | 43 | 其实一般不会有什么问题,Pull 的时候只要留意一下,是否有大的改动就可以了。 44 | 45 | ### 除了"中心式导入",还有没有其他的导入方法? 46 | 47 | 具体参考,AHK帮助文档里面会有非常多的介绍。 48 | 这里还有几点建议,供您参考。 49 | - 最好不要使用"自动入库"。因为这种方法只会在"显式调用"的时候生效,也就是无法动态引用,可能会造成很多兼容性问题。 50 | - 优先考虑使用"相对路径"。"绝对路径"会让后期维护非常麻烦。 51 | 52 | ## 为什么三个平台内容不一样? 53 | 54 | 看云 是最优先更新的平台,因为对文档展示的兼容性最好,支持搜索。 55 | 56 | 在源代码没有更改的情况下,[GitEE](https://gitee.com/xrvu_zen/BeanLib) 和 [GitHub](https://github.com/Oilj/BeanLib) 都不会更新。 57 | 58 | 所以当内容不一致时,以 [看云](https://www.kancloud.cn/xrvu_zen/ahk_lib/902301) 为准。 59 | 60 | ## 为什么函数失效了? 61 | 62 | - 检查类是否被覆盖。 63 | AHK中类是对象,直接加载到全局空间,所以类是可以被覆盖的。为了避免这一情况,BeanLib类都以"_"开头。可以开启 `#Warn ClassOverwrite` ,当类被覆盖时,将会收到提示。 64 | 65 | - 检查是否开启强制Local。 66 | - Class 默认为"强制全局",但如果函数体的第一行是Local,那么 Class 的"强制全局"会失效。 67 | 您可以取消Local,或者在Local后声明 Class 为全局,格式为 `Global ClassName`。 68 | - 如果您开启Local是为了避免收到 LocalListmeGlobal 警告,那么也可以单独关闭该警告。 69 | 在`#Warn`后方添加,`#Warn LocalSameAsGlobal, Off`,即可。 70 | 71 | - 检查输入值/返回值。 72 | 73 | AHK语法灵活,没有类型,所以输入值容易出错,请检查输入是否符合要求。 74 | 如果您期待函数返回一个值,请检查该函数是否的确应当返回该值,很多时候函数只是对传入的地址中的数据进行操作,并不返回值。(尤其是传入参数为 ByRef 或者为 数组 时。) 75 | 76 | - BUG。 77 | 还有一种可能,就是程序设计出现了BUG。 78 | 您可以在对应文档下方评论留言,提交issue,或者 Pull Request。 79 | -------------------------------------------------------------------------------- /Test/LibTest__Acc.ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | 24 | theWinTitle := "D:\MyDocs\重要文档\iThoughts思维导图\突发任务.itmz",theHWnd := "" 25 | WinGet, theHWnd, ID , %theWinTitle% 26 | theWinObj := _Win.Analyze("ahk_id " theHWnd) 27 | LogPrintln(theWinObj,A_LineFile "(" A_LineNumber ")" " : " "theWinObj >>> `r`n") 28 | 29 | theAccObj := Acc_ObjectFromWindow(theHWnd, theIdObject := 0) 30 | 31 | LogPrintln(_Acc.Analyze(theAccObj),A_LineFile "(" A_LineNumber ")" " : " "_Acc.Analyze(theAccObj) >>> `r`n") 32 | 33 | thePath := "4.1.3" 34 | 35 | theAccObj := _Acc.ObjectFromPath(theAccObj,thePath) 36 | 37 | LogPrintln(_Acc.Analyze(theAccObj),A_LineFile "(" A_LineNumber ")" " : " "_Acc.Analyze(theAccObj) >>> `r`n") 38 | 39 | PrintScreen:: 40 | result := theAccObj.accDefaultAction(vChildId) 41 | LogPrintln(_Acc.Analyze(theAccObj),A_LineFile "(" A_LineNumber ")" " : " "_Acc.Analyze(theAccObj) >>> `r`n") 42 | theAccObj.accDoDefaultAction(vChildId) 43 | LogPrintln(result,A_LineFile "(" A_LineNumber ")" " : " "result >>> `r`n") 44 | return 45 | 46 | ;------------------------------ 47 | 48 | 49 | ^PrintScreen:: 50 | theResult := _Acc.AnalyzeFromPoint(vChildId) 51 | LogPrintln(theResult,A_LineFile "(" A_LineNumber ")" " : " "theResult >>> `r`n") 52 | return 53 | 54 | 55 | #If WinActive(A_ScriptName) 56 | ;可以按下Alt+L查看最近运行的行 57 | 58 | /* 59 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 60 | ListLines 61 | return 62 | 63 | !^h:: 64 | KeyHistory 65 | return 66 | 67 | !a:: 68 | send,{F5} 69 | return 70 | 71 | !^s:: 72 | ListVars 73 | return 74 | */ 75 | 76 | 77 | #If 78 | 79 | 80 | !q:: 81 | ExitApp 82 | return 83 | 84 | +!q:: 85 | Pause 86 | return 87 | -------------------------------------------------------------------------------- /APP/AutoClassify.ahk: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | 说明:文件自动分类(依赖 Everything Class) 5 | */ 6 | class AutoClassify{ 7 | sSearchCriteria:=[""],sDestPattern:="",searchResultList:="",EverthingObj:="" 8 | sCheckIntervalMsec:=0.5 9 | ;---------------------------------------------------------------------- 10 | __New(sSearchCriteria,sDestPattern){ 11 | this.sSearchCriteria:=sSearchCriteria 12 | this.sDestPattern:=sDestPattern 13 | this.BuildSearchObj() 14 | return this 15 | } 16 | ;--------------------------------------------------------------------- 17 | BuildSearchObj(){ 18 | this.EverthingObj:=new Everything() 19 | this.EverthingObj.Setkey(this.sSearchCriteria) 20 | return 21 | } 22 | ;---------------------------------------------------------------------- 23 | Search(){ 24 | this.EverthingObj.Setkey(this.sSearchCriteria) 25 | this.EverthingObj.Search() 26 | this.searchResultList:=this.EverthingObj.getSearchResultList() 27 | return 28 | } 29 | ;---------------------------------------------------------------------- 30 | remove(){ 31 | try{ 32 | Counter:=bulkMoveFile(this.searchResultList,this.sDestPattern) 33 | } 34 | 35 | catch,ex{ 36 | LogPrintln(ex,A_LineFile "(" A_LineNumber ")" " : " "ex >>> `r`n") 37 | theMes := "移动失败:" ex.Message 38 | firstPara = 提醒 39 | secondPara = %theMes% 40 | theMesToast := new MesToast(firstPara,secondPara),theMesToast.show() 41 | return 42 | } 43 | 44 | 45 | if(Counter){ 46 | firstPara = %A_ScriptName% 提醒 47 | secondPara = 移动完毕!共移动%Counter%个文件. 48 | theMesToast := new MesToast(firstPara,secondPara),theMesToast.show() 49 | } 50 | return 51 | } 52 | ;---------------------------------------------------------------------- 53 | SearchAndRemove(){ 54 | this.Search() 55 | this.remove() 56 | return 57 | } 58 | ;---------------------------------------------------------------------- 59 | SetTimer(sCheckIntervalMsec){ 60 | FuncObj:=this.SearchAndRemove.Bind(this) 61 | this.sCheckIntervalMsec:=sCheckIntervalMsec 62 | theTimer := new Timer(FuncObj,this.sCheckIntervalMsec),theTimer.set() 63 | return 64 | } 65 | } 66 | ;AppLocker Class End 67 | -------------------------------------------------------------------------------- /Test/TPDD_getSourceTreeAccWrapper.ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | 23 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 24 | 25 | theWinTitle := "Sourcetree ahk_exe SourceTree.exe",theHWnd := "" 26 | WinGet, theHWnd, ID , %theWinTitle% 27 | theWinObj := _Win.Analyze("ahk_id " theHWnd) 28 | LogPrintln(theWinObj,A_LineFile "(" A_LineNumber ")" " : " "theWinObj >>> `r`n") 29 | 30 | theAccObj := AccWrapper.ObjectFromWindow(theHWnd, theIdObject := 0) 31 | LogPrintln(theAccObj,A_LineFile "(" A_LineNumber ")" " : " "theAccObj >>> `r`n") 32 | 33 | 标签 := "4.2.1.1.1.15" 34 | 35 | 36 | theAccObj := theAccObj.ObjectFromPath(标签) 37 | 38 | LogPrintln(theAccObj,A_LineFile "(" A_LineNumber ")" " : " "theAccObj >>> `r`n") 39 | 40 | vChildId := 0 41 | 42 | Insert:: 43 | theAnalyzeObj := theAccObj.Analyze() 44 | LogPrintln(theAnalyzeObj,A_LineFile "(" A_LineNumber ")" " : " "theAnalyzeObj >>> `r`n") 45 | result := theAccObj.get().accDefaultAction(vChildId) 46 | name := theAccObj.get().accName(vChildId) 47 | LogPrintln(result,A_LineFile "(" A_LineNumber ")" " : " "result >>> `r`n") 48 | LogPrintln(name,A_LineFile "(" A_LineNumber ")" " : " "name >>> `r`n") 49 | returnValue := theAccObj.get().accDoDefaultAction(vChildId) 50 | LogPrintln(returnValue,A_LineFile "(" A_LineNumber ")" " : " "returnValue >>> `r`n") 51 | return 52 | 53 | #If WinActive(A_ScriptName) 54 | ;可以按下Alt+L查看最近运行的行 55 | 56 | /* 57 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 58 | ListLines 59 | return 60 | 61 | !^h:: 62 | KeyHistory 63 | return 64 | 65 | !a:: 66 | send,{F5} 67 | return 68 | 69 | !^s:: 70 | ListVars 71 | return 72 | */ 73 | 74 | 75 | #If 76 | 77 | 78 | !q:: 79 | ExitApp 80 | return 81 | 82 | +!q:: 83 | Pause 84 | return 85 | -------------------------------------------------------------------------------- /Test/LibTest_InvisibleCharacter.clear(aStr).ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | 23 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 24 | 25 | theNewStr := RandomStr() "`r`n" RandomStr() "`r`n" RandomStr() "`r`n" RandomStr() "`r`n" 26 | 27 | LogPrintln(theNewStr.Length(),A_LineFile "(" A_LineNumber ")" " : " "theNewStr.Length() >>> `r`n") 28 | LogPrintln(theNewStr,A_LineFile "(" A_LineNumber ")" " : " "theNewStr >>> `r`n") 29 | 30 | for i,Chr in InvisibleCharacter.List { 31 | Random,insertIndex,1,% theNewStr.length() 32 | theNewStr := theNewStr.Insert(Chr,insertIndex) 33 | } 34 | 35 | LogPrintln(theNewStr.Length(),A_LineFile "(" A_LineNumber ")" " : " "theNewStr.Length() >>> `r`n") 36 | LogPrintln(theNewStr,A_LineFile "(" A_LineNumber ")" " : " "theNewStr >>> `r`n") 37 | 38 | theRegex := InvisibleCharacter.Regex 39 | 40 | LogPrintln(theRegex,A_LineFile "(" A_LineNumber ")" " : " "theRegex >>> `r`n") 41 | LogPrintln(InvisibleCharacter.count(theNewStr),A_LineFile "(" A_LineNumber ")" " : " "InvisibleCharacter.count(theNewStr) >>> `r`n") 42 | 43 | theNewStr := InvisibleCharacter.clear(theNewStr) 44 | 45 | LogPrintln(theNewStr,A_LineFile "(" A_LineNumber ")" " : " "theNewStr >>> `r`n") 46 | 47 | LogPrintln(InvisibleCharacter.count(theNewStr),A_LineFile "(" A_LineNumber ")" " : " "InvisibleCharacter.count(theNewStr) >>> `r`n") 48 | 49 | #If WinActive(A_ScriptName) 50 | ;可以按下Alt+L查看最近运行的行 51 | 52 | /* 53 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 54 | ListLines 55 | return 56 | 57 | !^h:: 58 | KeyHistory 59 | return 60 | 61 | !a:: 62 | send,{F5} 63 | return 64 | 65 | !^s:: 66 | ListVars 67 | return 68 | */ 69 | 70 | 71 | #If 72 | 73 | 74 | !q:: 75 | ExitApp 76 | return 77 | 78 | +!q:: 79 | Pause 80 | return 81 | -------------------------------------------------------------------------------- /Docs/Everything.md: -------------------------------------------------------------------------------- 1 | # Everything Class 2 | 3 | 使用 Everything 进行搜索 4 | 5 | - Everything 是一款非常出名的搜索工具,搜索速度极快 6 | - 使用条件 1.根目录或指定目录下存在 Everything的DLL 2.Everything程序正在运行 7 | - 根目录指的是`A_ScriptDir`,并不是`BeanLib`所在的根目录。 8 | - DLL 概不提供 自己从 Everything 中提取,或者直接指定本机 Everything 目录。 9 | - 提取自 RunAny - 一劳永逸的快速启动 @hui-Zz,主要改动如下 10 | - 精简方法名 11 | - 调用 __New 时直接获取 Dll 信息,检查 Everything 窗口是否存在 12 | 13 | ## 域 Field 14 | 15 | - key:="" 16 | - MatchWholeWord:=false 17 | - DLL:=false 18 | 19 | 20 | ## 方法 Method 21 | 22 | ### __New(DLLPath:="") 23 | 24 | 构造一个 Everything 对象 25 | 26 | - 会通过 getDll() 检查 Dll 文件是否存在,如果不存在 `throwWithSt("Not Found Everything.DLL/Everything64.DLL.")` 27 | - 会检查 `ahk_exe Everything.exe`是否存在,如果不存在`throwWithSt("ahk_exe Everything.exe is not Exist.")` 28 | 29 | ### getDll(DLLPath:="") 30 | 31 | 确认Everything的DLL是否存在 32 | 33 | - 如果存在,返回名称,不存在则返回 false 34 | 35 | ### SetKey(aValue) 36 | 37 | 设置搜索关键词 38 | 39 | return null 40 | 41 | ### SetMatchWholeWord(aValue) 42 | 43 | 设置是否全字匹配 44 | 45 | return null 46 | 47 | ### Search(aValue=1) 48 | 49 | 执行搜索动作 (执行后直接返回匹配数) 50 | 51 | - aValue - 意义不明,并非必须填写 52 | 53 | return null 54 | 55 | ### Count() 56 | 57 | 返回匹配总数 58 | 59 | ### GetFileName(aValue) 60 | 61 | 返回一个文件名 62 | 63 | - aValue - 文件名Index 64 | 65 | ### GetFullPath(aValue,cValue=128) 66 | 67 | 返回一个文件全路径 68 | 69 | - aValue - 文件路径Index 70 | 71 | ### GetVersionString() 72 | 获取 Everything 版本 (@YuKuan贡献) 73 | 74 | ### getSearchResultList() 75 | 76 | 获取所有结果组成的数组 77 | 78 | ### isEverythingExist() 79 | 80 | 检测 Everything 是否存在 81 | 82 | ### afEverythingExist() 83 | 84 | 断言 Everything 存在 85 | 86 | ## 示例 87 | 88 | ```autohotkey 89 | Obj:=new Everything() 90 | 91 | Obj.Setkey("xxx") 92 | 93 | Obj.Search() 94 | theLen:=Obj.Count() 95 | Str:=Obj.GetFullPath(0) 96 | 97 | StrList:=[] 98 | 99 | loop,%theLen%{ 100 | StrList.push(Obj.GetFullPath(A_Index-1)) 101 | } 102 | 103 | ExitApp 104 | 105 | ``` 106 | 107 | ```autohotkey 108 | Obj:=new Everything() 109 | 110 | thekey="D:\MyDesk" 111 | Obj.Setkey(thekey) 112 | Obj.Search() 113 | 114 | searchResultList:=Obj.getSearchResultList() 115 | ``` -------------------------------------------------------------------------------- /Docs/ObservableObj.md: -------------------------------------------------------------------------------- 1 | # ObservableObj Class 2 | 3 | 1. 性质:静态类/单例类/实例类 4 | 2. 开发目的:带有监听器的 Obj,类似 JavaFX 中的 ObservableValue。 5 | 6 | ## 方法 Method 7 | 8 | ### get() 9 | 10 | 获取Object 11 | 12 | #### 返回 Returns: 13 | 14 | Obj嗯 15 | 16 | ### set(aObj) 17 | 18 | 设置Object 19 | 20 | #### 参数 Parameters: 21 | 22 | - 需要设置的 `Object` 23 | 24 | #### 返回 Returns: 25 | 26 | Obj 27 | 28 | ### addListener(aMethod) 29 | 30 | #### 参数 Parameters: 31 | 32 | - 添加监听器 33 | 监听器的 `aChange` 参数是`observableObj, oldChange, newChange` 34 | 35 | #### 返回 Returns: 36 | 37 | null 38 | 39 | 40 | 41 | ## 示例 Example 42 | 43 | ```autohotkey 44 | theObservableObj := new ObservableObj("FirstString") 45 | theObj := theObservableObj.get() 46 | LogPrintln(theObj,A_LineFile "(" A_LineNumber ")" " : " "theObj >>> `r`n") 47 | theObservableObj.addListener(new Function("callback")) 48 | theObservableObj.addListener(new Function("callback")) 49 | theObservableObj.set("SecondString") 50 | 51 | callback(observableObj, oldChange, newChange){ 52 | LogPrintln(observableObj,A_LineFile "(" A_LineNumber ")" " : " "observableObj >>> `r`n") 53 | LogPrintln(oldChange,A_LineFile "(" A_LineNumber ")" " : " "oldChange >>> `r`n") 54 | LogPrintln(newChange,A_LineFile "(" A_LineNumber ")" " : " "newChange >>> `r`n") 55 | return 56 | } 57 | 58 | ``` 59 | 60 | ```AutoHotKey 61 | D:\AHKs\Dev\TPDD_ObservableObj.ahk(27) : theObj >>> 62 | FirstString 63 | D:\AHKs\Dev\TPDD_ObservableObj.ahk(33) : observableObj >>> 64 | {__Instance:ObservableObj,listenerList:[{__Instance:Function,bindParas:{*Obj*},func:callback()},{__Instance:Function,bindParas:{*Obj*},func:callback()}],Obj:FirstString} 65 | D:\AHKs\Dev\TPDD_ObservableObj.ahk(34) : oldChange >>> 66 | FirstString 67 | D:\AHKs\Dev\TPDD_ObservableObj.ahk(35) : newChange >>> 68 | SecondString 69 | D:\AHKs\Dev\TPDD_ObservableObj.ahk(33) : observableObj >>> 70 | {__Instance:ObservableObj,listenerList:[{__Instance:Function,bindParas:{*Obj*},func:callback()},{__Instance:Function,bindParas:{*Obj*},func:callback()}],Obj:FirstString} 71 | D:\AHKs\Dev\TPDD_ObservableObj.ahk(34) : oldChange >>> 72 | FirstString 73 | D:\AHKs\Dev\TPDD_ObservableObj.ahk(35) : newChange >>> 74 | SecondString 75 | ``` 76 | 77 | -------------------------------------------------------------------------------- /Docs/PathObj.md: -------------------------------------------------------------------------------- 1 | # PathObj Class 2 | 3 | 1. 对路径字符串进行各种操作。完全依赖 `SplitPath` 函数实现。 4 | 2. 对路径的合法性进行检查。依赖正则实现。 5 | 3. [构造方法会自动调用split()生成各种field](### split())。 6 | 7 | PathObj不依赖于真实对象,只要路径是合法的,就能够存在。 8 | 9 | [TOC] 10 | 11 | ## 方法 Method 12 | 13 | ### __New(aPath,aRootPathObj := "") 14 | 15 | 构造路径对象 16 | 17 | ```autohotkey 18 | FullFileName = C:\My Documents\Address List.txt 19 | ;~ FullFileName = C:\My Documents\\Address List.txt 20 | ;~ FullFileName = Address List.txt 21 | ;~ FullFileName = \Address List.txt 22 | 23 | thePathObj:=new PathObj(FullFileName) 24 | 25 | LogPrintln(thePathObj.name,"thePathObj.name >>>") 26 | LogPrintln(thePathObj.dir,"thePathObj.dir >>>") 27 | LogPrintln(thePathObj.ext,"thePathObj.ext >>>") 28 | LogPrintln(thePathObj.name_no_ext,"thePathObj.name_no_ext >>>") 29 | LogPrintln(thePathObj.drive,"thePathObj.drive >>>") 30 | ``` 31 | 32 | #### 参数 ParaMeter 33 | 34 | - aPath - 路径字符串 35 | 支持相对路径和绝对路径 36 | 37 | - aRootPathObj - aPath的根目录PathObj 38 | 如果为空,则未指定根目录 39 | 40 | #### 测试 Test 41 | 42 | 有 43 | 44 | ### replaceName(SearchText,ReplaceText) 45 | 46 | 替换文件名 47 | 48 | 和替换字符串的作用类似,只不过,这个字符串是文件名,替换后文件名会被更改 49 | 50 | ### reName(aName) 51 | 52 | 重命名文件或目录 53 | 54 | 重命名之前会检查,如果是文件则调用`FileMove`命令,否则就调用`FileMoveDir`命令。 55 | 56 | #### 返回值 Return 57 | 58 | if(失败) 59 | 60 | ​ return false 61 | 62 | else 63 | 64 | ​ return 新PathObj 65 | 66 | #### 测试 Test 67 | 68 | 有 69 | 70 | ### getPath() 71 | 72 | 获取路径 73 | 74 | 相对路径在构造方法中会转换为绝对路径存储起来,所以不会随后续的相对路径变化而变化,很好的解决AHK命令式编程,导致出现各种全局变量的问题。 75 | 76 | ### delete() 77 | 78 | 删除文件 79 | 80 | 返回`FileDelete`命令的`ErrorLevel`值 81 | 82 | ### isExist() 83 | 84 | 检测文件是否存在 85 | 86 | ### assertExist() 87 | 88 | 断言文件存在 89 | 90 | ### isFile() 91 | 92 | 检查路径是否为文件 93 | 94 | ### assert() 95 | 96 | 检查路径是否合法 97 | 98 | 默认假设绝对路径,如果发现不合法;那么假设为相对路径,在当前路径的前面加入变量`A_WorkingDir`后再行检查。 99 | 100 | ### split() 101 | 102 | 生成以下 Filed: 103 | 104 | 1. name 105 | 2. dir 106 | 3. ext (扩展名) 107 | 4. name_no_ext 108 | 5. drive 109 | 110 | ### create(aPathList) 111 | 112 | 批量创建`PathObj`,`aPathList`既可以是`List`,也可以是以换行分开的路径`String`。 113 | 114 | 返回`PathOb[]`。 115 | 116 | -------------------------------------------------------------------------------- /Test/LibTest_PathObj.ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | 24 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 25 | 26 | path= 27 | ( 28 | H:\MyLibrary\电子书_计算机\GitHub实践(2016-11).pdf 29 | H:\MyLibrary\电子书_计算机\Git小书(2016-06-23)_刘传君__EA022_文本版.docx 30 | H:\MyLibrary\电子书_计算机\Git权威指南(2011).docx 31 | H:\MyLibrary\电子书_计算机\Git高手之路(2018-04)_自带OCR_2020.8.13_AYOCR.pdf 32 | H:\MyLibrary\电子书_计算机\Git高手之路(2018-04)_自带OCR_2020.8.13_AYOCR.docx 33 | H:\MyLibrary\电子书_计算机\Git团队协作(2017-6)_625005.pdf 34 | H:\MyLibrary\电子书_计算机\Git学习指南(2015-3)_ rené preibel 普莱贝尔 & bjorn stachmann 斯拉赫曼.docx 35 | H:\MyLibrary\电子书_计算机\精通Git(Pro Git)(2017-9)_第2版_中文版_文本版.pdf 36 | H:\MyLibrary\电子书_计算机\JavaScript\Electron\(2017)Electron From Beginner to Pro Learn to Build Cross Platform Desktop Applications using Githubs Electron by Chris Griffith,Leif Wells (auth.) (z-lib.org).pdf 37 | H:\MyLibrary\电子书_计算机\Git团队协作(2017-6)_艾玛·简·霍格宾·韦斯特比__978-7-115-45467-6_文本版.docx 38 | H:\MyLibrary\电子书_计算机\GitHub_漫游指南(2015.3.9)(网络自制书)_Phodal_Huang_漫游指南__文本版.docx 39 | H:\MyLibrary\电子书_计算机\Git版本控制管理(第2版)_[美]乔恩·罗力格(Jon_Loeliger),马修·麦卡洛(Matthew_McCullough)著___文本版.docx 40 | H:\MyLibrary\电子书_计算机\GitHub入门与实践(2015-7)_(图灵程序设计丛书)_[日]大塚弘记__978-7-115-39409-5_文本版.docx 41 | H:\MyLibrary\电子书_计算机\Git权威指南(2011)_第2版.pdf 42 | ) 43 | 44 | theList := PathObj.creat(path) 45 | 46 | for i,v in theList { 47 | LogPrintln(v.name,A_LineFile "(" A_LineNumber ")" " : " "v.name >>> `r`n") 48 | } 49 | 50 | #If WinActive(A_ScriptName) 51 | ;可以按下Alt+L查看最近运行的行 52 | 53 | /* 54 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 55 | ListLines 56 | return 57 | 58 | !^h:: 59 | KeyHistory 60 | return 61 | 62 | !a:: 63 | send,{F5} 64 | return 65 | 66 | !^s:: 67 | ListVars 68 | return 69 | */ 70 | 71 | 72 | #If 73 | 74 | 75 | !q:: 76 | ExitApp 77 | return 78 | 79 | +!q:: 80 | Pause 81 | return 82 | -------------------------------------------------------------------------------- /Docs/_Win.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # _Win Class 4 | 5 | 1. 是一个**静态类**, 不提供构造器 6 | 2. 主要包含针对单个窗口的各种操作 7 | 8 | 9 | [TOC] 10 | 11 | ## 内部类 InnerClass 12 | 13 | ### Path 14 | 15 | Path 类,可以通过及构造方法迅速的获得包含`name`和`path`两种数据的对象。 16 | 17 | 由于ahk不支持通过路径操作窗口,而支持通过进程名(name)操作,所以将它们绑定在一起非常有利于使用。 18 | 19 | 构造方法,从外部直接调用比较麻烦,可读性比较差,可以通过 `_Win.getPathObj() ` 调用。 20 | 21 | - **Method:** 22 | 23 | __New(aPath) 24 | 25 | - **Filed:** 26 | 27 | name:="",path:="" 28 | 29 | ## 域 Field 30 | 31 | ### 常量 Const 32 | 33 | ### 变量 Variate 34 | 35 | ## 方法 Method 36 | 37 | ### Exist(aWinTitle,path="") 38 | 39 | - aWinTitle - 目标窗口的 `WinTitle` 40 | - path - 目标窗口进程 41 | 42 | ### Analyze(aWinTitle,aDetectHiddenWindows:="",EnableWinText:=false,path:="") 43 | 44 | #### 参数 Parameters: 45 | 46 | - aWinTitle - 目标窗口的 `WinTitle` 47 | - aDetectHiddenWindows - 隐藏窗口的检查策略 48 | - EnableWinText - 是否检测 `WinText` 49 | - path - 对结果进行进程路径筛选 50 | 51 | #### 返回 Returns: 52 | Obj 或者 false 53 | 54 | - 如果窗口不存在,那么就返回 `false` 55 | 56 | - 包含以下 Key 57 | 58 | ```autohotkey 59 | { 60 | 61 | WinClass:ahk_class Qt5QWindowIcon 62 | ,Class:Qt5QWindowIcon 63 | 64 | ,WinId:ahk_id 0xc12fc 65 | ,Id:0xc12fc 66 | 67 | ,WinPath:F:\gAPP\VNote\VNote.exe 68 | 69 | ,WinProcessName:ahk_exe VNote.exe 70 | ,ProcessName:VNote.exe 71 | 72 | ,WinTitle:从剪切板中插入图片 73 | } 74 | ``` 75 | 76 | #### 示例 Example 77 | ```autohotkey 78 | Obj:=_Win.Analyze(WinTitle) 79 | ``` 80 | 81 | ### AnalyzeByMousePos() 82 | 83 | 获取当前鼠标位置上的窗口信息 84 | 85 | ### getIdByPath(aWinPath,aDetectHiddenWindows:="") 86 | 87 | 通过路径获取窗口ID 88 | 89 | ### SwapDetectHidden() 90 | 91 | 环保型“窗口隐藏设置”切换 92 | 93 | - 用于切换 `A_DetectHiddenWindows` 94 | - **那为什么不直接切换呢?** 95 | - 主要是可以实现:在某个方法中切换,但是不污染环境。也就是说方法执行完之后又改回原来的。 96 | - **那具体怎么操作呢?** 97 | - 需要在方法的头部和尾部分别使用两个语句。代码在后面的示例中有贴。 98 | 99 | ```autohotkey 100 | ;SwapDetectHidden()使用案例 101 | /* 102 | 获取窗口ID(HWND)列表收集器(数组形式) 103 | */ 104 | WinGetList(WinTitle,aDetectHiddenWindows:=""){ 105 | 106 | ;头 107 | aFuncId:=getFuncId(A_ThisFunc) 108 | _Win.SwapDetectHidden(aFuncId,aDetectHiddenWindows) 109 | 110 | ;.................... 111 | 112 | ;尾 _Win.SwapDetectHidden(aFuncId,aDetectHiddenWindows) 113 | 114 | return ... 115 | } 116 | 117 | ``` 118 | 119 | -------------------------------------------------------------------------------- /Core/Stack.ahk: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Stack{ 4 | list := Array() 5 | maxIndex := "" 6 | isOutOfBounds(aIndex){ 7 | if(this.maxIndex="") 8 | return false 9 | else 10 | return aIndex > this.maxIndex 11 | } 12 | get(){ 13 | return this.list 14 | } 15 | set(aList){ 16 | Type.assertList(aList) 17 | if(this.isOutOfBounds(aList.Length())) 18 | throw(_Ex.IndexOutOfBounds) 19 | return this.list := _List.clone(aList) 20 | } 21 | length(){ 22 | return this.get().length() 23 | } 24 | 25 | __New(aMaxIndex := ""){ 26 | if(aMaxIndex != "") 27 | Type.assertNumber(aMaxIndex) 28 | this.maxIndex := aMaxIndex 29 | } 30 | 31 | empty(){ 32 | if(this.length() = 0) 33 | return true 34 | else 35 | return false 36 | } 37 | 38 | peek(){ 39 | return this.get()[this.length()] 40 | } 41 | class Enum{ 42 | list := "",CurrentIndex := "",lastIndex := 1 43 | ;---------------------------------------------------------------------- 44 | __New(aList){ 45 | this.list := aList 46 | this.CurrentIndex := this.list.length() 47 | this.next:=this.base.next 48 | } 49 | ;---------------------------------------------------------------------- 50 | __Call(methodName,byref v:=""){ 51 | if(methodName = "")or(methodName="next") 52 | return this.next(v) 53 | else 54 | throwWithSt(_Ex.NoExistMethod) 55 | } 56 | ;---------------------------------------------------------------------- 57 | next(byref v:=""){ 58 | if (this.CurrentIndex < this.lastIndex) 59 | return false 60 | else{ 61 | v := this.list[this.CurrentIndex] 62 | this.CurrentIndex-- 63 | return true 64 | } 65 | 66 | } 67 | ;---------------------------------------------------------------------- 68 | } 69 | getEnum(){ 70 | return new Stack.Enum(this.get()) 71 | } 72 | 73 | ;AHK-Array有同名方法 74 | pop(){ 75 | return this.get().pop() 76 | } 77 | Cut(){ 78 | return this.get().RemoveAt(1) 79 | } 80 | push(aElement){ 81 | if(this.isOutOfBounds(this.get().Length())) 82 | this.Cut() 83 | return this.get().push(aElement) 84 | } 85 | 86 | search(aElement){ 87 | thePos := this.get().Length() 88 | while(thePos>0){ 89 | if(aElement = this.get()[thePos]) 90 | return thePos 91 | else 92 | thePos-- 93 | } 94 | return false 95 | } 96 | } ;---------class Stack End -------------------------------------------------------------------------------- /Docs/更新历史(CHANGELOG).md: -------------------------------------------------------------------------------- 1 | # 更新历史(CHANGELOG) 2 | 3 | 下面是 BeanLib 的更新日志 4 | 5 | ## 1.1 - 2019年01月23日 6 | 7 | - 新增 Script 类,支持对于任意 AHK脚本 的各种控制,比如重启/暂停. 8 | - 从该版本开始,将使用标准的 Commit Message 格式 9 | 10 | - v1.1是第一个 BeanLib release 版(正式版) 11 | - release 版大概会每月更新一次 12 | 13 | ## 1.2 - 2019年03月27日 14 | 15 | 1. 增加用于调试的LogPrintln() 16 | 2. 新增函数:getCurrentTime()、SetTimer()、UseCMD() 17 | 3. EverythingClass:修复检测Everything存在性的BUG ;新增 getSearchResultList();新增 isEverythingExist() 、 afEverythingExist() ;增加Everything.GetVersionString()函数,获取Everything软件版本 18 | 4. 新增 AutoClassify 类,文件自动分类器 19 | 5. 新增 APPLocker,一个简单的应用锁 20 | 21 | 22 | ## 1.2.1 - 2019年04月01日 23 | 24 | 1. StringMethod 25 | 26 | - isNumber() - 检测字符串是否为纯数字 27 | - isRegExMatch() - 检测String是否匹配某正则 28 | - 去掉了CharAt 的第二个参数 29 | 30 | 2. "SA"改为"List",放弃"SimpleArray"这种叫法. 31 | 3. _List类新增 Match(list,aRegEx) - 找出数组中所有匹配正则表达式的元素 32 | 4. .fix : 修复APPLocker类中,UnLock与Lock函数名错误问题. 33 | 5. _Ex 增加 TooManyParas , NoExistKey 34 | 6. 新增 ini 类 ,用于批量读取 Ini 内容 35 | 7. 新增 PathObj类 ,可以快速分割路径为 path name ext 等等,并且支持路径合法性检测 36 | 37 | ## 1.3 - 2019年07月08日 38 | 39 | 1. 目录:(1)层级更明确 (2)整齐排序 40 | 2. UMSS :让任何按键变成修饰键的类,代码全面重构,对效率和稳定性进行了大幅优化 41 | 3. HotString类和HotStringMaps类:可以从更接近底层的地方掌控HotString,从而实现各种批量化操作。 42 | 4. .feat : 43 | (1)Contain:增加 DeleteByFunc,根据对象运行的返回值来删除容器元素. 44 | (2)_Ex :增加 InvalidPara 等多个常用异常 45 | (3)FuncTion: 修改SetTimer函数,从接收分钟变成毫秒 46 | (4)StringMethod:为配合(3),加入分钟和秒转毫秒的方法, 47 | 48 | ## 1.3.5 - 2019年07月15日 49 | 50 | 1. WinEvent Class: 51 | 新增「热窗口」(ShellHook)功能 52 | 我们已经有了强大的「热键」和「热字串」,现在我们又有了「热窗口」。 53 | 2. Type: 54 | (1)断言方法支持多参数 (2)加入 Exception 类型 55 | 3. Function 56 | (1)加入堆栈追踪方法 throw() 、throwWithSt() 57 | (2)InstanceCheck (单例类测试工具) 58 | (3)新增InstanceCheck(),主要用于「单例模式」 59 | 4. 新增TimeChecker Class: 60 | (1)用于「检查当前时间是否位于规定范围内」,支持黑、白名单两种检查方 61 | 5. APPLock重构 62 | 使用TimeChecker Class作为新的检查机制 63 | 6. _Ex 64 | 增加关于「单例类重复实例化」的ExceptionMes 65 | 66 | ## 1.3.6 - 2019年07月23日 67 | 68 | 更换 type 类下的所有"af"方法为"assert"方法,功能不变。 69 | 70 | ## 1.3.7 - 2019年11月24日 71 | 72 | .feat 73 | 74 | 1. Method Class:用于替代 Bind() 方法,提供良好的内部可见性,为单独使用方法(Method)提供了便利。 75 | 2. JSON:加入 JSON 字符串读写类和 JsonFile 文件读写类。 76 | 3. RunningSpeedTest Class :用于高精度计时。 77 | 4. 增加了序列化 ObjLoad() 函数 与反序列化 ObjDump() 函数。 78 | 79 | .fix 80 | 81 | 1. UMSS Class:修复只能注册 `Tab` 键的BUG。 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /Test/LibTestAccWrapper.ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | 24 | theWinTitle := "D:\MyDocs\重要文档\iThoughts思维导图\突发任务.itmz",theHWnd := "" 25 | WinGet, theHWnd, ID , %theWinTitle% 26 | theWinObj := _Win.Analyze("ahk_id " theHWnd) 27 | LogPrintln(theWinObj,A_LineFile "(" A_LineNumber ")" " : " "theWinObj >>> `r`n") 28 | 29 | theAccObj := AccWrapper.ObjectFromWindow(theHWnd, theIdObject := 0) 30 | LogPrintln(theAccObj,A_LineFile "(" A_LineNumber ")" " : " "theAccObj >>> `r`n") 31 | 32 | LogPrintln(theAccObj.Analyze(0),A_LineFile "(" A_LineNumber ")" " : " "theAccObj.Analyze(0) >>> `r`n") 33 | 34 | thePath := "4.1.3" 35 | 36 | ;在这里可能生成了错误的ACC对象 37 | theAccObj := theAccObj.ObjectFromPath(thePath) 38 | 39 | 40 | LogPrintln(theAccObj,A_LineFile "(" A_LineNumber ")" " : " "theAccObj >>> `r`n") 41 | 42 | LogPrintln(theAccObj.Analyze(0),A_LineFile "(" A_LineNumber ")" " : " "theAccObj.Analyze(0) >>> `r`n") 43 | 44 | return 45 | 46 | 47 | PrintScreen:: 48 | result := theAccObj.get().accDefaultAction(vChildId) 49 | LogPrintln(theAccObj.Analyze(theAccObj),A_LineFile "(" A_LineNumber ")" " : " "theAccObj.Analyze(theAccObj) >>> `r`n") 50 | theAccObj.get().accDoDefaultAction(vChildId) 51 | LogPrintln(result,A_LineFile "(" A_LineNumber ")" " : " "result >>> `r`n") 52 | return 53 | 54 | ;------------------------------ 55 | 56 | 57 | ^PrintScreen:: 58 | theResult := AccWrapper.AnalyzeFromPoint(vChildId) 59 | LogPrintln(theResult,A_LineFile "(" A_LineNumber ")" " : " "theResult >>> `r`n") 60 | return 61 | 62 | 63 | #If WinActive(A_ScriptName) 64 | ;可以按下Alt+L查看最近运行的行 65 | 66 | /* 67 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 68 | ListLines 69 | return 70 | 71 | !^h:: 72 | KeyHistory 73 | return 74 | 75 | !a:: 76 | send,{F5} 77 | return 78 | 79 | !^s:: 80 | ListVars 81 | return 82 | */ 83 | 84 | 85 | #If 86 | 87 | 88 | !q:: 89 | ExitApp 90 | return 91 | 92 | +!q:: 93 | Pause 94 | return 95 | -------------------------------------------------------------------------------- /GUI/_Wins.ahk: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 说明:主要包含针对多个窗口的各种操作 4 | */ 5 | 6 | 7 | Class _Wins{ 8 | 9 | ;---------------------------------------------------------------------- 10 | /* 11 | 获取Analyze(多维数组形式) 12 | */ 13 | Analyze(aWinTitle,aDetectHiddenWindows:="",path:=""){ 14 | theAnalyzeWins:=[] 15 | theWinList:=_Wins.getIdList(aWinTitle,aDetectHiddenWindows) 16 | for i,v in theWinList { 17 | AnalyzeWinObj:=_Win.Analyze(v,aDetectHiddenWindows,false,path) 18 | theAnalyzeWins.Push(AnalyzeWinObj) 19 | } 20 | return theAnalyzeWins 21 | } 22 | ;------------------------------ 23 | /* 24 | 获取Analyze(多维数组形式) 25 | */ 26 | AnalyzeOnMap(aWinTitle,aDetectHiddenWindows:="",path:=""){ 27 | theAnalyzeWins:=Object() 28 | theWinList:=_Wins.getIdList(aWinTitle,aDetectHiddenWindows) 29 | for i,v in theWinList { 30 | AnalyzeWinObj:=_Win.Analyze(v,aDetectHiddenWindows,false,path) 31 | theAnalyzeWins[AnalyzeWinObj.ID] := AnalyzeWinObj 32 | } 33 | 34 | return theAnalyzeWins 35 | } 36 | 37 | ;---------------------------------------------------------------------- 38 | /* 39 | 获取数组形式窗口ID 40 | */ 41 | getIdList(WinTitle,aDetectHiddenWindows:=""){ 42 | 43 | aFuncId:=getFuncId(A_ThisFunc) 44 | _Win.SwapDetectHidden(aFuncId,aDetectHiddenWindows) 45 | 46 | WinGet,OutputVar,List,%WinTitle% 47 | 48 | if (OutputVar=0) 49 | return false 50 | WinList:=[] 51 | loop,%OutputVar%{ 52 | WinList.Push(OutputVar%A_Index%) 53 | } 54 | 55 | 56 | _Win.SwapDetectHidden(aFuncId,aDetectHiddenWindows) 57 | 58 | for i,v in WinList { 59 | WinList[i]:="ahk_id " v 60 | } 61 | 62 | return WinList 63 | } 64 | 65 | SelectWinByPath(aPathObj,aAnalyzeWins){ 66 | newAnalyzeWins:=[] 67 | for i,v in aAnalyzeWins { 68 | theAnalyzeWin:=v 69 | 70 | if(theAnalyzeWin.WinPath=aPathObj.path) 71 | newAnalyzeWins.push(theAnalyzeWin) 72 | } 73 | return newAnalyzeWins 74 | } 75 | 76 | ;---------------------------------------------------------------------- 77 | 78 | /* 79 | 通过路径(path),获取AnalyzeWins(多维数组形式) 80 | */ 81 | 82 | AnalyzeByPath(aWinPath,aDetectHiddenWindows:=""){ 83 | thePathObj:=new PathObj(aWinPath) 84 | theAnalyzeWins:=_Wins.Analyze("ahk_exe" thePathObj.name,aDetectHiddenWindows) 85 | return _Wins.SelectWinByPath(thePathObj,theAnalyzeWins) 86 | } 87 | ;---------------------------------------------------------------------- 88 | 89 | } ;_Wins Class End -------------------------------------------------------------------------------- /Core/Bean.ahk: -------------------------------------------------------------------------------- 1 | 2 | ;~ protect(Bean) 3 | 4 | Class Bean{ 5 | static ObjectMetaMethodName:=["_NewEnum","__Init","__New","__Delete","__Get","__call","__Set","Count","Length"] 6 | ,LogEnable:=true 7 | 8 | ;---------------------------------------------------------------------- 9 | 10 | true(aParas*){ 11 | return true 12 | } 13 | ;---------------------------------------------------------------------- 14 | 15 | false(aParas*){ 16 | return false 17 | } 18 | 19 | 20 | ;---------------------------------------------------------------------- 21 | 22 | isFunc(aObj){ 23 | if((type.isMethod(aObj))OR(type.isFuncObj(aObj))){ 24 | return true 25 | } 26 | else{ 27 | return false 28 | } 29 | } 30 | ;---------------------------------------------------------------------- 31 | 32 | afFunc(aObj){ 33 | theTypeString := Type.ofCode(Type(aObj)) 34 | if (NOT(Bean.isFunc(aObj))){ 35 | throwWithSt(_EX.InvalidPara "1 : 参数不是FuncObj或Active,而是 " theTypeString) 36 | } 37 | return 38 | } 39 | ;---------------------------------------------------------------------- 40 | 41 | isMeta(aMethodName){ 42 | result := _Container.Contains(Bean.ObjectMetaMethodName,aMethodName) 43 | return result 44 | } 45 | 46 | ;---------------------------------------------------------------------- 47 | notMeta(aMethodName){ 48 | result := Not(Bean.isMeta(aMethodName)) 49 | return result 50 | } 51 | 52 | ;---------------------------------------------------------------------- 53 | 54 | 55 | isCall(aMethodName,athis:=""){ 56 | if (IsObject(aMethodName) AND IsObject(athis)){ 57 | result := _Container.Contains(aMethodName,athis) 58 | return result 59 | } 60 | 61 | result := ((aMethodName = "")OR(aMethodName = "Call")) 62 | return result 63 | } 64 | ;---------------------------------------------------------------------- 65 | 66 | 67 | notCall(aMethodName){ 68 | result := Not(Bean.isCall(aMethodName)) 69 | return result 70 | } 71 | 72 | 73 | Class Protect{ 74 | 75 | __Call(param*){ 76 | ;~ println("Call保护") 77 | throwWithSt(_EX.NoExistMethod) 78 | return 79 | } 80 | 81 | __Set(param*){ 82 | ;~ println("Set保护") 83 | throwWithSt(_EX.NoExistVariate) 84 | return 85 | } 86 | 87 | __Get(param*){ 88 | ;~ println("Get保护") 89 | throwWithSt(_EX.NoExistVariate) 90 | return 91 | } 92 | 93 | ;---------------------------------------------------------------------- 94 | 95 | } 96 | 97 | 98 | } -------------------------------------------------------------------------------- /Core/_toString.ahk: -------------------------------------------------------------------------------- 1 | class _toString{ 2 | str(aStr){ 3 | if(aStr="") 4 | return "*NS*" 5 | else 6 | return aStr 7 | } 8 | ;------------------------------ 9 | list(aObj){ 10 | ResultString := "[" 11 | if (Type.isList(aObj)){ 12 | for i,v in aObj{ 13 | if (A_Index!=1) 14 | symbol:="," 15 | else 16 | symbol:="" 17 | if (Type.isObj(v)){ 18 | ResultString.=symbol toString(v) 19 | } 20 | else if (v="") 21 | ResultString.=symbol "*NS*" 22 | 23 | else 24 | ResultString.=symbol v 25 | } 26 | ResultString.= "]" ;添加右侧的中括号并出厂 27 | return ResultString 28 | } 29 | } 30 | 31 | ;------------------------------ 32 | obj(aObj){ 33 | ResultString := "{" 34 | if(aObj.toString()!="") 35 | return aObj.toString() 36 | if (aObj.count()=0) 37 | return "{*Obj*}" 38 | ;如果发现是实例,那么增加实例提示 39 | if (ObjHasKey(aObj.base,"__Class")){ 40 | ResultString .= "__Instance:" . aObj.base.__Class . "," 41 | } 42 | for key,v in aObj{ 43 | theKey:=toString(Key) 44 | if (A_Index!=1) 45 | symbol:="," 46 | else 47 | symbol:="" 48 | if (Type.isObj(v)){ ;key一定是用""包裹的,value则不 49 | theV:=toString(v) ;DeBug 50 | TheSubString=%symbol%%theKey%:%theV% 51 | ResultString.=TheSubString 52 | } 53 | else{ 54 | if(v="") 55 | ds:="*NS*" 56 | else 57 | ds:=v 58 | TheSubString=%symbol%%theKey%:%DS% 59 | ResultString.=TheSubString 60 | } 61 | } 62 | ResultString.= "}" 63 | return ResultString 64 | } 65 | ;------------------------------ 66 | 67 | funcObj(aObj){ 68 | if (type.isFuncObj(aObj)){ 69 | theMap := Object() 70 | theMap.Name := aObj.Name 71 | theMap.IsBuiltIn := aObj.IsBuiltIn 72 | theMap.IsVariadic := aObj.IsVariadic 73 | theMap.MinParams := aObj.MinParams 74 | theMap.MaxParams := aObj.MaxParams 75 | } 76 | else{ 77 | return "*NotFunc*:"toString(aObj) 78 | } 79 | } 80 | ;------------------------------ 81 | comObj(aCOMAcc){ 82 | theResult := Object() 83 | theResult.Value := ComObjValue(aCOMAcc) 84 | theResult.VarType := ComObjType(aCOMAcc) ; 需要 [v1.0.91+] 85 | theResult.Name := ComObjType(aCOMAcc, "Name") 86 | theResult.IID := ComObjType(aCOMAcc, "IID") 87 | theResult.Class := ComObjType(aCOMAcc, "Class") ; 需要 [v1.1.26+] 88 | theResult.CLSID := ComObjType(aCOMAcc, "CLSID") ; 需要 [v1.1.26+] 89 | return toString(theResult) 90 | } 91 | 92 | } ;---------class _toString End 93 | -------------------------------------------------------------------------------- /Docs/AccWrapper.md: -------------------------------------------------------------------------------- 1 | # AccWrapper Class 2 | 3 | 1. 性质:实例类/静态类 4 | 2. 开发目的: 5 | 6 | 更方便的操作Acc(IAccessible)对象 7 | 8 | ## 域 Fields 9 | 10 | ```AutoHotKey 11 | p_accObj := "",path := AccWrapper.unknown 12 | ;------------------------------ 13 | Static loaded := "",setting := 0,unknown := "UnKnown" 14 | ;sources: WinUser.h, oleacc.h 15 | ;e.g. STATE_SYSTEM_SELECTED := 0x2 16 | static State := {0x1:"UNAVAILABLE" 17 | , 0x2:"SELECTED" 18 | , 0x4:"FOCUSED" 19 | , 0x8:"PRESSED" 20 | , 0x10:"CHECKED" 21 | , 0x20:"MIXED" 22 | , 0x40:"READONLY" 23 | , 0x80:"HOTTRACKED" 24 | , 0x100:"DEFAULT" 25 | , 0x200:"EXPANDED" 26 | , 0x400:"COLLAPSED" 27 | , 0x800:"BUSY" 28 | , 0x1000:"FLOATING" 29 | , 0x2000:"MARQUEED" 30 | , 0x4000:"ANIMATED" 31 | , 0x8000:"INVISIBLE" 32 | , 0x10000:"OFFSCREEN" 33 | , 0x20000:"SIZEABLE" 34 | , 0x40000:"MOVEABLE" 35 | , 0x80000:"SELFVOICING" 36 | , 0x100000:"FOCUSABLE" 37 | , 0x200000:"SELECTABLE" 38 | , 0x400000:"LINKED" 39 | , 0x800000:"TRAVERSED" 40 | , 0x1000000:"MULTISELECTABLE" 41 | , 0x2000000:"EXTSELECTABLE" 42 | , 0x4000000:"ALERT_LOW" 43 | , 0x8000000:"ALERT_MEDIUM" 44 | , 0x10000000:"ALERT_HIGH" 45 | , 0x20000000:"PROTECTED" 46 | , 0x40000000:"HASPOPUP"} 47 | ``` 48 | 49 | 50 | 51 | ## 示例 Examples 52 | ```AutoHotKey 53 | 可以用任务栏作为例子操作下 54 | ``` 55 | 56 | ## 方法 Methods 57 | 58 | ### ObjectFromWindow(hWnd, idObject := 0) 59 | 60 | **静态方法,用于获取窗口的Acc对象** 61 | 62 | #### 参数 Parameters 63 | 64 | hWnd - 窗口的ID 65 | 66 | idObject - 含义不清,默认用0即可 67 | 68 | #### 返回 Returns 69 | 70 | AccWrapper 71 | 72 | #### 抛出异常 Throws 73 | 74 | - 未知 75 | 76 | #### 测试 Test 77 | 78 | LibTest_AccWrapper.ObjectFromWindow().ahk 79 | 80 | ### Analyze(vChildId := 0) 81 | 82 | **尽量将Acc对象的信息写入到Map当中,便于DeBug:** 83 | 84 | #### 参数 Parameters 85 | 86 | vChildId - 含义不清,默认用0即可 87 | 88 | #### 返回 Returns 89 | 90 | Map 91 | 92 | #### 抛出异常 Throws 93 | 94 | - 未知 95 | 96 | #### 测试 Test 97 | 98 | LibTest_AccWrapper.ObjectFromWindow().ahk 99 | 100 | ### println(vChildId := 0) 101 | 102 | 将`Analyze(vChildId := 0)`的返回值直接打印到控制台 103 | 104 | #### 测试 Test 105 | 106 | LibTest_AccWrapper.ObjectFromWindow().ahk 107 | 108 | ### ObjectFromPath(aPath) 109 | 110 | **使用路径获取子控件:** 111 | 112 | #### 参数 Parameters 113 | 114 | aPath - 路径,例如`4.7`,可以通过`AccView`获取,使用的时候注意基准,`AccView`获取的路径可能是相对的,而不是绝对(总是对于窗口)的。 115 | #### 返回 Returns 116 | 117 | AccWrapper 118 | 119 | #### 抛出异常 Throws 120 | 121 | - 未知 122 | 123 | #### 测试 Test 124 | 125 | LibTest_AccWrapper.ObjectFromWindow().ahk -------------------------------------------------------------------------------- /Test/LibTest__Acc._Sourcetree.ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | #Include D:\AHKs\ahk_lib\GUI\_Acc.ahk 24 | 25 | 26 | theWinTitle := "Sourcetree ahk_exe SourceTree.exe",theHWnd := "" 27 | 28 | WinGet, theHWnd, ID , %theWinTitle% 29 | 30 | theWinObj := _Win.Analyze("ahk_id " theHWnd) 31 | LogPrintln(theWinObj,A_LineFile "(" A_LineNumber ")" " : " "theWinObj >>> `r`n") 32 | 33 | LogPrintln(theHWnd,A_LineFile "(" A_LineNumber ")" " : " "theHWnd >>> `r`n") 34 | 35 | theAccObj := Acc_ObjectFromWindow(theHWnd := "0x17124c", theIdObject := 0) 36 | 37 | LogPrintln(theAccObj,A_LineFile "(" A_LineNumber ")" " : " "theAccObj >>> `r`n") 38 | 39 | return 40 | 41 | LogPrintln(theAccObj,A_LineFile "(" A_LineNumber ")" " : " "theAccObj >>> `r`n") 42 | 43 | LogPrintln(_Acc.Analyze(theAccObj),A_LineFile "(" A_LineNumber ")" " : " "_Acc.Analyze(theAccObj) >>> `r`n") 44 | 45 | thePath := "4.2.1.2.2.1.5.6" 46 | 47 | theAccObj := _Acc.ObjectFromPath(theAccObj,thePath) 48 | 49 | LogPrintln(_Acc.Analyze(theAccObj),A_LineFile "(" A_LineNumber ")" " : " "_Acc.Analyze(theAccObj) >>> `r`n") 50 | 51 | PrintScreen:: 52 | result := theAccObj.accDefaultAction(vChildId) 53 | LogPrintln(_Acc.Analyze(theAccObj),A_LineFile "(" A_LineNumber ")" " : " "_Acc.Analyze(theAccObj) >>> `r`n") 54 | theAccObj.accDoDefaultAction(vChildId) 55 | LogPrintln(result,A_LineFile "(" A_LineNumber ")" " : " "result >>> `r`n") 56 | return 57 | 58 | ;------------------------------ 59 | 60 | 61 | ^PrintScreen:: 62 | theResult := _Acc.AnalyzeFromPoint(vChildId) 63 | LogPrintln(theResult,A_LineFile "(" A_LineNumber ")" " : " "theResult >>> `r`n") 64 | return 65 | 66 | 67 | 68 | 69 | #If WinActive(A_ScriptName) 70 | ;可以按下Alt+L查看最近运行的行 71 | 72 | /* 73 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 74 | ListLines 75 | return 76 | 77 | !^h:: 78 | KeyHistory 79 | return 80 | 81 | !a:: 82 | send,{F5} 83 | return 84 | 85 | !^s:: 86 | ListVars 87 | return 88 | */ 89 | 90 | 91 | #If 92 | 93 | 94 | !q:: 95 | ExitApp 96 | return 97 | 98 | +!q:: 99 | Pause 100 | return 101 | -------------------------------------------------------------------------------- /Docs/WinEvent.md: -------------------------------------------------------------------------------- 1 | # WinEvent Class 2 | 3 | 1. 性质:抽象类 4 | 2. 开发目的:ShellHook(窗口钩子),让窗口切换、建立等等,十几种窗口操作本身作为触发器。AHK最突出的特点是是「热键」和「热字串」,而现在有了「热窗口」。O(∩_∩)O~ 5 | AHK没有「抽象类」,但是这个函数类似Java中的「抽象类」,只能继承使用。 6 | 7 | ## 域 Field 8 | 9 | ```autohotkey 10 | class wParam_Base{ 11 | Created := 1, 12 | Destroyed := 2, 13 | Activate := 3, 14 | Activated := 4, 15 | GetMinRect := 5, 16 | ReDraw := 6, 17 | Taskman := 7, 18 | Language := 8, 19 | Sysmenu := 9, 20 | Endtask := 10, 21 | AccessibilityState := 11, 22 | Appcommand := 12, 23 | Windowreplaced := 13, 24 | Windowreplacing := 14, 25 | FullScreen := 53, 26 | ExitFullScreen := 54, 27 | Switched := 32772 28 | 29 | ;1 顶级窗体被「创建」 30 | ;2 顶级窗体即将被「关闭」 31 | ;3 SHELL 的主窗体将被激活 32 | ;4 顶级窗体被激活 33 | ;5 顶级窗体被最大化或最小化 34 | ;6 Windows 任务栏被刷新,也可以理解成「标题变更」 35 | ;7 任务列表的内容被选中 36 | ;8 中英文切换或输入法切换 37 | ;9 显示系统菜单 38 | ;10 顶级窗体被强制关闭 39 | ;11 用于残障人士的辅助功能 40 | ;12 没有被程序处理的APPCOMMAND。见WM_APPCOMMAND 41 | ;13 wParam=被替换的顶级窗口的hWnd 42 | ;14 wParam=替换顶级窗口的窗口hWnd 43 | ;&H8000& 掩码 44 | ;53 全屏 45 | ;54 退出全屏 46 | ;32772 窗口切换 47 | ;------------------------------ 48 | } 49 | ``` 50 | 51 | ## 方法 Method 52 | 53 | ### ShellMessage_Base(wParam, lParam, msg:="", hwnd:="") 54 | 55 | 该方法会被COM对象自动回调 56 | 57 | ### ShellMessage(wParam, lParam, msg:="", hwnd:="") 58 | 59 | 在之前,该方法必须被复写,现在完全自动化了,不需要复写 60 | 61 | ### ShellHook() 62 | 63 | 注册窗口钩子 64 | 65 | ### enable() 66 | 67 | 启用 68 | 69 | ### disable() 70 | 71 | 禁用 72 | 73 | ## 示例 74 | 75 | 运行前,应先导入BeanLib 76 | 77 | ### 在之前必须复写ShellMessage() 78 | 79 | ```autohotkey 80 | 81 | WinEventObj:=new MyWinEvent() 82 | class MyWinEvent extends WinEvent{ 83 | ShellMessage(wParam, lParam, msg:="", hwnd:=""){ 84 | if (wParam = this.wParam.Switched){ 85 | this.OnSwap() 86 | } 87 | return 88 | } 89 | ;------------------------------ 90 | OnSwap(){ 91 | aTitle := A_ScriptName,aTipString := A_ScriptName,TrayTip(aTitle,aTipString) 92 | return 93 | } 94 | } ;---------class MyWinEvent End 95 | 96 | ``` 97 | 98 | ### 现在可以直接编写方法 99 | 100 | ```autohotkey 101 | 102 | WinEventObj:=new MyWinEvent() 103 | class MyWinEvent extends WinEvent{ 104 | OnDestroyed(theWinObjs){ 105 | theWinObj := theWinObjs[1] 106 | if(theWinObj.WinId = this.WinID.fiboOwner){ 107 | if(this.fiboObject) 108 | this.fiboObject.close() 109 | } 110 | return 111 | } 112 | } ;---------class MyWinEvent End 113 | 114 | ``` 115 | 116 | 要注意,会传入**窗口数组**,必须有这个参数,否则会调用失败。 117 | *此前会传入窗口对象,现在是窗口数组。* -------------------------------------------------------------------------------- /BeanLib.ahk: -------------------------------------------------------------------------------- 1 | 2 | ;定义 #Include 的工作目录 3 | #Include D:\AHKs\ahk_lib 4 | 5 | /* 6 | Core Pack 必须全部导入 7 | 其余 Pack 按需导入 8 | */ 9 | 10 | #Include Core\AHKTest.ahk 11 | #Include Core\Bean.ahk 12 | #Include Core\_Container.ahk 13 | #Include Core\_EX.ahk 14 | #Include Core\_List.ahk 15 | #Include Core\_Map.ahk 16 | #Include Core\_toString.ahk 17 | #Include Core\Analyze().ahk 18 | #Include Core\Function.ahk 19 | #Include Core\getClass().ahk 20 | #Include Core\Instanof().ahk 21 | #Include Core\InvisibleCharacter.ahk 22 | #Include Core\StringMethod.ahk 23 | #Include Core\TypeFuncAndClass.ahk 24 | #Include Core\Method.ahk 25 | #Include Core\Function.ahk 26 | #Include Core\ObservableMap.ahk 27 | #Include Core\ObservableObj.ahk 28 | #Include Core\PathObj.ahk 29 | #Include Core\Stack.ahk 30 | #Include Core\Queue.ahk 31 | #Include Core\Timer.ahk 32 | #Include Core\MesToast.ahk 33 | 34 | #Include GUI\AccWrapper.ahk 35 | 36 | ;FuncObj Pack 37 | #Include FuncObj\BeanEnum.ahk 38 | #Include FuncObj\Condition.ahk 39 | 40 | 41 | ;GUI Pack 42 | #Include GUI\_GUI.ahk 43 | #Include GUI\_Win.ahk 44 | #Include GUI\_Wins.ahk 45 | #Include GUI\BeanControl.ahk 46 | #Include GUI\WinEvent.ahk 47 | #Include GUI\AutoGUI.ahk 48 | #Include GUI\AutoInputBox.ahk 49 | 50 | ;Everthing Pack 51 | #Include Everything.ahk 52 | 53 | ;APP Pack 54 | #Include APP\AutoClassify.ahk 55 | #Include APP\APPLocker.ahk 56 | #Include APP\TimeChecker.ahk 57 | #Include APP\TimeChecker.ahk 58 | #Include APP\Script.ahk 59 | #Include APP\Switcher.ahk 60 | #Include APP\RunningSpeedTest.ahk 61 | #Include APP\IPA_EN.ahk 62 | 63 | ;UMSS Pack 64 | #Include UMSS.ahk 65 | 66 | ;HotString Pack 67 | #Include HotString.ahk 68 | 69 | ;Spliter Pack 70 | #Include Spliter.ahk 71 | 72 | ;I/O Pack 73 | #Include IO\Ini.ahk 74 | #Include IO\ExcelToList().ahk 75 | #Include IO\JSON.ahk 76 | #Include IO\TextFile.ahk 77 | 78 | 79 | ;示例: 80 | 81 | /* 82 | 83 | ;APP Pack 84 | #Include AutoClassify.ahk 85 | #Include APPLocker.ahk 86 | #Include TimeChecker.ahk 87 | #Include Script.ahk 88 | 89 | ;Everthing Pack 90 | #Include Everything.ahk 91 | 92 | ;GUI Pack 93 | #Include GUI.ahk 94 | #Include Win.ahk 95 | #Include _Win.ahk 96 | #Include _Wins.ahk 97 | #Include BeanControl.ahk 98 | 99 | ;FuncObj Pack 100 | #Include Method.ahk 101 | #Include BeanEnum.ahk 102 | #Include Condition.ahk 103 | #Include WinEvent.ahk 104 | #Include AutoGUI.ahk 105 | #Include AutoInputBox.ahk 106 | 107 | 108 | ;UMSS Pack 109 | #Include UMSS.ahk 110 | 111 | ;HotString Pack 112 | #Include HotString.ahk 113 | 114 | ;String Pack 115 | #Include PathObj.ahk 116 | #Include Spliter.ahk 117 | 118 | ;I/O Pack 119 | #Include Ini.ahk 120 | #Include ExcelToList().ahk 121 | */ -------------------------------------------------------------------------------- /HotString.ahk: -------------------------------------------------------------------------------- 1 | class HotStringMaps{ 2 | static List := [] 3 | ;------------------------------ 4 | HotStringCheck(){ 5 | for i,v in HotStringMaps.List { 6 | result := v.when() 7 | if(result){ 8 | return v 9 | } 10 | 11 | } 12 | return false 13 | } 14 | ;------------------------------ 15 | Extract(theHotStringMap){ 16 | local String := "" 17 | for k,v in theHotStringMap { 18 | result := HotString.isHotString(v) 19 | if(result){ 20 | String .= v.Trigger "`t" v.Remarks "`r`n" 21 | } 22 | } 23 | return String 24 | } 25 | ;------------------------------ 26 | ExtractAndMerge(){ 27 | for k,v in HotStringMaps.List{ 28 | theHotStringMap := v 29 | String := HotStringMaps.Extract(theHotStringMap) 30 | HotStringMaps.List[k] := Object("String",String,"Name",v.__class,"When",v.when) 31 | } 32 | return 33 | } 34 | 35 | } ;HotStringMaps End 36 | ;------------------------------ 37 | class HotString{ 38 | 39 | ContextMatch(){ 40 | return this.PremiseBindFunc.call() 41 | } 42 | 43 | isHotString(HotStringObj){ 44 | try{ 45 | result := Instanof(HotStringObj,HotString) 46 | } 47 | catch Ex{ 48 | return false 49 | } 50 | return result 51 | } 52 | ;------------------------------ 53 | Trigger := behavior := Remarks := "" 54 | static On := "On",Toggle := "Toggle",Off := "Off" 55 | Premise := PremiseBindFunc := Object("Null","Null") 56 | ;------------------------------ 57 | IFOn(){ 58 | theFunc := this.PremiseBindFunc 59 | Hotkey, If, % theFunc 60 | return ErrorLevel 61 | } 62 | ;------------------------------ 63 | IFOff(){ 64 | Hotkey, If 65 | return ErrorLevel 66 | } 67 | ;------------------------------ 68 | __New(Trigger,behavior,Remarks,Premise){ 69 | type.assertStr(Trigger),type.assertStr(Remarks),type.assertObj(Premise) 70 | this.PremiseBindFunc := this.Premise.bind(this) 71 | this.Premise := Premise,this.Trigger := Trigger,this.behavior := behavior,this.Remarks := Remarks 72 | return this 73 | } 74 | ;---------------------------------------------------------------------- 75 | clone(Remarks){ 76 | return HotString.__New(this.Trigger,this.behavior,Remarks) 77 | } 78 | ;---------------------------------------------------------------------- 79 | equal(OtherHotString){ 80 | result := ((Trigger = this.Trigger) AND (behavior = this.behavior)) 81 | return result 82 | } 83 | ;------------------------------ 84 | register(){ 85 | this.IFOn(),Hotstring(this.Trigger,this.behavior),this.IFOff() 86 | return 87 | } 88 | ;------------------------------ 89 | create(Trigger,behavior,Remarks,Premise){ 90 | theObj := new HotString(Trigger,behavior,Remarks,Premise) 91 | theObj.register() 92 | return theObj 93 | } 94 | ;------------------------------ 95 | } ;---------class HotString End -------------------------------------------------------------------------------- /IO/ExcelToList().ahk: -------------------------------------------------------------------------------- 1 | ; v1.1 (2018-7-19) 2 | ; https://github.com/tmplinshi/ExcelToArray 3 | 4 | ExcelToList(FileName, nSheet := 1, last_row := "", last_column := ""){ 5 | return ExcelToArrayClass.DoIt(FileName, nSheet, last_row, last_column) 6 | } 7 | 8 | class ExcelToArrayClass{ 9 | DoIt(FileName, nSheet := 1, last_row := "", last_column := ""){ 10 | if !FileExist(FileName){ 11 | throw(_Ex.NoExistFile) 12 | } 13 | 14 | 15 | ListfeArr := this.GetListfeArrFromXlFile(FileName, nSheet, last_row, last_column) 16 | ret := this.ListfeArr_To_AHKArr(ListfeArr) 17 | return ret 18 | } 19 | 20 | GetListfeArrFromXlFile(FileName, nSheet := 1, last_row := "", last_column := ""){ 21 | fPath := this.GetFullPath(FileName),wb:=xlObj:="" 22 | 23 | if this.IsFileInUse(fPath) { 24 | try wb := this.GetWorkbook(fpath) 25 | } 26 | if !wb { 27 | xlObj := ComObjCreate("Excel.Application") 28 | xlObj.Workbooks.Open(fPath) 29 | wb := xlObj.ActiveWorkbook 30 | } 31 | 32 | ListfeArr := this.GetListfeArr(wb, nSheet, last_row, last_column) 33 | 34 | xlObj.Quit 35 | 36 | return ListfeArr 37 | } 38 | 39 | GetWorkbook(fPath){ 40 | xls := ComObjActive("Excel.Application") 41 | 42 | Loop, % xls.WorkBooks.Count 43 | { 44 | if ( xls.WorkBooks(A_Index).FullName = fPath ) 45 | Return xls.WorkBooks(A_Index) 46 | } 47 | } 48 | 49 | ListfeArr_To_AHKArr(ListfeArr){ 50 | ret := [] 51 | 52 | rowCount := ListfeArr.MaxIndex(1) 53 | colCount := ListfeArr.MaxIndex(2) 54 | 55 | Loop, % rowCount { 56 | row := A_Index 57 | 58 | arr := [] 59 | Loop, % colCount { 60 | arr.push( ListfeArr[row, A_Index] ) 61 | } 62 | ret.push(arr) 63 | } 64 | 65 | return ret 66 | } 67 | 68 | GetListfeArr(oWorkbook, nSheet := 1, last_row := "", last_column := ""){ 69 | sheet := oWorkbook.Sheets(nSheet) 70 | 71 | if last_row && last_column 72 | lastCell := {row: last_row, column: last_column} 73 | else 74 | { 75 | lastCell := this.xlFindLastCell(oWorkbook, nSheet) 76 | if last_row 77 | lastCell.row := last_row 78 | else if last_column 79 | lastCell.column := last_column 80 | } 81 | cell_begin := sheet.cells(1, 1) 82 | cell_end := sheet.cells(lastCell.row, lastCell.column) 83 | 84 | return ListfeArr := sheet.Range(cell_begin, cell_end).FormulaR1C1 85 | } 86 | 87 | GetFullPath(FileName){ 88 | Loop, % FileName 89 | return A_LoopFileLongPath 90 | } 91 | 92 | IsFileInUse(FileName){ 93 | return FileExist(FileName) && !FileOpen(FileName, "rw") 94 | } 95 | 96 | xlFindLastCell(oWorkbook, sheet := 1){ 97 | static xlByRows := 1 98 | , xlByColumns := 2 99 | , xlPrevious := 2 100 | 101 | lastRow := oWorkbook.Sheets(sheet).Cells.Find("*", , , , xlByRows , xlPrevious).Row 102 | lastCol := oWorkbook.Sheets(sheet).Cells.Find("*", , , , xlByColumns, xlPrevious).Column 103 | 104 | return {row: lastRow, column: lastCol} 105 | } 106 | } -------------------------------------------------------------------------------- /Test/LibTest_AccWrapper.ObjectFromWindow().ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | 24 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 25 | 26 | theAccWrapperObj := AccWrapper.ObjectFromWindow(_Win.Analyze("ahk_class Shell_TrayWnd ahk_exe explorer.exe").id) 27 | 28 | LogPrintln(theAccWrapperObj.Analyze(),A_LineFile "(" A_LineNumber ")" " : " "theAccWrapperObj.Analyze() >>> `r`n") 29 | 30 | /* 31 | D:\AHKs\ahk_lib\Test\LibTest_AccWrapper.ObjectFromWindow().ahk(28) : theAccWrapperObj.Analyze() >>> 32 | {Action:*NS*,ChildCount:7,Description:*NS*,Focus:*NS*,Help:*NS*,HelpTopic:0,hWnd:65736,Keyboard:*NS*,Location:{h:46,w:1920,x:0,y:1034},Name:任务栏,Path:--,RoleNum:9,RoleNumHex:0x9,RoleText:窗口,Selection:*NS*,SelectionCount:0,StateNum:1048576,StateNumHex:0x100000,StateText:可设定焦点,StateTextAll:focusable,Value:*NS*} 33 | */ 34 | 35 | theAccWrapperObj.println() 36 | 37 | /* 38 | {Action:*NS*,ChildCount:7,Description:*NS*,Focus:*NS*,Help:*NS*,HelpTopic:0,hWnd:65736,Keyboard:*NS*,Location:{h:46,w:1920,x:0,y:1034},Name:任务栏,Path:--,RoleNum:9,RoleNumHex:0x9,RoleText:窗口,Selection:*NS*,SelectionCount:0,StateNum:1048576,StateNumHex:0x100000,StateText:可设定焦点,StateTextAll:focusable,Value:*NS*} 39 | */ 40 | 41 | /* 42 | TODO:现在的问题就是,我没有对于某个窗口进行分析的工具,结果导致经常找不到目标. 43 | 原来那个工具的话,主要是用鼠标焦点,在实际的使用中,一般不会这么操作,尤其是对于那些窗口比较另类的情况,比如说任务栏之类的。 44 | 之后可以进行改进,在此基础上增加ObjectFromWindow对象的分析功能,最好支持全局搜索,直接找到对应的值所在的控件. 45 | */ 46 | 47 | ;使用便利来查找窗口下的「任务栏」控件 48 | for i,v in theAccWrapperObj.getChildren() { 49 | LogPrintln( v.Analyze(),A_LineFile "(" A_LineNumber ")" " : " " v.Analyze() >>> `r`n") 50 | } 51 | 52 | ;打印任务栏中的「开始」控件信息 53 | LogPrintln(theAccWrapperObj.ObjectFromPath("4.1").Analyze(),A_LineFile "(" A_LineNumber ")" " : " "theAccWrapperObj.ObjectFromPath(""4.1"").Analyze() >>> `r`n") 54 | 55 | /* 56 | D:\AHKs\ahk_lib\Test\LibTest_AccWrapper.ObjectFromWindow().ahk(53) : theAccWrapperObj.ObjectFromPath("4.1").Analyze() >>> 57 | {Action:*NS*,ChildCount:7,Description:*NS*,Focus:*NS*,Help:*NS*,HelpTopic:0,hWnd:65744,Keyboard:*NS*,Location:{h:46,w:54,x:0,y:1034},Name:开始,Path:--,RoleNum:9,RoleNumHex:0x9,RoleText:窗口,Selection:*NS*,SelectionCount:0,StateNum:1048576,StateNumHex:0x100000,StateText:可设定焦点,StateTextAll:focusable,Value:*NS*} 58 | */ 59 | 60 | #If WinActive(A_ScriptName) 61 | ;可以按下Alt+L查看最近运行的行 62 | 63 | /* 64 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 65 | ListLines 66 | return 67 | 68 | !^h:: 69 | KeyHistory 70 | return 71 | 72 | !a:: 73 | send,{F5} 74 | return 75 | 76 | !^s:: 77 | ListVars 78 | return 79 | */ 80 | 81 | 82 | #If 83 | 84 | 85 | !q:: 86 | ExitApp 87 | return 88 | 89 | +!q:: 90 | Pause 91 | return 92 | -------------------------------------------------------------------------------- /Core/ObservableMap.ahk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | class ObservableMap{ 5 | field := Object("map","","listenerList",[]) 6 | ;------------------------------ 7 | size(){ 8 | return this.field.map.count() 9 | } 10 | ;------------------------------ 11 | __Set(key,value,para*){ 12 | if(key = "field","base") 13 | return ObjRawSet(this,key,value) 14 | else{ 15 | LogPrintln(key,A_LineFile "(" A_LineNumber ")" " : " "key >" ">> `r`n") 16 | throwWithST(A_ThisFunc) 17 | } 18 | return 19 | } 20 | ;------------------------------ 21 | _NewEnum(){ 22 | return new BeanEnum(this.field.map) 23 | } 24 | ;------------------------------ 25 | __New(aMap:=""){ 26 | if(aMap=""){ 27 | this.field.map := Object() 28 | } 29 | else{ 30 | Type.assertObj(aMap) 31 | this.field.map := aMap 32 | } 33 | return this 34 | } 35 | ;------------------------------ 36 | addListener(aMethod){ 37 | this.field.listenerList.push(aMethod) 38 | return 39 | } 40 | ;------------------------------ 41 | get(aKey){ 42 | return this.field.map[aKey] 43 | } 44 | ;------------------------------ 45 | clear(){ 46 | theRemovedMap := this.field.map 47 | this.field.map := Object() 48 | theChange := new ObservableMap.Change(aObservableMap:=this,aRemoved:=true,theRemovedMap,aAdded:=false,aAddedMap:=Object()) 49 | this.callListener(theChange) 50 | return 51 | } 52 | ;------------------------------ 53 | remove(aKey*){ 54 | theRemovedMap := _Container.Extract(this.field.map,aKey) 55 | this.field.map.remove(aKey*) 56 | theChange := new ObservableMap.Change(aObservableMap:=this,aRemoved:=true,theRemovedMap,aAdded:=false,aAddedMap:=Object()) 57 | this.callListener(theChange) 58 | return 59 | } 60 | ;------------------------------ 61 | put(aKeyValue*){ 62 | theAddedMap := Object(aKeyValue*) 63 | this.field.map := _Map.merge(this.field.map,theAddedMap) 64 | theChange := new ObservableMap.Change(aObservableMap:=this,aRemoved:=false,aRemovedMap:=Object(),aAdded:=true,theAddedMap) 65 | this.callListener(theChange) 66 | return 67 | } 68 | ;------------------------------ 69 | callListener(aChange){ 70 | for i,v in this.field.listenerList { 71 | v.call(aChange) 72 | } 73 | return 74 | } 75 | ;------------------------------ 76 | class Change{ 77 | __New(aObservableMap,aRemoved,aRemovedMap,aAdded,aAddedMap){ 78 | this.observableMap := aObservableMap 79 | this.removed := aRemoved 80 | this.removedMap := aRemovedMap 81 | this.added := aAdded 82 | this.addedMap := aAddedMap 83 | return this 84 | } 85 | ;------------------------------ 86 | getMap(){ 87 | return this.observableMap 88 | } 89 | ;------------------------------ 90 | wasRemoved(){ 91 | return this.removed 92 | } 93 | ;------------------------------ 94 | wasAdded(){ 95 | return this.added 96 | } 97 | ;------------------------------ 98 | getValueRemoved(){ 99 | return this.removedMap 100 | } 101 | ;------------------------------ 102 | getValueAdded(){ 103 | return this.addedMap 104 | } 105 | } ;---------class change End 106 | } ;---------class ObservableMap End 107 | -------------------------------------------------------------------------------- /Test/LibTest_toString().ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | 24 | LogPrintln(A_ScriptName,"A_ScriptName >>> ") 25 | 26 | 27 | 28 | theKeyFunc := Method.for(FuncClass.handleKey,FuncClass) 29 | theValueFunc := Method.for(FuncClass.handleValue,FuncClass) 30 | 31 | 32 | stdoutln(MapFactory(TypeClassInstance,theKeyFunc,theValueFunc)) 33 | 34 | 35 | Class FuncClass{ 36 | handleKey(aKey){ 37 | theStr = toString(%aKey%) 38 | return theStr 39 | } 40 | handleValue(aValue){ 41 | return toString(aValue) 42 | } 43 | } 44 | 45 | return 46 | 47 | ;下面是之前手动测试留下来的痕迹,可以和现在的全自动测试对比下 48 | 49 | LogPrintln(TypeClassInstance.ComObj,A_LineFile "(" A_LineNumber ")" " : " "TypeClassInstance.ComObj >>> `r`n") 50 | LogPrintln(TypeClassInstance.Obj,A_LineFile "(" A_LineNumber ")" " : " "TypeClassInstance.Obj >>> `r`n") 51 | LogPrintln(TypeClassInstance.Class,A_LineFile "(" A_LineNumber ")" " : " "TypeClassInstance.Class >>> `r`n") 52 | LogPrintln(TypeClassInstance.FuncObj,A_LineFile "(" A_LineNumber ")" " : " "TypeClassInstance.FuncObj >>> `r`n") 53 | LogPrintln(TypeClassInstance.Exception,A_LineFile "(" A_LineNumber ")" " : " "TypeClassInstance.Exception >>> `r`n") 54 | LogPrintln(TypeClassInstance.Path,A_LineFile "(" A_LineNumber ")" " : " "TypeClassInstance.Path >>> `r`n") 55 | LogPrintln(TypeClassInstance.NS,A_LineFile "(" A_LineNumber ")" " : " "TypeClassInstance.NS >>> `r`n") 56 | LogPrintln(TypeClassInstance.Number,A_LineFile "(" A_LineNumber ")" " : " "TypeClassInstance.Number >>> `r`n") 57 | LogPrintln(TypeClassInstance.Boolean,A_LineFile "(" A_LineNumber ")" " : " "TypeClassInstance.Boolean >>> `r`n") 58 | LogPrintln(TypeClassInstance.FileObj,A_LineFile "(" A_LineNumber ")" " : " "TypeClassInstance.FileObj >>> `r`n") 59 | 60 | ComObj:=160 61 | FileObj:=150 62 | Obj:=100,Class:=110,FuncObj:=120,Exception:=121 63 | List:=130 64 | Str:=10,NS:=11,Number:=12,Boolean:=13 65 | 66 | /* 67 | >"C:\Program Files\AutoHotkey\SciTE\..\AutoHotkey.exe" /ErrorStdOut "D:\AHKs\ahk_lib\Test\LibTest_toString().ahk" 68 | A_ScriptName >>> LibTest_toString().ahk 69 | toString(Boolean):0 70 | toString(Class):{__Class:AutoInputBox,__Init:,__New:,SetAlwaysOnTop:,SetDeFaultText:,start:} 71 | toString(ComObj):{Class:*NS*,CLSID:*NS*,IID:{618736E0-3C3D-11CF-810C-00AA00389B71},Name:IAccessible,Value:13026208,VarType:9} 72 | toString(Exception):{File:D:\AHKs\ahk_lib\Test\Lib.ahk,Line:7,Message:Index Out Of Bounds.数组越界,What:TypeClass.__Init} 73 | toString(FileObj):{} 74 | toString(FuncObj):{__Instance:Function,bindParas:{*Obj*},func:} 75 | toString(NS):*NS* 76 | toString(Number):123456789 77 | toString(Obj):{*Obj*} 78 | toString(Path):D:\AHKs\ahk_lib\Test\LibTest_toString().ahk 79 | 80 | */ 81 | 82 | !q:: 83 | ExitApp 84 | return 85 | 86 | +!q:: 87 | Pause 88 | return 89 | -------------------------------------------------------------------------------- /Docs/StringMethod.md: -------------------------------------------------------------------------------- 1 | # String Method 2 | 3 | [TOC] 4 | # 介绍 5 | 1. 是一个依靠[元编程](http://xrvu_zen.gitee.io/wyagd001.github.io/docs/Objects.htm#Meta_Functions)实现的 String 方法,并非类。 6 | 2. 主要包含对于 String 的各种增强操作, 包括但不限于 获取长度,获取单个字符,转为字符数组,提取汉字汉语拼音首字母... 7 | 3. 关于元编程的更多内容,可参考以下文档 8 | - [AHK官方文档](https://autohotkey.com/docs/Objects.htm#Meta_Functions) 9 | - [AHK元编程入门系列教程(@心如止水)](https://zhuanlan.zhihu.com/AHKZen) 10 | - [AHK面向对象的编程教程(@jeeswg)](https://www.autohotkey.com/boards/viewtopic.php?f=7&t=54588) 11 | 4. 由于这些方法都非常基础和简单,所以按照官方文档的处理方法(比如其对数学函数的处理方法),多个方法的文档放在同一个页面之中。 12 | 13 | ### 定义常量 14 | - 并非真实存在的,只是为了演示方便。 15 | 因为名字太常见,容易撞车。以后如果用得多了可能单独放在一个类里面。 16 | 17 | **Str:="MyHome"** 18 | 19 | **Zh:="那里有条美丽的河"** 20 | 21 | ### CharAt(index) - 提取字符 22 | 23 | 提取String中的字符 24 | 25 | - 如果越界会抛出 IndexOutOfBounds 异常 26 | 27 | **参数:** 28 | 29 | index - 索引 30 | 31 | ``` autohotkey 32 | Str.CharAt(6) ;返回e 33 | Str.CharAt(7) ;抛出异常 34 | Str.CharAt(0) ;抛出异常 35 | ``` 36 | ### insert(insert,pos=1) - 插入字符串 37 | 38 | 在字符串中插入字符串。 39 | 40 | 如果`pos`>`length+1`,那么头部位置依旧为`length+1`。 41 | 42 | **参数:** 43 | 44 | insert- 被插入的字符串 45 | 46 | pos - 被插入字符串在新字符串中的头部位置 47 | 48 | **测试:** 49 | 50 | 有 51 | 52 | ### Length() - 获取长度 53 | 54 | 获取String的长度 55 | 56 | ``` autohotkey 57 | Str.Length() 58 | ``` 59 | 60 | ### ToList() - 转为数组 61 | 62 | 提取String中的字符 63 | 64 | ``` autohotkey 65 | Str.ToList() 66 | ``` 67 | 68 | ### toHex() - 转为十六进制(16进制) 69 | 70 | 如果不是数字会抛出"String is not Number"异常 71 | 72 | ### py() - 获取拼音首字母 73 | 74 | 转换汉字字符串为首字母汉语拼音字符串 75 | 76 | - 提取自 [HotWindows(@刘老六)](https://www.iplaysoft.com/p/hotwindows) 77 | 78 | ``` autohotkey 79 | Zh.py() 80 | ``` 81 | 82 | ### ExtractFileNameByPath() - 从路径中提取文件名(带后缀) 83 | 84 | 从路径中提取文件名(带后缀) 85 | 86 | ```autohotkey 87 | path=D:\BeanLib\StringMethod.ahk 88 | println(path.ExtractNameFromPath()) 89 | ``` 90 | 91 | ### SplitFileName() - 分割带后缀文件名为单纯的文件名和后缀名(提取后缀名) 92 | 93 | 分割带后缀文件名为单纯的文件名和后缀名(提取后缀名) 94 | 95 | ```autohotkey 96 | FileName=chrome.dll 97 | s:=FileName.SplitFileName() 98 | println(s[1]) 99 | println(s[2]) 100 | ``` 101 | 102 | ### isRegExMatch(aRegEx,aRegExOption:="i)") 103 | 104 | 检查字符串是否能完全匹配正则表达式。 105 | 106 | `PathObj` 中的路径合法性检查就是依赖这个实现的,如下: 107 | 108 | ```autohotkey 109 | af(){ 110 | aPath:=this.path 111 | aRegEx=^[a-zA-Z]:\\(((?![<>:"/\\|?*]).)+((?>>") 132 | ``` 133 | ### minToMSec() 134 | 分钟转毫秒 135 | 136 | ### secToMSec() 137 | 秒转毫秒 138 | 139 | ### replaceAll(aStringList,aReplaceString) 140 | 141 | 用多个关键词替换字符串 142 | 143 | ```AutoHotKey 144 | "ABCDEFG".replaceAll("ACG".ToList(),"") 145 | 146 | LogPrintln("ACG".ToList(),A_LineFile "(" A_LineNumber ")" " : " """ACG"".ToList() >>> `r`n") 147 | 148 | LogPrintln("ABCDEFG".replaceAll("ACG".ToList(),""),A_LineFile "(" A_LineNumber ")" " : " """ABCDEFG"".replaceAll(""ACG"".ToList(),"""") >>> `r`n") 149 | ``` 150 | 151 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | - [指南 (README)](Docs/README.md) 2 | - [常见问题 (FAQ)](Docs/BeanLib_FQA.md) 3 | - [更新历史(CHANGELOG)](Docs/更新历史(CHANGELOG).md) 4 | - [贡献指南 (CONTRIBUTING)](Docs/BeanLib_CONTRIBUTING.md) 5 | - [开源协议 (LICENCE)](Docs/LICENCE) 6 | - [鸣谢 (ACKNOWLEDGEMENT)](Docs/BeanLib_ACKNOWLEDGEMENT.md) 7 | - [文档模板 (TEMPLATE)](Docs/TEMPLATE.md) 8 | - [新手指南(BEGINNER_GUIDE)](Docs/新手指南(BEGINNER_GUIDE).md) 9 | - [语法高亮(HIGHLIGHTING)](Docs/HIGHLIGHTING.md) 10 | - [Class](Docs/Method.md) 11 | - [AccWrapper](Docs/AccWrapper.md) 12 | - [AHKTest](Docs/AHKTest.md) 13 | - [_Container](Docs/_Container.md) 14 | - [_EX](Docs/_EX.md) 15 | - [_List](Docs/_List.md) 16 | - [_Map](Docs/_Map.md) 17 | - [_Win](Docs/_Win.md) 18 | - [_Wins](Docs/_Wins.md) 19 | - [BeanEnum](Docs/BeanEnum.md) 20 | - [Function](Docs/Function.md) 21 | - [HotString](Docs/HotString.md) 22 | - [HotStringMaps](Docs/HotStringMaps.md) 23 | - [InvisibleCharacter](Docs/InvisibleCharacter.md) 24 | - [JSON](Docs/JSON.md) 25 | - [JsonFile](Docs/JsonFile.md) 26 | - [Method](Docs/Method.md) 27 | - [ObservableMap](Docs/ObservableMap.md) 28 | - [ObservableObj](Docs/ObservableObj.md) 29 | - [Queue](Docs/Queue.md) 30 | - [WinEvent](Docs/WinEvent.md) 31 | - [TextFile](Docs/TextFile.md) 32 | - [Timer](Docs/Timer.md) 33 | - [MesToast](Docs/MesToast.md) 34 | - [APPLocker](Docs/APPLocker.md) 35 | - [AutoClassify](Docs/AutoClassify.md) 36 | - [Everything](Docs/Everything.md) 37 | - [Ini](Docs/Ini.md) 38 | - [AutoInputBox](Docs/AutoInputBox.md) 39 | - [ParaChecker](Docs/ParaChecker.md) 40 | - [PathObj](Docs/PathObj.md) 41 | - [RunningSpeedTest](Docs/RunningSpeedTest.md) 42 | - [Script](Docs/Script.md) 43 | - [Switcher](Docs/Switcher.md) 44 | - [Stack](Docs/Stack.md) 45 | - [TimeChecker](Docs/TimeChecker.md) 46 | - [Type](Docs/Type.md) 47 | - [UMSS](Docs/UMSS.md) 48 | - [_GUI](Docs/_GUI.md) 49 | - [IPA_EN](Docs/IPA_EN.md) 50 | - [Function](Docs/Function.md) 51 | - [assert()](Docs/assert().md) 52 | - [Analyze()](Docs/Analyze().md) 53 | - [AnalyzeClassName()](Docs/AnalyzeClassName().md) 54 | - [AutoBind()](Docs/AutoBind().md) 55 | - [bulkMoveFile()](Docs/bulkMoveFile.md) 56 | - [ExcelToList()](Docs/ExcelToList().md) 57 | - [getClass()](Docs/getClass().md) 58 | - [getCurrentTime()](Docs/getCurrentTime.md) 59 | - [getFunc()](Docs/getFunc.md) 60 | - [Instanof()](Docs/Instanof().md) 61 | - [InstanceCheck()](Docs/InstanceCheck().md) 62 | - [loadMethod()](Docs/loadMethod().md) 63 | - [LogPrintln()](Docs/LogPrintln().md) 64 | - [rawCall()](Docs/rawCall.md) 65 | - [RandomStr()](Docs/RandomStr().md) 66 | - [showObj()](Docs/showObj().md) 67 | - [WatchFolder()](Docs/WatchFolder().md) 68 | - [Type()](Docs/Type().md) 69 | - [throwWithSt()](Docs/throwWithSt.md) 70 | - [UseCMD()](Docs/UseCMD.md) 71 | - [ObjDump()](Docs/ObjDump.md) 72 | - [ObjLoad()](Docs/ObjLoad.md) 73 | - [FileToClipboard()](Docs/FileToClipboard().md) 74 | - [RegexAllMatch()](Docs/RegexAllMatch().md) 75 | - [StringMethod](Docs/StringMethod.md) 76 | - [Test](Docs/TypeClass.md) 77 | - [TypeClass](Docs/TypeClass.md) 78 | - [MapFactory()](Docs/MapFactory().md) -------------------------------------------------------------------------------- /Test/LibTest_Stack.ahk: -------------------------------------------------------------------------------- 1 | #Include D:\AHKs\Dev\_CoreLib.ahk 2 | 3 | Hotstring("EndChars"," ") 4 | #Hotstring ? O Z 5 | 6 | #NoEnv 7 | 8 | #Warn All , StdOut 9 | #Warn ClassOverwrite , MsgBox 10 | #Warn LocalSameAsGlobal, Off 11 | 12 | #SingleInstance force 13 | 14 | Process, Priority,, High 15 | SetTitleMatchMode 2 16 | SendMode Input 17 | SetFormat,Float,0.2 18 | FileEncoding , UTF-8 19 | 20 | ;------------------------------ 21 | #Include D:\AHKs\Dev\_TempLib.ahk 22 | #Include D:\AHKs\ahk_lib\Test\Lib.ahk 23 | try{ 24 | theStack := new Stack("AADS") 25 | } 26 | catch,ex{ 27 | LogPrintln(ex,A_LineFile "(" A_LineNumber ")" " : " "ex >>> `r`n") 28 | } 29 | 30 | theStack := new Stack(10) 31 | 32 | try{ 33 | theStack.set(_List.LetterList) 34 | } 35 | catch,ex{ 36 | LogPrintln(ex,A_LineFile "(" A_LineNumber ")" " : " "ex >>> `r`n") 37 | } 38 | 39 | for i,v in _List.LetterList { 40 | theStack.push(v) 41 | LogPrintln(theStack,A_LineFile "(" A_LineNumber ")" " : " "theStack >>> `r`n") 42 | } 43 | 44 | LogPrintln(theStack,A_LineFile "(" A_LineNumber ")" " : " "theStack >>> `r`n") 45 | 46 | return 47 | 48 | theStack := new Stack(_List.LetterList) 49 | 50 | theEnum := theStack.getEnum() 51 | 52 | while(theEnum.next(v)){ 53 | LogPrintln(v,A_LineFile "(" A_LineNumber ")" " : " "v >>> `r`n") 54 | } 55 | 56 | 57 | 58 | return 59 | 60 | 61 | theStack := new Stack() 62 | 63 | LogPrintln(theStack.empty(),A_LineFile "(" A_LineNumber ")" " : " "theStack.empty() >>> `r`n") 64 | 65 | theStack := new Stack(_List.LetterList) 66 | 67 | LogPrintln(theStack.empty(),A_LineFile "(" A_LineNumber ")" " : " "theStack.empty() >>> `r`n") 68 | 69 | 70 | LogPrintln(theStack.search("A"),A_LineFile "(" A_LineNumber ")" " : " "theStack.search(""A"") >>> `r`n") 71 | 72 | 73 | LogPrintln(theStack,A_LineFile "(" A_LineNumber ")" " : " "theStack >>> `r`n") 74 | 75 | for i,v in _List.LetterList { 76 | theStack.push(v) 77 | } 78 | 79 | LogPrintln(theStack,A_LineFile "(" A_LineNumber ")" " : " "theStack >>> `r`n") 80 | 81 | LogPrintln(theStack.empty(),A_LineFile "(" A_LineNumber ")" " : " "theStack.empty() >>> `r`n") 82 | 83 | LogPrintln(theStack.length(),A_LineFile "(" A_LineNumber ")" " : " "theStack.length() >>> `r`n") 84 | 85 | LogPrintln(theStack.search("A"),A_LineFile "(" A_LineNumber ")" " : " "theStack.search(""A"") >>> `r`n") 86 | 87 | LogPrintln(theStack.search("XX"),A_LineFile "(" A_LineNumber ")" " : " "theStack.search(""XX"") >>> `r`n") 88 | 89 | 90 | LogPrintln(theStack.peek(),A_LineFile "(" A_LineNumber ")" " : " "theStack.peek() >>> `r`n") 91 | 92 | 93 | LogPrintln(theStack.pop(),A_LineFile "(" A_LineNumber ")" " : " "theStack.pop() >>> `r`n") 94 | LogPrintln(theStack.pop(),A_LineFile "(" A_LineNumber ")" " : " "theStack.pop() >>> `r`n") 95 | LogPrintln(theStack.pop(),A_LineFile "(" A_LineNumber ")" " : " "theStack.pop() >>> `r`n") 96 | 97 | 98 | #If WinActive(A_ScriptName) 99 | ;可以按下Alt+L查看最近运行的行 100 | 101 | /* 102 | !^l:: ;主要是为了防止和CapsLock+Alt+l冲突,所以多加了一个^ 103 | ListLines 104 | return 105 | 106 | !^h:: 107 | KeyHistory 108 | return 109 | 110 | !a:: 111 | send,{F5} 112 | return 113 | 114 | !^s:: 115 | ListVars 116 | return 117 | */ 118 | 119 | 120 | #If 121 | 122 | 123 | !q:: 124 | ExitApp 125 | return 126 | 127 | +!q:: 128 | Pause 129 | return 130 | -------------------------------------------------------------------------------- /Meta_Script.ahk: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | AHK元编程模板 - @心如止水_Zen 4 | - 主要功能:完全控制 __Get __Set __Call , 实现类的高度自定义 5 | - 小提示:是以"Test"这个类为例子搞的,到时候批量替换成自己的名字就行 6 | - 关于Class:会创建两个最外层的类,一个是 Test 一个是 TestBase ,编程的三个方法也要创建类,但是为了节约外部命名空间,所以放入 Test类 内部了. 7 | */ 8 | 9 | Class Test{ 10 | 11 | ;---------------------------------------------------------------------- 12 | 13 | class TestCallBase{ 14 | __Call(aThis,aFuncName,aParams*){ 15 | 16 | aNameLen:=StrLen(aName) 17 | 18 | if(ObjHasKey(this,aFuncName)){ ;这里的this指代,真正的元函数本身 19 | OutPut :=this[aFuncName].Call(aThis,aParams) ;第一个参数必须是 this ,另外,aParams已经是数组了 20 | return OutPut 21 | } 22 | else{ 23 | throwWithSt(_Ex.NoExistMethod) ;找不到方法,就抛出异常 24 | } 25 | 26 | } 27 | } 28 | 29 | ;---------------------------------------------------------------------- 30 | 31 | class TestGetBase{ 32 | __Call(aThis,aVariateName,aParams*){ 33 | 34 | if(ObjHasKey(this,aVariateName)){ 35 | OutPut :=this[aVariateName] 36 | return OutPut 37 | } 38 | else{ 39 | throwWithSt(_EX.NoExistVariate) ;如果找不到,那么就抛出值不存在异常 40 | return "" 41 | } 42 | } 43 | } 44 | 45 | ;---------------------------------------------------------------------- 46 | 47 | ;主要是为了实现保护写入,也就是保证里面的东西是常量 48 | 49 | class TestSetBase{ 50 | __Call(aThis,aVariateName,aParams*){ 51 | 52 | if(ObjHasKey(TestBase.__Get,aVariateName)){ 53 | throwWithSt(_EX.SetConst) ;如果已经存在,那么就抛出常量写入异常 54 | return "" 55 | } 56 | else{ 57 | throwWithSt(_EX.NoExistVariate) ;如果找不到,那么就抛出变量不存在异常 58 | } 59 | } 60 | } 61 | 62 | ;---------------------------------------------------------------------- 63 | 64 | } ;Test Class End 65 | 66 | ;---------------------------------------------------------------------- 67 | ;---------------------------------------------------------------------- 68 | 69 | Test.base:=new TestBase() 70 | 71 | ;---------------------------------------------------------------------- 72 | ;---------------------------------------------------------------------- 73 | 74 | 75 | Class TestBase{ 76 | Class __Set extends Test.TestSetBase{ 77 | ;主要目的就是为了防止写入,所以里面往往什么也不用填写 78 | } 79 | 80 | Class __Get extends Test.TestGetBase{ 81 | 82 | Static Msg := 0x111 83 | 84 | Static Open := 65300 ;打开窗口 85 | Static Reload := 65400 ;重启 86 | Static Edit := 65401 ;编辑 87 | Static Spy := 65402 ;Spy 88 | Static Pause := 65403 ;暂停 89 | Static Suspend := 65404 ;挂起 90 | Static Exit := 65405 ;退出 91 | 92 | Static Lines := 65406 ;最近运行 93 | Static Variable := 65407 ;变量信息 94 | Static HotKeys := 65408 ;热键信息 95 | Static KeyHistory := 65409 ;按键历史信息 96 | Static Refresh := 65410 ;刷新 信息窗口 97 | 98 | Static Help := 65411 ;打开CHM帮助文件 99 | Static WebSite := 65412 ;打开 https://www.autohotkey.com 100 | 101 | } 102 | 103 | ;---------------------------------------------------------------------- 104 | 105 | Class __Call extends Test.TestCallBase{ 106 | ;可以在里面填写各种方法 107 | FuncA(){ 108 | MsgBox,% A_LineNumber " : " A_ThisFunc 109 | return 110 | } 111 | 112 | FuncB(){ 113 | MsgBox,% A_LineNumber " : " A_ThisFunc 114 | return 115 | } 116 | 117 | FuncC(){ 118 | MsgBox,% A_LineNumber " : " A_ThisFunc 119 | return 120 | } 121 | 122 | } 123 | 124 | ;---------------------------------------------------------------------- 125 | 126 | } ;TestBase Class End 127 | -------------------------------------------------------------------------------- /UMSS.ahk: -------------------------------------------------------------------------------- 1 | 2 | 3 | class UMSS extends UMSSWithOutDestroy{ 4 | registeredKeys := Object() 5 | ;------------------------------ 6 | __New(aKey){ 7 | this.base.base := new UMSSWithOutDestroy(aKey) 8 | return this 9 | } 10 | ;------------------------------ 11 | register(keyName,theFunc,Options:=""){ 12 | this.registeredKeys[keyName] := theFunc 13 | this.base.base.register(keyName,theFunc,Options) 14 | return 15 | } 16 | ;------------------------------ 17 | Unregister(keyName){ 18 | this.base.base.Unregister(keyName) 19 | this.registeredKeys.Delete(keyName) 20 | return 21 | } 22 | ;------------------------------ 23 | destroy(){ 24 | for keyName,v in this.registeredKeys { 25 | this.Unregister(keyName) 26 | } 27 | this.registeredKeys := Object() 28 | return 29 | } 30 | } ;---------class UMSS End 31 | class UMSSWithOutDestroy{ 32 | Count := 0,key:="" 33 | static keys := Object() 34 | premiseFunc := "" 35 | ;------------------------------ 36 | empty(){ 37 | return 38 | } 39 | ;------------------------------ 40 | Unregister(keyName){ 41 | if(this.premiseFunc != ""){ 42 | this.IFOn() 43 | hotkey,% keyName,OFF 44 | this.IFOff() 45 | } 46 | return 47 | } 48 | ;------------------------------ 49 | IFOn(){ 50 | if(this.premiseFunc == "") 51 | this.premiseFunc := this.Premise.bind(this) 52 | theFunc := this.premiseFunc 53 | Hotkey, If, % theFunc 54 | return 55 | } 56 | ;------------------------------ 57 | IFOff(){ 58 | Hotkey, If 59 | return 60 | } 61 | ;------------------------------ 62 | premise(aName){ 63 | return GetKeyPhysicalState(this.key) 64 | } 65 | ;------------------------------ 66 | behavior(FuncObj){ 67 | this.DiscardCacheEvent() 68 | this.Count++ 69 | result := FuncObj.Call() 70 | return result 71 | } 72 | ;------------------------------ 73 | register(keyName,theFunc,Options:=""){ 74 | Func := this.behavior.Bind(this,theFunc) 75 | this.IFOn() 76 | hotkey,% keyName,% Func,% "On" " " Options 77 | this.IFOff() 78 | return 79 | } 80 | ;------------------------------ 81 | registerNewKey(){ 82 | theFunc := this.SendSrcKeyWhenItIsUp.bind(this) 83 | hotkey,% this.key,% theFunc,I100 84 | return 85 | } 86 | ;------------------------------ 87 | __New(key){ 88 | if(isObject(UMSSWithOutDestroy.keys[key])){ 89 | return UMSSWithOutDestroy.keys[key] 90 | } 91 | else{ 92 | this.key := key 93 | this.registerNewKey() 94 | UMSSWithOutDestroy.keys[key] := this 95 | return this 96 | } 97 | } 98 | ;------------------------------ 99 | 100 | SendSrcKeyWhenItIsUp(){ 101 | this.DiscardSelfEvent() 102 | KeyWait,% this.key 103 | this.SendSrcKey(this.key) 104 | return 105 | } 106 | ;------------------------------ 107 | SendSrcKey(EnableBlind:=true){ 108 | if(this.Count>0){ 109 | this.Count := 0 110 | } 111 | else{ 112 | Key := this.Key 113 | if(EnableBlind) 114 | Send,{Blind}{%Key%} 115 | else 116 | Send,{%Key%} 117 | } 118 | return 119 | } 120 | ;------------------------------ 121 | DiscardCacheEvent(thePriority := 0x7fffffff){ 122 | Thread, Interrupt , 0, 0 123 | Thread, Priority, %thePriority% 124 | return 125 | } 126 | DiscardSelfEvent(thePriority := -0x80000000){ 127 | Thread, Interrupt , 0, 0 128 | Thread, Priority, %thePriority% 129 | return 130 | } 131 | } ;---------class UMSSWithOutDestroy End 132 | -------------------------------------------------------------------------------- /Core/PathObj.ahk: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | 说明:对路径字符串进行各种操作 5 | */ 6 | ;---------------------------------------------------------------------- 7 | Class PathObj{ 8 | 9 | path := "" 10 | 11 | replaceName(SearchText,ReplaceText){ 12 | theName := StrReplace(this.name,SearchText,ReplaceText,OutputVarCount) 13 | if(OutputVarCount != 0) 14 | return this.reName(theName) 15 | else 16 | return false 17 | } 18 | 19 | delete(){ 20 | FileDelete, % this.getPath() 21 | return ErrorLevel 22 | } 23 | 24 | reName(aName){ 25 | 26 | Overwrite := Flag := false 27 | theNewPathObj := new PathObj(aName,new PathObj(this.dir)) 28 | 29 | if(this.isFile()){ 30 | FileMove, % this.getPath(), % theNewPathObj.getPath(), %Overwrite% 31 | if(error := Errorlevel){ 32 | LogPrintln(A_LineFile "(" A_LineNumber ")" " : " "文件重命名失败") 33 | } 34 | } 35 | else{ 36 | FileMoveDir,% this.getPath(), % theNewPathObj.getPath() , %Flag% 37 | if(error := Errorlevel){ 38 | LogPrintln(A_LineFile "(" A_LineNumber ")" " : " "目录重命名失败") 39 | } 40 | } 41 | 42 | if(error){ 43 | return false 44 | } 45 | else{ 46 | return theNewPathObj 47 | } 48 | } 49 | 50 | __New(aPath,aRootPathObj := ""){ 51 | this.path:=aPath 52 | if(aRootPathObj != ""){ 53 | Type.assertObj(this.rootPathObj := aRootPathObj) 54 | } 55 | this.assert() 56 | this.split() 57 | this.format() 58 | } 59 | 60 | isFile(aPath := ""){ 61 | if(aPath = "") 62 | aPath := this.path 63 | return !InStr(FileExist(aPath), "D") 64 | } 65 | 66 | isExist(aPath := ""){ 67 | if(aPath = "") 68 | aPath := this.path 69 | return FileExist(this.path) 70 | } 71 | 72 | assertExist(){ 73 | isExist := this.isExist() 74 | if(NOT(isExist)){ 75 | throw(_EX.NoExistFile " " this.getPath()) 76 | } 77 | return isExist 78 | } 79 | 80 | getPath(){ 81 | return this.path 82 | } 83 | 84 | ; 用于去除路径尾部多余的'\' 85 | format(){ 86 | if(this.name != ""){ 87 | this.path := this.dir "\" this.name 88 | } 89 | else if(this.name = ""){ 90 | this.path := this.dir 91 | } 92 | return 93 | } 94 | 95 | create(aPathList){ 96 | if(Type.isList(aPathList)){ 97 | theResultList := [] 98 | for i,v in aPathList { 99 | theResultList[i] := new PathObj(v) 100 | } 101 | return theResultList 102 | } 103 | else if(Type.isStr(aPathList)){ 104 | paths := aPathList 105 | paths := StrReplace(paths,"`r`n","`n") 106 | theResultList := StrSplit(paths, Delimiters := "`n") 107 | return PathObj.create(theResultList) 108 | } 109 | else{ 110 | ;~ throw() 111 | } 112 | } 113 | ;---------------------------------------------------------------------- 114 | split(){ 115 | SplitPath, % this.path, name, dir, ext, name_no_ext, drive 116 | this.name:=name,this.dir:=dir,this.ext:=ext,this.name_no_ext:=name_no_ext,this.drive:=drive 117 | return 118 | } 119 | 120 | ;---------------------------------------------------------------------- 121 | /* 122 | 说明:用正则表达式检查路径 123 | */ 124 | assert(){ 125 | if(Type.isObj(this.rootPathObj)){ 126 | this.path := this.rootPathObj.getPath() "\" this.path 127 | } 128 | if(Type.isPath(this.path)) 129 | return 130 | else{ 131 | this.path := A_WorkingDir "\" this.path 132 | return Type.assertPath(this.path) 133 | } 134 | } 135 | 136 | } 137 | ;--------------------------Class Path End 138 | -------------------------------------------------------------------------------- /Everything.ahk: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | 调用 Everthing 进行搜索 5 | */ 6 | 7 | ;提取自 RunAny - 一劳永逸的快速启动 @hui-Zz 8 | ;主要改动: 1.精简方法名 2.调用 __New 时直接获取Dll信息 9 | ;需要保证:1.根目录或指定目录下存在 Everthing的DLL 2.Everthing程序正在运行 10 | ;[修改于AHK论坛,IPC方式和everything进行通讯] 11 | 12 | 13 | ;~ protect(Everything) 14 | 15 | class Everything{ 16 | 17 | 18 | key:="",MatchWholeWord:=false,DLL:=false 19 | ;---------------------------------------------------------------------- 20 | ;获取EverthingDll 21 | 22 | getDll(DLLPath:=""){ 23 | if(DLLPath="") 24 | DLLPath:=A_ScriptDir 25 | DLL:=false 26 | if(FileExist(DLLPath "\Everything.dll")){ 27 | DLL:=DllCall("LoadLibrary", str, "Everything.dll") ? "Everything.dll" : "Everything64.dll" 28 | } 29 | else if(FileExist(DLLPath "\Everything64.dll")){ 30 | DLL:=DllCall("LoadLibrary", str, "Everything64.dll") ? "Everything64.dll" : "Everything.dll" 31 | } 32 | return DLL 33 | } 34 | 35 | ;---------------------------------------------------------------------- 36 | 37 | 38 | __New(DLLPath:=""){ 39 | 40 | 41 | this.assertEverythingExist() 42 | Dll:=this.getDll(DLLPath) 43 | 44 | if Not(Dll){ 45 | throwWithSt("Not Found Everthing.DLL/Everthing64.DLL.") 46 | } 47 | 48 | this.Dll:=Dll 49 | 50 | this.hModule := DllCall("LoadLibrary", str, this.DLL) 51 | 52 | return this 53 | } 54 | 55 | __Delete(){ 56 | DllCall("FreeLibrary", "UInt", this.hModule) 57 | return 58 | } 59 | 60 | ;---------------------------------------------------------------------- 61 | afEverythingExist(){ 62 | if Not(this.isEverythingExist()){ 63 | throwWithSt("process ""Everything.exe"" is not Exist.") 64 | } 65 | return 66 | } 67 | 68 | ;---------------------------------------------------------------------- 69 | isEverythingExist(){ 70 | Process, Exist , % "Everything.exe" 71 | return ErrorLevel 72 | } 73 | ;---------------------------------------------------------------------- 74 | 75 | getSearchResultList(){ 76 | theLen:=this.Count() 77 | Str:=this.GetFullPath(0) 78 | 79 | StrList:=[] 80 | 81 | loop,%theLen%{ 82 | StrList.push(this.GetFullPath(A_Index-1)) 83 | } 84 | return StrList 85 | } 86 | 87 | ;---------------------------------------------------------------------- 88 | 89 | ;设置关键词 90 | SetKey(aValue){ 91 | this.assertEverythingExist() 92 | this.key := aValue 93 | DllCall(this.DLL "\Everything_SetSearch",str,this.key) 94 | return 95 | } 96 | 97 | ;---------------------------------------------------------------------- 98 | 99 | ;设置全字匹配 100 | SetMatchWholeWord(aValue){ 101 | this.MatchWholeWord := aValue 102 | DllCall(this.DLL "\Everything_SetMatchWholeWord",int,aValue) 103 | return 104 | } 105 | 106 | ;执行搜索动作 (执行后直接返回匹配数) 107 | Search(aValue=1){ 108 | this.assertEverythingExist() 109 | DllCall(this.DLL "\Everything_Query",int,aValue) 110 | return 111 | } 112 | 113 | ;返回匹配总数 114 | Count(){ 115 | return DllCall(this.DLL "\Everything_GetTotResults") 116 | } 117 | 118 | ;返回文件名 119 | GetFileName(aValue){ 120 | return StrGet(DllCall(this.DLL "\Everything_GetResultFileName",int,aValue)) 121 | } 122 | 123 | ;返回文件全路径 124 | GetFullPath(aValue,cValue=128){ 125 | VarSetCapacity(bValue,cValue*2) 126 | DllCall(this.DLL "\Everything_GetResultFullPathName",int,aValue,str,bValue,int,cValue) 127 | return bValue 128 | } 129 | 130 | ;获取 Everything 版本 131 | GetVersionString(){ 132 | fmajor := DllCall(this.DLL "\Everything_GetMajorVersion") 133 | fminor:=DllCall(this.DLL "\Everything_GetMinorVersion") 134 | frevision:=DllCall(this.DLL "\Everything_GetRevision") 135 | return Format("{}.{}.{}", fmajor, fminor, frevision) 136 | } 137 | 138 | 139 | } 140 | -------------------------------------------------------------------------------- /IO/Ini.ahk: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | 说明:用于读写 Ini 文件的 Ini 对象 和 Section 对象 5 | */ 6 | class Ini { 7 | path:="" 8 | ;---------------------------------------------------------------------- 9 | 10 | __New(aPath){ 11 | new PathObj(aPath) 12 | this.path:=aPath 13 | return this 14 | } 15 | ;---------------------------------------------------------------------- 16 | ;引 17 | readAllIni(){ 18 | FileRead,allIni,% this.path 19 | this.allIni := allIni 20 | return 21 | } 22 | ;---------------------------------------------------------------------- 23 | ;引 24 | trimBlankLine(){ 25 | _Container.deepDelete(this.theMap,aRegEx:="^(?!.*=).*$") 26 | return 27 | } 28 | ;---------------------------------------------------------------------- 29 | ;引 30 | dividedBySection(){ 31 | theLineSpliter:=new Spliter(this.allIni,"`r`n") 32 | List:=theLineSpliter.split() 33 | theSectionIndexList:=_List.OldMatch(List,"\[.*\]") 34 | _List.RegExReplace(List,"\[(.*)\]","$1") 35 | this.theMap:=_List.getMapByIndex(List,theSectionIndexList*) 36 | return 37 | } 38 | ;---------------------------------------------------------------------- 39 | ;引 40 | dividedByKeyValue(){ 41 | aSpliter:=new Spliter("","=") 42 | aSpliter.deleteBlankelement:=false 43 | aSpliter.elementTrim:=false 44 | _Container.deepSplit(this.theMap,aSpliter) 45 | return 46 | } 47 | ;---------------------------------------------------------------------- 48 | ;引 49 | swapToMap(){ 50 | _Container.swapToMap(this.theMap) 51 | _Container.shuck(this.theMap) 52 | _Container.swapToMaps(this.theMap) 53 | return 54 | } 55 | 56 | ;---------------------------------------------------------------------- 57 | getMap(){ 58 | this.readAllIni() 59 | this.dividedBySection() 60 | this.trimBlankLine() 61 | this.dividedByKeyValue() 62 | this.swapToMap() 63 | return this.theMap 64 | } 65 | ;---------------------------------------------------------------------- 66 | getSection(aSection){ 67 | newSection:=this.Section.__New(this,aSection) 68 | return newSection 69 | } 70 | 71 | ;---------------------------------------------------------------------- 72 | class Section{ 73 | theIni:="",section:="" 74 | ;---------------------------------------------------------------------- 75 | __New(aIni,aSection){ 76 | this.theIni:=aIni 77 | this.section:=aSection 78 | return this 79 | } 80 | ;---------------------------------------------------------------------- 81 | read(aKey,aDefault:=""){ 82 | IniRead, OutVar, % this.theIni.path, % this.section, %aKey% , %aDefault% 83 | 84 | if (aDefault="") AND (OutVar="ERROR") 85 | throwWithSt(_Ex.NoExistKey) 86 | 87 | return OutVar 88 | } 89 | ;---------------------------------------------------------------------- 90 | write(aKey,value){ 91 | IniWrite, %value%, % this.theIni.path, % this.section, %aKey% 92 | return 93 | } 94 | ;---------------------------------------------------------------------- 95 | writeByMap(aMap){ 96 | for aKey , value in aMap { 97 | IniWrite, %value%, % this.theIni.path, % this.section, %aKey% 98 | } 99 | return 100 | } 101 | 102 | ;---------------------------------------------------------------------- 103 | 104 | readInMap(aMap,aKey,aDefault:=""){ 105 | data:=this.read(aKey,aDefault) 106 | aMap[aKey]:=data 107 | return 108 | } 109 | ;---------------------------------------------------------------------- 110 | getMap(aKeys*){ 111 | theMap:=getEmptyMap(aKeys*) 112 | for key,v in theMap { 113 | this.readInMap(theMap,key,aDefault:="") 114 | } 115 | return theMap 116 | } 117 | ;---------------------------------------------------------------------- 118 | 119 | } 120 | } 121 | ;-----------class Ini End -------------------------------------------------------------------------------- /Docs/ObservableMap.md: -------------------------------------------------------------------------------- 1 | # ObservableMap Class 2 | 3 | 1. 性质:实例类 4 | 2. 开发目的:带有监听器的 Map,类似 JavaFX 中的 ObservableMap 5 | 6 | 为了与已有的「关联数组」做出明确区分,ObservableMap 对 __Set() 做出限制,除了写入 "Field" (初始化时)之外,任何的写入都是不被允许的。 7 | 8 | 另外,这个和「关联数组」是不同的,获取数据用 get(),加入不是用 push(),而是用 put(),删除依然是 remove(),新增了 clear() 清除所有内容。 9 | 10 | ## 域 Field 11 | 12 | ### Field 13 | 14 | 为避开对 __Set() 做出限制,而设置的变量。 15 | 16 | ### Change 17 | 18 | 内部类,用于传递信息给 Listener 19 | 20 | #### __New(aObservableMap,aRemoved,aRemovedMap,aAdded,aAddedMap) 21 | 22 | aObservableMap - ObservableMap本身 23 | 24 | aRemoved - 是否移除了 `Key-Vaule` 25 | 26 | aRemovedMap - 移除的 subMap 27 | 28 | aAdded - 是否添加了 `Key-Vaule` 29 | 30 | aAddedMap- 添加的 subMap 31 | 32 | #### getMap() 33 | 34 | 获取 Change 所属的 ObservableMap 35 | 36 | #### wasRemoved() 37 | 38 | Change 是否为移除 39 | 40 | #### wasAdded() 41 | 42 | Change 是否为添加 43 | 44 | #### getValueRemoved() 45 | 46 | 获取移除的 subMap 47 | 48 | #### getValueAdded() 49 | 50 | 获取添加的 subMap 51 | 52 | #### size() 53 | 54 | 获取 Map 中元素的数量 55 | 56 | ## 方法 Method 57 | ### __New(aMap:="") 58 | 59 | #### 参数 Parameters: 60 | 61 | - aMap - 生成ObservableMap的初始Map 62 | 63 | #### 返回 Returns: 64 | 65 | ObservableMap 66 | ### put(aKeyValue*) 67 | 放入 `key-value` 对 68 | 69 | #### 参数 Parameters: 70 | 71 | - aKeyValue* :被添加的 `key-value` 对 72 | 73 | #### 返回 Returns: 74 | 75 | null 76 | ### remove(aKey*) 77 | 78 | 批量移除 `key-value` 对 79 | 80 | #### 参数 Parameters: 81 | 82 | - aKey* :被移除的 `Key` 列表 83 | 84 | #### 返回 Returns: 85 | 86 | null 87 | ### clear() 88 | 89 | 清除所有`key-value` 对 90 | 91 | #### 参数 Parameters: 92 | 93 | #### 返回 Returns: 94 | 95 | null 96 | ### get(aKey) 97 | 98 | 根据 `key` 获取某个 `value` 99 | 100 | #### 参数 Parameters: 101 | 102 | - 需要获取的 `value` 对应的 `key` 103 | 104 | #### 返回 Returns: 105 | 106 | Obj 107 | ### addListener(aMethod) 108 | 109 | #### 参数 Parameters: 110 | 111 | - 添加监听器 112 | 监听器只有一个 `aChange` 参数 113 | 114 | #### 返回 Returns: 115 | 116 | null 117 | 118 | ## 示例 Example 119 | 120 | ```AutoHotKey 121 | map := new ObservableMap(_Container.LetterAndNumberMap) 122 | map.addListener(new Method(Listeners.print,Listeners)) 123 | 124 | LogPrintln(map.get("A"),A_LineFile "(" A_LineNumber ")" " : " "map.get(""A"") >>> `r`n") 125 | 126 | map.remove("A","B") 127 | map.remove("C") 128 | map.put("W","18") 129 | map.put("T","20","X","24") 130 | map.clear() 131 | 132 | 133 | map := new ObservableMap(_Container.LetterAndNumberMap) 134 | map.addListener(new Method(Listeners.print,Listeners)) 135 | 136 | 137 | map["A"] 138 | ;~ map["A"] := "1" 139 | map.no() 140 | ``` 141 | 142 | 143 | 144 | ```AutoHotKey 145 | D:\AHKs\Dev\TPDD_ObservableMap.ahk(28) : map.get("A") >>> 146 | 1 147 | 减少: 148 | D:\AHKs\Dev\TPDD_ObservableMap.ahk(62) : aChange.getValueRemoved() >>> 149 | {A:1,B:2} 150 | 目前: 151 | D:\AHKs\Dev\TPDD_ObservableMap.ahk(65) : aChange.getMap() >>> 152 | {__Instance:ObservableMap,C:3,D:4,E:5,F:6,G:7,H:8,I:9,J:0} 153 | 减少: 154 | D:\AHKs\Dev\TPDD_ObservableMap.ahk(62) : aChange.getValueRemoved() >>> 155 | {C:3} 156 | 目前: 157 | D:\AHKs\Dev\TPDD_ObservableMap.ahk(65) : aChange.getMap() >>> 158 | {__Instance:ObservableMap,D:4,E:5,F:6,G:7,H:8,I:9,J:0} 159 | 增加: 160 | D:\AHKs\Dev\TPDD_ObservableMap.ahk(58) : aChange.getValueAdded() >>> 161 | {W:18} 162 | 目前: 163 | D:\AHKs\Dev\TPDD_ObservableMap.ahk(65) : aChange.getMap() >>> 164 | {__Instance:ObservableMap,D:4,E:5,F:6,G:7,H:8,I:9,J:0,W:18} 165 | 增加: 166 | D:\AHKs\Dev\TPDD_ObservableMap.ahk(58) : aChange.getValueAdded() >>> 167 | {T:20,X:24} 168 | 目前: 169 | D:\AHKs\Dev\TPDD_ObservableMap.ahk(65) : aChange.getMap() >>> 170 | {__Instance:ObservableMap,D:4,E:5,F:6,G:7,H:8,I:9,J:0,T:20,W:18,X:24} 171 | 减少: 172 | D:\AHKs\Dev\TPDD_ObservableMap.ahk(62) : aChange.getValueRemoved() >>> 173 | {D:4,E:5,F:6,G:7,H:8,I:9,J:0,T:20,W:18,X:24} 174 | 目前: 175 | D:\AHKs\Dev\TPDD_ObservableMap.ahk(65) : aChange.getMap() >>> 176 | {__Instance:ObservableMap,} 177 | ``` 178 | 179 | -------------------------------------------------------------------------------- /APP/Script.ahk: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | -;已知问题: 4 | 1,发送消息的脚本,如果是通过 #SingleInstance force 重启的,不会执行成功 5 | 2,不支持 Unicode字符,原因未知,可能是 AHK元编程 的BUG 6 | */ 7 | 8 | 9 | Class Script{ 10 | __New(InputTitle){ 11 | ObjRawSet(this,"InputTitle",InputTitle) ;为了绕过元函数而用,如果不用,就会陷入死循环 12 | return this 13 | } 14 | ;---------------------------------------------------------------------- 15 | 16 | class ScriptCallBase{ 17 | __Call(aThis,aFuncName,aParams*){ 18 | 19 | aDetectHiddenWindows:="On" 20 | 21 | aFuncId:=getFuncId(A_ThisFunc) 22 | _Win.SwapDetectHidden(aFuncId,aDetectHiddenWindows) 23 | 24 | aNameLen:=StrLen(aFuncName) 25 | 26 | the__Get:=ObjRawGet(ScriptBase,"__Get") ;为了绕过元函数而用,如果不用,就会陷入死循环 27 | 28 | if(ObjHasKey(the__Get,aFuncName)){ ;这里的this指代,真正的元函数本身 29 | ; DeBugDeepPrintln(aFuncName,"aFuncName >>> ") 30 | 31 | theMsg:=the__Get["Msg"],wParam:=the__Get[aFuncName] 32 | 33 | InputTitle := aThis.InputTitle 34 | 35 | ResultTitle := InputTitle " ahk_class AutoHotkey" 36 | 37 | ;如果没有发现窗口,就抛出异常 38 | if(MesObj=false){ 39 | throwWithSt(_EX.NoExistWin) 40 | } 41 | 42 | MesObj:=_Win.Analyze(ResultTitle,true,false) 43 | 44 | MesStr:=MesObj["Str"] 45 | 46 | ResultWinId := MesObj["WinId"] 47 | 48 | PostMessage,%theMsg%,%wParam%,,,%ResultWinId% 49 | 50 | 51 | _Win.SwapDetectHidden(aFuncId,aDetectHiddenWindows) 52 | 53 | return MesObj ;返回对应窗口的信息 54 | } 55 | else{ 56 | throwWithSt(_Ex.NoExistMethod) ;找不到方法,就抛出异常 57 | } 58 | 59 | } 60 | } 61 | 62 | ;---------------------------------------------------------------------- 63 | 64 | class ScriptGetBase{ 65 | __Call(aThis,aVariateName,aParams*){ 66 | 67 | if(ObjHasKey(this,aVariateName)){ 68 | OutPut :=this[aVariateName] 69 | return OutPut 70 | } 71 | else{ 72 | throwWithSt(_EX.NoExistVariate) ;如果找不到,那么就抛出值不存在异常 73 | return "" 74 | } 75 | } 76 | } 77 | 78 | ;---------------------------------------------------------------------- 79 | 80 | ;主要是为了实现保护写入,也就是保证里面的东西是常量 81 | 82 | class ScriptSetBase{ 83 | __Call(aThis,aVariateName,aParams*){ 84 | 85 | the__Get:=ObjRawGet(ScriptBase,"__Get") ;为了绕过元函数而用,如果不用,就会陷入死循环 86 | 87 | if(ObjHasKey(the__Get,aVariateName)){ 88 | throwWithSt(_EX.SetConst) ;如果已经存在,那么就抛出常量写入异常 89 | return "" 90 | } 91 | else{ 92 | throwWithSt(_EX.NoExistVariate) ;如果找不到,那么就抛出变量不存在异常 93 | } 94 | } 95 | } 96 | 97 | ;---------------------------------------------------------------------- 98 | 99 | } ;Script Class End 100 | 101 | ;---------------------------------------------------------------------- 102 | ;---------------------------------------------------------------------- 103 | 104 | Script.base:=new ScriptBase() 105 | 106 | ;---------------------------------------------------------------------- 107 | ;---------------------------------------------------------------------- 108 | 109 | 110 | Class ScriptBase{ 111 | Class __Set extends Script.ScriptSetBase{ 112 | ;主要目的就是为了防止写入,所以里面往往什么也不用填写 113 | } 114 | 115 | Class __Get extends Script.ScriptGetBase{ 116 | 117 | Static Msg := 0x111 118 | 119 | Static Open := 65300 ;打开窗口 120 | Static Reload := 65400 ;重启 121 | Static Edit := 65401 ;编辑 122 | Static Spy := 65402 ;Spy 123 | Static Pause := 65403 ;暂停 124 | Static Suspend := 65404 ;挂起 125 | Static Exit := 65405 ;退出 126 | 127 | Static Lines := 65406 ;最近运行 128 | Static Variable := 65407 ;变量信息 129 | Static HotKeys := 65408 ;热键信息 130 | Static KeyHistory := 65409 ;按键历史信息 131 | Static Refresh := 65410 ;刷新 信息窗口 132 | 133 | Static Help := 65411 ;打开CHM帮助文件 134 | Static WebSite := 65412 ;打开 https://www.autohotkey.com 135 | 136 | } 137 | 138 | ;---------------------------------------------------------------------- 139 | 140 | Class __Call extends Script.ScriptCallBase{ 141 | ;啥也没有,别看了 142 | 143 | } 144 | 145 | ;---------------------------------------------------------------------- 146 | 147 | } ;ScriptBase Class End 148 | -------------------------------------------------------------------------------- /APP/switcher.ahk: -------------------------------------------------------------------------------- 1 | 2 | class Switcher{ 3 | static Options := "Max" 4 | ,winStackMaxSize := 300 5 | ,winStack := new Stack(Switcher.winStackMaxSize) 6 | /* 7 | TODO: 可以为每个 Switcher 提供额外的配置,如果想用默认的,那就直接用Switcher.xx(),如果想使用一个额外的配置,那么就Switcher.xx().xx(),这包含了一些常用的预设配置;如果要完全自定义,那么就 theSwitcher := new Switcher(); theSwitcher.xxx(); 8 | 主要是为了「隐藏窗口」,以及「wintitle匹配规则」,等等设置,但是暂时先不需要,等我遇到之后再做. 9 | */ 10 | /* 11 | TODO:关于方法之间参数的调用,传参还是经过域的问题.一个Switcher实例代表的是一种「切换设置」,所以关于「窗口」的数据都是经过参数的,而所有关于「设置」的参数都是经过域的. 12 | */ 13 | getLastWin(aWinTitle,winPath:=""){ 14 | theLastWin := _Win.Analyze(aWinTitle,"",false,winPath) ;分析出一个 15 | LogPrintln(theLastWin,A_LineFile "(" A_LineNumber ")" " : " "theLastWin >>> `r`n") 16 | theWins := _Wins.AnalyzeOnMap(aWinTitle,"",winPath) ;分析出所有符合条件的 Map 17 | LogPrintln(theWins,A_LineFile "(" A_LineNumber ")" " : " "theWins >>> `r`n") 18 | if(theWins.Count()<=1){ ;如果符合条件的只有一个,那么直接返回 19 | return theLastWin 20 | } 21 | theEnum := Switcher.winStack.getEnum() ;遍历之前保存的 22 | while(theEnum.next(v)){ 23 | theWin := theWins[v.id] ;从前到后找,如果匹配符合的,那么就可以返回它 24 | if(Type.isObj(theWin)){ 25 | theLastWin := theWin 26 | break 27 | } 28 | } 29 | return theLastWin 30 | ;更改的方法是让 Analyze 支持根据 Path 进行筛选 31 | } 32 | ;------------------------------ 33 | toggle(aWinTitle,winPath:=""){ 34 | theLastWin := this.getLastWin(aWinTitle,winPath) 35 | LogPrintln(theLastWin,A_LineFile "(" A_LineNumber ")" " : " "theLastWin >>> `r`n") 36 | return this.p_ActivateOrMini(theLastWin.WinId) 37 | } 38 | ;------------------------------ 39 | runFuncObj(funcObj){ 40 | return funcObj.call() 41 | } 42 | ;------------------------------ 43 | run(aWinTitle,aPathOrFuncObj,aWait = 0){ 44 | if(Type.isStr(aPathOrFuncObj)){ 45 | path := aPathOrFuncObj 46 | funcObj := new Method(this.p_Run,this,path) 47 | } 48 | else{ 49 | funcObj := aPathOrFuncObj 50 | } 51 | FuncObjReturn := this.runFuncObj(funcObj) 52 | if((aWait != 0) AND (aWait.isNumber())){ 53 | WinWait , %aWinTitle%, , %aWait% 54 | { 55 | if(ErrorLevel){ 56 | LogPrintln(ex,A_LineFile "(" A_LineNumber ")" " : " "ex >>> `r`n") 57 | throw(_EX.NoExistWin "(可能是窗口未能如期出现)") 58 | } 59 | WinActivate , %aWinTitle% 60 | } 61 | } 62 | } 63 | ;------------------------------ 64 | switch(aWinTitle,aPathOrFuncObj,aWait = 0,winPath:=""){ 65 | theWinExist := _Win.Exist(aWinTitle,winPath) 66 | if(theWinExist){ 67 | this.toggle(aWinTitle,winPath) 68 | } 69 | else{ 70 | this.run(aWinTitle,aPathOrFuncObj,aWait) 71 | } 72 | return theWinExist 73 | } 74 | ;------------------------------ 75 | p_ActivateOrMini(aWinTitle){ 76 | if(Type.isNS(aWinTitle)) 77 | return false 78 | LogPrintln(aWinTitle,A_LineFile "(" A_LineNumber ")" " : " "aWinTitle >>> `r`n") 79 | theWinExist := WinExist(aWinTitle) 80 | if(WinActive(aWinTitle)){ 81 | WinMinimize,%aWinTitle% 82 | } 83 | else{ 84 | LogPrintln(aWinTitle,A_LineFile "(" A_LineNumber ")" " : " "aWinTitle >>> `r`n") 85 | WinActivate,%aWinTitle% 86 | ;~ this.p_ifJavaSwingReDraw(aWinTitle) 87 | ;不仅Java要重绘,任何窗口都重绘吧,希望能解决VSCode的WSL远程模式的卡顿问题 88 | WinSet, Redraw ,,%aWinTitle% 89 | } 90 | return theWinExist 91 | } 92 | p_getWorkingDir(aPath){ 93 | ;这是为了去除可能存在的命令行参数 94 | if(RegExMatch(aPath, "O)^(.+) ([^ ]+)$",SubPat)) 95 | aPath := SubPat.1 96 | else if(RegExMatch(aPath, "O)^`"(.+)`"",SubPat)) 97 | aPath := SubPat.1 98 | return (new PathObj(aPath)).dir 99 | } 100 | ;------------------------------ 101 | p_Run(aPath){ 102 | run,%aPath%,% this.p_getWorkingDir(aPath),% this.Options,OutputVarPID 103 | return OutputVarPID 104 | } 105 | ;------------------------------ 106 | p_ifJavaSwingReDraw(aWinTitle){ 107 | if(WinActive("ahk_class SunAwtFrame")){ 108 | WinSet, Redraw ,,%aWinTitle% 109 | } 110 | return 111 | } 112 | } 113 | 114 | 115 | 116 | ;------------------------------ 117 | 118 | global SwitcherEvent 119 | 120 | SwitcherEvent := new SwitcherEventBase() 121 | 122 | class SwitcherEventBase extends WinEvent{ 123 | OnSwitched(aWinObjs){ 124 | Switcher.winStack.push(aWinObjs[1]) 125 | } 126 | } 127 | 128 | -------------------------------------------------------------------------------- /GUI/WinEvent.ahk: -------------------------------------------------------------------------------- 1 | 2 | ;-------------------------------------------------------------------------------------------------------------- 3 | class WinEvent{ 4 | Usable := true 5 | ;------------------------------ 6 | disable(){ 7 | this.Usable := false 8 | return 9 | } 10 | ;------------------------------ 11 | 12 | enable(){ 13 | this.Usable := true 14 | return 15 | } 16 | 17 | ;------------------------------ 18 | findFuncNameFromWParam(aWParam){ 19 | for k,v in WinEvent.wParam { 20 | if(v = aWParam){ 21 | ;~ LogPrintln(aWParam,A_LineFile "(" A_LineNumber ")" " : " "aWParam >>> `r`n") 22 | theFuncName := "On" k 23 | ;~ LogPrintln(theFuncName,A_LineFile "(" A_LineNumber ")" " : " "theFuncName >>> `r`n") 24 | return theFuncName 25 | } 26 | 27 | } 28 | } 29 | ;------------------------------ 30 | class wParam{ 31 | static Created := 1 32 | ,Destroyed := 2 33 | ,Activate := 3 34 | ,Activated := 4 35 | ,GetMinRect := 5 36 | ,ReDraw := 6 37 | ,Taskman := 7 38 | ,Language := 8 39 | ,Sysmenu := 9 40 | ,Endtask := 10 41 | ,AccessibilityState := 11 42 | ,Appcommand := 12 43 | ,Windowreplaced := 13 44 | ,Windowreplacing := 14 45 | ,FullScreen := 53 46 | ,ExitFullScreen := 54 47 | ,Switched := 32772 48 | 49 | ;1 顶级窗体被「创建」 50 | ;2 顶级窗体即将被「关闭」 51 | ;3 SHELL 的主窗体将被激活 52 | ;4 顶级窗体被激活 53 | ;5 顶级窗体被最大化或最小化 54 | ;6 Windows 任务栏被刷新,也可以理解成「标题变更」 55 | ;7 任务列表的内容被选中 56 | ;8 中英文切换或输入法切换 57 | ;9 显示系统菜单 58 | ;10 顶级窗体被强制关闭 59 | ;11 用于残障人士的辅助功能 60 | ;12 没有被程序处理的APPCOMMAND。见WM_APPCOMMAND 61 | ;13 wParam=被替换的顶级窗口的hWnd 62 | ;14 wParam=替换顶级窗口的窗口hWnd 63 | ;&H8000& 掩码 64 | ;53 全屏 65 | ;54 退出全屏 66 | ;32772 窗口切换 67 | ;------------------------------ 68 | } 69 | ;------------------------------ 70 | __New(){ 71 | this.ShellHook() 72 | return this 73 | } 74 | ;------------------------------ 75 | ShellMessagePrint(wParam, lParam,msg:="", hwnd:=""){ 76 | printMap := Object("Paras",Object("wParam",wParam, "lParam",lParam, "msg",msg, "hwnd",hwnd)) 77 | return LogPrintln(printMap) 78 | } 79 | ;------------------------------ 80 | ShellMessage(wParam, lParam, msg:="", hwnd:="") { 81 | theFindFuncName := this.findFuncNameFromWParam(wParam) 82 | theFunc := this[theFindFuncName] 83 | if(theFunc = "") 84 | return 85 | 86 | ;~ LogPrintln(theFindFuncName,A_LineFile "(" A_LineNumber ")" " : " "theFindFuncName >>> `r`n") 87 | ;~ this.ShellMessagePrint(wParam, lParam, msg, hwnd) 88 | ;~ LogPrintln(theFunc,A_LineFile "(" A_LineNumber ")" " : " "theFunc >>> `r`n") 89 | ;~ LogPrintln(IsFunc(theFunc),A_LineFile "(" A_LineNumber ")" " : " "IsFunc(theFunc) >>> `r`n") 90 | 91 | wParam := wParam.toHex() 92 | lParam := lParam.toHex() 93 | msg := msg.toHex() 94 | hwnd := hwnd.toHex() 95 | 96 | theMethod := new Method(theFunc,this) 97 | if(theMethod != ""){ 98 | return theMethod.Call(_Wins.Analyze("ahk_id " . lParam)) 99 | } 100 | return 101 | } 102 | 103 | ;------------------------------ 104 | ShellMessage_Base(wParam, lParam, msg:="", hwnd:="") { 105 | if(Not(this.Usable)){ 106 | return 107 | } 108 | return this.ShellMessage(wParam, lParam, msg, hwnd) 109 | } 110 | ShellHookPrint(MsgNum1,MsgNum,Str,UInt){ 111 | theObj := Object("MsgNum1",MsgNum1,"MsgNum",MsgNum,"Str",Str,"UInt",UInt) 112 | LogPrintln(theObj,A_LineFile "(" A_LineNumber ")" " : " "theObj >>> `r`n") 113 | } 114 | ;------------------------------ 115 | ShellHook(){ 116 | Gui +LastFound 117 | hWnd := WinExist() ;返回脚本自身窗口的ID(hWnd) 118 | MsgNum1 := DllCall("RegisterShellHookWindow",UInt,hWnd) 119 | ;~ LogPrintln(MsgNum1,A_LineFile "(" A_LineNumber ")" " : " "MsgNum1 >>> `r`n") 120 | MsgNum := DllCall("RegisterWindowMessage", Str,"SHELLHOOK") 121 | ShellMessageMethod := new Method(this.ShellMessage_Base,this) 122 | ;~ this.ShellHookPrint(MsgNum1,MsgNum,Str,UInt) 123 | OnMessage(MsgNum,ShellMessageMethod) 124 | return 125 | } 126 | ;------------------------------ 127 | } ;---------class WinEvent End 128 | ;------------------------------ -------------------------------------------------------------------------------- /style/website.css: -------------------------------------------------------------------------------- 1 | /* 2 | styles tweaked from the original AutoHotkey css 3 | From:GenDocs @fincs https://github.com/yoke233/genSets 4 | */ 5 | 6 | body { 7 | font-family: "Arial", Listns-serif; 8 | font-size: 95%; 9 | color: black; 10 | border: 0; 11 | background-color: #FFFFFF; 12 | line-height: 145%; 13 | margin: 1em 2em; 14 | } 15 | p { 16 | margin-top: 0.7em; 17 | margin-bottom: 0.7em; 18 | } 19 | 20 | h1 { 21 | font-size: 2em; 22 | font-weight: bold; 23 | /* margin: 0; */ 24 | 25 | /* padding: 0 0 0.5em 4px; */ 26 | /* border-bottom-style: ridge; */ 27 | border-bottom-color: #FFFFFF; 28 | border-bottom-width: 2px; 29 | color: darkblue; 30 | } 31 | h2 { 32 | font-size: 144%; 33 | font-weight: bold; 34 | font-family: Arial, Helvetica, Listns-serif, "MS Listns serif"; 35 | color: #A04040; 36 | margin: 1.5em 0 0.5em 0; 37 | padding: 0.1em 0 0.1em 0; 38 | } 39 | h3 { 40 | font-size: 111%; 41 | font-weight: bold; 42 | margin: 1.0em 0 0.5em 0; 43 | padding: 0.1em 0 0.1em 0; 44 | color: #00AA00; 45 | } 46 | h4 { 47 | font-size: 100%; 48 | margin: 0.7em 0; 49 | border-bottom: 1px solid lightgrey; 50 | } 51 | 52 | ul, ol {margin-top: 0.7em; margin-bottom: 0.7em;} 53 | li {margin-top: 0.2em; margin-bottom: 0.2em; margin-left: -0.75em;} 54 | 55 | a {text-decoration: none;} 56 | a:link, a:active {color: #4280CA;} 57 | a:visited {color: #AA00AA;} 58 | a:hover, a:focus {text-decoration: underline; color: #2A6496;} 59 | 60 | .Indent { 61 | margin-left: 2em; 62 | } 63 | .NoIndent { 64 | margin-left: 0; 65 | margin-right: 0; 66 | } 67 | 68 | /* pre: code blocks, code: inline code, .Syntax: syntax definition (block/pre or inline/span) */ 69 | pre, code, .Syntax { 70 | font-family: Consolas, Courier New, monospace; 71 | font-size: 1em; 72 | } 73 | pre, code { 74 | border-right: solid 1px #C8C8C8; 75 | border-bottom: solid 1px #C8C8C8; 76 | background-color: #F6F6E8; 77 | } 78 | .Syntax { background-color: #FFFFAA; border: solid 1px #E8E89A; } 79 | code, span.Syntax { padding: 0 0.2em; } 80 | pre { 81 | margin: 0.7em 1.5em 0.7em 1.5em; 82 | padding: 0.7em 0 0.7em 0.7em; 83 | white-space: pre-wrap; /* works in IE8 but apparently not CHM viewer */ 84 | word-wrap: break-word; /* works in CHM viewer */ 85 | } 86 | pre.Syntax { 87 | margin: 0 0 1.0em 0; 88 | line-height: 150%; 89 | position: relative; 90 | } 91 | pre, pre.Short /*used with .Syntax*/ { line-height: 120%; } 92 | /* comments */ 93 | pre em, code em { color: #00A000; font-style: normal; } 94 | 95 | 96 | /* tables */ 97 | table.info { 98 | border: solid 2px #C0C0C0; 99 | border-collapse: collapse; 100 | width: 100%; 101 | /*table-layout: fixed;*/ 102 | } 103 | table.info td { 104 | border: solid 1px #C0C0C0; 105 | padding: 0.3em; 106 | } 107 | table.info th { 108 | background-color: #F6F6F6; 109 | padding: 0.3em; 110 | } 111 | 112 | /* command parameters */ 113 | dt { /* param name */ 114 | font-style: italic; 115 | } 116 | dd { 117 | margin-left: 0.3em; 118 | padding-left: 1.5em; 119 | border-left: 0.3em solid #e0e0e0; 120 | } 121 | dd > p:first-child { 122 | margin-top: 0.3em; 123 | } 124 | 125 | /* version number/requirement tag */ 126 | h1 .ver, h2 .ver, h3 .ver {font-size: 65%; font-weight: normal; margin-left: 1em; vertical-align: top} 127 | h2 .ver {color: lightgray; font-size: 80%;} 128 | .ver, 129 | /* de-emphasized */ 130 | .dull {color: gray;} 131 | .red {color: red;} /* used for highlight in various places */ 132 | .blue {color: blue;} 133 | /* emphasized note */ 134 | .note {border: 1px solid #99BB99; background-color: #E6FFE6; 135 | color: #005500; padding: 0 3px; } 136 | 137 | /* styles for briefly documenting multiple methods on one page: */ 138 | .methodShort { 139 | border: solid thin #C0C0C0; 140 | padding: 0.5em; 141 | margin-bottom: 1em; 142 | } 143 | .methodShort h2 { margin-top: 0; } 144 | .methodShort table.info { border: none; } 145 | .methodShort table.info td { 146 | border: none; 147 | vertical-align: text-top; 148 | } 149 | .methodShort:target { /* non-essential, but helpful if it works */ 150 | border-color: black; 151 | } 152 | 153 | /* nav links */ 154 | .navlinks { 155 | float: right; 156 | } 157 | .navlinks a { 158 | font-weight: bold; 159 | } --------------------------------------------------------------------------------