├── LICENSE ├── Lib ├── IEObj.ahk ├── StdOutStream.ahk ├── StdOutToVar.ahk ├── audioRouter.ahk ├── binSearch.ahk ├── borderlessMode.ahk ├── borderlessMove.ahk ├── checkSession.ahk ├── commaFormat.ahk ├── compileScript.ahk ├── db.ahk ├── downloadGithubRelease.ahk ├── dpiOffset.ahk ├── externalIP.ahk ├── externalIP_old.ahk ├── fileUnblock.ahk ├── functionalAHK.ahk ├── getCurrentTime.ahk ├── getImageSize.ahk ├── getPosFromAngle.ahk ├── getSelected.ahk ├── getUTCOffset.ahk ├── getWinClientSize.ahk ├── hToMs.ahk ├── hwndHung.ahk ├── ifContains.ahk ├── ifIn.ahk ├── imageSearchc.ahk ├── internetConnected.ahk ├── invertCaseChr.ahk ├── invertCaseStr.ahk ├── is64bitExe.ahk ├── isAlpha.ahk ├── isAlphaNum.ahk ├── isBetween.ahk ├── isDigit.ahk ├── isFloat.ahk ├── isHex.ahk ├── isInt.ahk ├── isLower.ahk ├── isNum.ahk ├── isSpace.ahk ├── isUpper.ahk ├── lanConnected.ahk ├── mToMs.ahk ├── mouseOverWin.ahk ├── msToH.ahk ├── msToM.ahk ├── msToS.ahk ├── multiKeyStates.ahk ├── muteWindow.ahk ├── nicRestart.ahk ├── nicSetState.ahk ├── processExist.ahk ├── processPriority.ahk ├── rand.ahk ├── randStr.ahk ├── readHotkeys.ahk ├── regExMatchI.ahk ├── regExReplaceI.ahk ├── sToMs.ahk ├── setWindowVol.ahk ├── strI.ahk ├── strReplaceI.ahk ├── strToLower.ahk ├── strToUpper.ahk ├── stringify.ahk ├── threadMan.ahk ├── tool.ahk ├── toolSpeak.ahk ├── urlDownloadToFile.ahk ├── urlDownloadToVar.ahk ├── urlFileGetSize.ahk └── winInfo.ahk ├── README.md └── Required-Libraries ├── Gdip_All.ahk ├── Gdip_min.ahk ├── VA.ahk ├── _MemoryLibrary.ahk ├── _Struct.ahk └── readResource.ahk /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Masonjar13 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Lib/IEObj.ahk: -------------------------------------------------------------------------------- 1 | #include *i 2 | class IEObj { 3 | 4 | __new(){ 5 | detectHiddenWindows on 6 | return this 7 | } 8 | 9 | __delete(){ 10 | this.quit() 11 | } 12 | 13 | ; methods 14 | init(private:=0,extensionsOff:=0){ 15 | this.init:=0 16 | ;static url:="about:InPrivate" 17 | 18 | run,% "Iexplore.exe " . (extenstionsOff?"-extoff ":"") . (private?"-private ":"") . "-noframemerging about:blank",,,wbpid 19 | this.wbpid:=wbpid 20 | ;winWait,% "ahk_pid " . this.wbpid 21 | while(!isObject(this.wb:=this.IEGetbyURL("about:blank"))) 22 | sleep 100 23 | this.wb.silent:=1 24 | this.wb.visible:=0 25 | ;i+=this.navToUrl("www.google.com") 26 | return 27 | } 28 | 29 | init2(){ 30 | this.init:=1 31 | this.wb:=comObjCreate("InternetExplorer.Application") 32 | winGet,wbpid,pid,% "ahk_id " . wb.wb.hwnd 33 | this.wbpid:=wbpid 34 | this.wb.silent:=1 35 | return 36 | } 37 | 38 | ; wb functions 39 | waitLoad(timeout:=15000){ 40 | static sleepTime:=100 41 | 42 | t:=0 43 | timeout/=sleepTime 44 | try{ 45 | while((++t=timeout?1:0) 51 | } 52 | 53 | navToUrl(url,timeout:=15000,userAgent:="",attempts:=1){ 54 | t:=0 55 | try{ 56 | loop{ 57 | this.wb.navigate(url,0,0,0,userAgent) 58 | i:=this.waitLoad(timeout) 59 | }until !i || ++t>=attempts 60 | }catch{ 61 | return 1 62 | } 63 | return i 64 | } 65 | 66 | ; etc 67 | quit(){ 68 | if(!this.init){ 69 | while(processExist(this.wbpid)){ 70 | process,close,% this.wbpid 71 | sleep 1000 72 | } 73 | }else{ 74 | this.wb.quit() 75 | sleep 1000 76 | try{ 77 | while(winExist("ahk_id " . this.wb.hwnd)){ 78 | process,close,% "ahk_id " . this.wb.hwnd 79 | sleep 1000 80 | } 81 | } 82 | } 83 | } 84 | 85 | IEGetbyURL(URL) { ; http://www.autohotkey.com/board/topic/102723-ieget-via-url-instead-of-name/#entry636586 86 | for pwb in comObjCreate("Shell.Application").Windows 87 | ;msgbox % pwb.LocationURL 88 | if (pwb.LocationURL = URL and InStr(pwb.FullName, "iexplore.exe") > 0) 89 | return pwb 90 | } 91 | 92 | err(desc){ 93 | msgbox,,Error,% desc 94 | } 95 | } -------------------------------------------------------------------------------- /Lib/StdOutStream.ahk: -------------------------------------------------------------------------------- 1 | /* Written by SKAN, HotKeyIt, and Sean, modified by Masonjar13 2 | 3 | Open a stream to a stdout of a given batch command. 4 | 5 | Parameters: 6 | --------------- 7 | sCmd: batch command to execute 8 | 9 | Callback (optional): function name to call back to each time 10 | the stream receives output. 11 | 12 | return: if callback was omitted, the entire output will be here 13 | --------------- 14 | 15 | Example: 16 | ------------ 17 | StdOutStream("ping 1.1.1.1","toolT") 18 | return 19 | 20 | esc::exitApp 21 | 22 | toolT(output,index) { 23 | static sOutput 24 | sOutput.="`n" index ": " output 25 | tooltip,% sOutput:=trim(sOutput," `n") 26 | } 27 | ------------ 28 | 29 | */ 30 | 31 | ; Edited by Masonjar13 to be compatible with 32 and 64-bit (2015) 32 | StdOutStream( sCmd, Callback = "" ) { ; Modified : SKAN 31-Aug-2013 http://goo.gl/j8XJXY 33 | Static StrGet := "StrGet" ; Thanks to : HotKeyIt http://goo.gl/IsH1zs 34 | ; Original : Sean 20-Feb-2007 http://goo.gl/mxCdn 35 | 36 | DllCall( "CreatePipe", UIntP,hPipeRead, UIntP,hPipeWrite, UInt,0, UInt,0 ) 37 | DllCall( "SetHandleInformation", UInt,hPipeWrite, UInt,1, UInt,1 ) 38 | 39 | if(a_ptrSize=8){ 40 | VarSetCapacity( STARTUPINFO, 104, 0 ) ; STARTUPINFO ; http://goo.gl/fZf24 41 | NumPut( 68, STARTUPINFO, 0 ) ; cbSize 42 | NumPut( 0x100, STARTUPINFO, 60 ) ; dwFlags => STARTF_USESTDHANDLES = 0x100 43 | NumPut( hPipeWrite, STARTUPINFO, 88 ) ; hStdOutput 44 | NumPut( hPipeWrite, STARTUPINFO, 96 ) ; hStdError 45 | VarSetCapacity( PROCESS_INFORMATION, 32 ) ; PROCESS_INFORMATION ; http://goo.gl/b9BaI 46 | }else{ 47 | VarSetCapacity( STARTUPINFO, 68, 0 ) ; STARTUPINFO ; http://goo.gl/fZf24 48 | NumPut( 68, STARTUPINFO, 0 ) ; cbSize 49 | NumPut( 0x100, STARTUPINFO, 44 ) ; dwFlags => STARTF_USESTDHANDLES = 0x100 50 | NumPut( hPipeWrite, STARTUPINFO, 60 ) ; hStdOutput 51 | NumPut( hPipeWrite, STARTUPINFO, 64 ) ; hStdError 52 | VarSetCapacity( PROCESS_INFORMATION, 16 ) ; PROCESS_INFORMATION ; http://goo.gl/b9BaI 53 | } 54 | If ! DllCall( "CreateProcess", UInt,0, UInt,&sCmd, UInt,0, UInt,0 ; http://goo.gl/USC5a 55 | , UInt,1, UInt,0x08000000, UInt,0, UInt,0 56 | , UInt,&STARTUPINFO, UInt,&PROCESS_INFORMATION ) 57 | Return "" 58 | , DllCall( "CloseHandle", UInt,hPipeWrite ) 59 | , DllCall( "CloseHandle", UInt,hPipeRead ) 60 | , DllCall( "SetLastError", Int,-1 ) 61 | 62 | hProcess := NumGet( PROCESS_INFORMATION, 0 ) 63 | if(a_is64bitOS) 64 | hThread := NumGet( PROCESS_INFORMATION, 8 ) 65 | else 66 | hThread := NumGet( PROCESS_INFORMATION, 4 ) 67 | DllCall( "CloseHandle", UInt,hPipeWrite ) 68 | 69 | AIC := ( SubStr( A_AhkVersion, 1, 3 ) = "1.0" ) ; A_IsClassic 70 | VarSetCapacity( Buffer, 4096, 0 ), nSz := 0 71 | 72 | While DllCall( "ReadFile", UInt,hPipeRead, UInt,&Buffer, UInt,4094, UIntP,nSz, Int,0 ) { 73 | 74 | tOutput := ( AIC && NumPut( 0, Buffer, nSz, "Char" ) && VarSetCapacity( Buffer,-1 ) ) 75 | ? Buffer : %StrGet%( &Buffer, nSz, "CP850" ) 76 | 77 | Isfunc( Callback ) ? %Callback%( tOutput, A_Index ) : sOutput .= tOutput 78 | 79 | } 80 | 81 | DllCall( "GetExitCodeProcess", UInt,hProcess, UIntP,ExitCode ) 82 | DllCall( "CloseHandle", UInt,hProcess ) 83 | DllCall( "CloseHandle", UInt,hThread ) 84 | DllCall( "CloseHandle", UInt,hPipeRead ) 85 | DllCall( "SetLastError", UInt,ExitCode ) 86 | 87 | Return Isfunc( Callback ) ? %Callback%( "", 0 ) : sOutput 88 | } -------------------------------------------------------------------------------- /Lib/StdOutToVar.ahk: -------------------------------------------------------------------------------- 1 | /* Written by SKAN and Sean, modified by Masonjar13 2 | 3 | Return all stdout of a given batch command. 4 | 5 | Parameters: 6 | --------------- 7 | sCmd: batch command to execute 8 | 9 | return: stdout data 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % StdOutToVar("ping 1.1.1.1") 15 | ------------ 16 | 17 | */ 18 | 19 | ; Edited by Masonjar13 to be compatible with 32 and 64-bit (2015) 20 | StdOutToVar( sCmd ) { ; GAHK32 ; Modified Version : SKAN 05-Jul-2013 http://goo.gl/j8XJXY 21 | Static StrGet := "StrGet" ; Original Author : Sean 20-Feb-2007 http://goo.gl/mxCdn 22 | 23 | DllCall( "CreatePipe", UIntP,hPipeRead, UIntP,hPipeWrite, UInt,0, UInt,0 ) 24 | DllCall( "SetHandleInformation", UInt,hPipeWrite, UInt,1, UInt,1 ) 25 | 26 | if(a_ptrSize=8){ 27 | VarSetCapacity( STARTUPINFO, 104, 0 ) ; STARTUPINFO ; http://goo.gl/fZf24 28 | NumPut( 104, STARTUPINFO, 0 ) ; cbSize 29 | NumPut( 0x100, STARTUPINFO, 60 ) ; dwFlags => STARTF_USESTDHANDLES = 0x100 30 | NumPut( hPipeWrite, STARTUPINFO, 88 ) ; hStdOutput 31 | NumPut( hPipeWrite, STARTUPINFO, 96 ) ; hStdError 32 | VarSetCapacity( PROCESS_INFORMATION, 32 ) ; PROCESS_INFORMATION ; http://goo.gl/b9BaI 33 | }else{ 34 | VarSetCapacity( STARTUPINFO, 68, 0 ) ; STARTUPINFO ; http://goo.gl/fZf24 35 | NumPut( 68, STARTUPINFO, 0 ) ; cbSize 36 | NumPut( 0x100, STARTUPINFO, 44 ) ; dwFlags => STARTF_USESTDHANDLES = 0x100 37 | NumPut( hPipeWrite, STARTUPINFO, 60 ) ; hStdOutput 38 | NumPut( hPipeWrite, STARTUPINFO, 64 ) ; hStdError 39 | VarSetCapacity( PROCESS_INFORMATION, 16 ) ; PROCESS_INFORMATION ; http://goo.gl/b9BaI 40 | } 41 | If ! DllCall( "CreateProcess", UInt,0, UInt,&sCmd, UInt,0, UInt,0 ; http://goo.gl/USC5a 42 | , UInt,1, UInt,0x08000000, UInt,0, UInt,0 43 | , UInt,&STARTUPINFO, UInt,&PROCESS_INFORMATION ) 44 | Return "" 45 | , DllCall( "CloseHandle", UInt,hPipeWrite ) 46 | , DllCall( "CloseHandle", UInt,hPipeRead ) 47 | , DllCall( "SetLastError", Int,-1 ) 48 | 49 | hProcess := NumGet( PROCESS_INFORMATION, 0 ) 50 | if(a_is64bitOS) 51 | hThread := NumGet( PROCESS_INFORMATION, 8 ) 52 | else 53 | hThread := NumGet( PROCESS_INFORMATION, 4 ) 54 | 55 | DllCall( "CloseHandle", UInt,hPipeWrite ) 56 | 57 | AIC := ( SubStr( A_AhkVersion, 1, 3 ) = "1.0" ) ; A_IsClassic 58 | VarSetCapacity( Buffer, 4096, 0 ), nSz := 0 59 | 60 | While DllCall( "ReadFile", UInt,hPipeRead, UInt,&Buffer, UInt,4094, UIntP,nSz, UInt,0 ) 61 | sOutput .= ( AIC && NumPut( 0, Buffer, nSz, "UChar" ) && VarSetCapacity( Buffer,-1 ) ) 62 | ? Buffer : %StrGet%( &Buffer, nSz, "CP850" ) 63 | 64 | DllCall( "GetExitCodeProcess", UInt,hProcess, UIntP,ExitCode ) 65 | DllCall( "CloseHandle", UInt,hProcess ) 66 | DllCall( "CloseHandle", UInt,hThread ) 67 | DllCall( "CloseHandle", UInt,hPipeRead ) 68 | 69 | Return sOutput, DllCall( "SetLastError", UInt,ExitCode ) 70 | } -------------------------------------------------------------------------------- /Lib/audioRouter.ahk: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* 4 | Methods: 5 | setProcessToDevice(ProcessName,DeviceName:="Default Audio Device") 6 | This sets the specified process to be used with the specified 7 | audio playback device. 8 | 9 | getDeviceList() 10 | Returns an array object containing all available playback 11 | devices. 12 | 13 | Returned error codes: 14 | setProcessToDevice() 15 | Returns string defining the error. 16 | */ 17 | 18 | class audioRouter { 19 | winId:="Audio Router ahk_class Audio Router ahk_exe Audio Router.exe" 20 | winRoutId:="Route Audio ahk_class #32770 ahk_exe Audio Router.exe" 21 | path:="" 22 | 23 | __new(path){ 24 | if(!a_isAdmin){ 25 | msgbox,,Error,This object requires administrative privileges. 26 | return 27 | } 28 | if(!fileExist(path)){ 29 | msgbox,,Error,Path doesn't exist. 30 | return 31 | } 32 | detectHiddenWindows,on 33 | detectHiddenText,on 34 | setControlDelay -1 35 | this.path:=path 36 | return this 37 | } 38 | 39 | __delete(){ 40 | this.killIt() 41 | } 42 | 43 | setProcessToDevice(procName,deviceName:="Default Audio Device"){ 44 | if(this.runIt()) 45 | return "Waiting for Audio Router window timed out." 46 | if(this._method1(procName)){ 47 | this.killIt() 48 | return "Process not found in list." 49 | } 50 | if(this._selectDeviceRouteWindow(deviceName)){ 51 | this.killIt() 52 | return "Waiting for Route Audio window timed out." 53 | } 54 | this.killIt() 55 | } 56 | 57 | getDeviceList(){ ;credit to qwerty12 - https://autohotkey.com/boards/viewtopic.php?p=154595#p154595 58 | audioDevices:=["Default Audio Device"],i:=1 59 | while(device:=VA_GetDevice("playback:" . i++)) 60 | audioDevices.push(VA_GetDeviceName(device)),ObjRelease(device) 61 | return audioDevices 62 | } 63 | 64 | ; internal 65 | _method1(procName){ 66 | lvc:="SysListView321" 67 | lvmIndex:=0 68 | winMenuSelectItem,% "ahk_id " . this.hwnd,% "",File,Switch View 69 | while(!lvh) 70 | controlGet,lvh,Hwnd,,% lvc,% this.winId 71 | controlGet,lvx,list,count,,% "ahk_id " . lvh 72 | controlFocus,,% "ahk_id " . lvh 73 | while(!lvT||!inStr(lvT,procName)){ 74 | controlSend,,{down},% "ahk_id " . lvh 75 | controlGet,lvT,list,focused,,% "ahk_id " . lvh 76 | if(++lvmIndex>lvx) 77 | return 1 78 | } 79 | 80 | pos:=this.LVM_GETITEMPOSITION(lvmIndex,lvh) 81 | postMessage,0x203,0,pos.x&0xFFFF | pos.y<<16,,% "ahk_id " . lvh ; WM_LBUTTONDBLCLCK 82 | } 83 | 84 | _selectDeviceRouteWindow(deviceName){ 85 | winWait,% this.winRoutId,,10 86 | if(errorlevel) 87 | return 1 88 | control,chooseString,% deviceName,ComboBox1,% this.winRoutId 89 | controlClick,Button1,% this.winRoutId,,,,NA 90 | sleep 1000 91 | } 92 | 93 | runIt(debug:=0){ 94 | run,% this.path,,% debug?"":"hide",hpid 95 | winWait,% this.winId,,10 96 | if(errorlevel) 97 | return 1 98 | winGet,hhwnd,id,% this.winId 99 | this.pid:=hpid,this.hwnd:=hhwnd 100 | if(!debug){ 101 | sysGet,width,78 102 | sysget,height,79 103 | winMove,% "ahk_id " . hhwnd,,width,height 104 | } 105 | } 106 | 107 | killIt(){ 108 | process,close,% this.pid 109 | this.pid:="",this.hwnd:="" 110 | } 111 | 112 | ; other 113 | LVM_GETITEMPOSITION(itemIdx,hwnd){ ;credit to qwerty12 - https://autohotkey.com/boards/viewtopic.php?p=154570#p154570 114 | if (!(hProcess := DllCall("OpenProcess", "UInt", PROCESS_QUERY_INFORMATION := 0x0400 | PROCESS_VM_OPERATION := 0x0008 | PROCESS_VM_READ := 0x0010 | PROCESS_VM_WRITE := 0x0020, "Int", False, "UInt", this.pid, "Ptr"))) ; open handle to process 115 | throw 116 | if (!(remotePoint := DllCall("VirtualAllocEx", "Ptr", hProcess, "Ptr", 0, "Ptr", 8, "UInt", MEM_COMMIT := 0x00001000, "UInt", PAGE_READWRITE := 0x04, "Ptr"))) ; allocate memory inside process 117 | throw 118 | if (!DllCall("SendMessage", "Ptr", hwnd, "UInt", LVM_GETITEMPOSITION := 0x1000+16, "Ptr", itemIdx, "Ptr", remotePoint, "Ptr")) ; because I find AHK's built-in clunkier 119 | throw 120 | varSetCapacity(point,8,0) 121 | if (!DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", remotePoint, "Ptr", &point, "Ptr", 8, "Ptr*", br) || br != 8) ; read point structure out from process and save into local copy 122 | throw 123 | ; sendMessage,% LVM_GETITEMPOSITION,% itemIndex,&point,,% "ahk_id " . hwnd ; ,% "ahk_id " . hwnd 124 | itemPos:={x: numGet(point,0,"Int"),y: numGet(point,4,"Int")} 125 | if (hProcess) { 126 | if (remotePoint) 127 | DllCall("VirtualFreeEx", "Ptr", hProcess, "Ptr", remotePoint, "Ptr", 0, "UInt", MEM_RELEASE := 0x8000) ; free allocated memory in remote process 128 | DllCall("CloseHandle", "Ptr", hProcess) ; close handle to remote process 129 | } 130 | return itemPos 131 | } 132 | 133 | /* deprecated 134 | 135 | getDeviceList(){ 136 | if(this.runIt()) 137 | return 1 138 | if(this._method1(this.selfProc)) 139 | return 2 140 | deviceList:=[] 141 | winWait,% this.winRoutId,,10 142 | if(errorlevel) 143 | return 3 144 | loop { 145 | control,choose,% a_index,ComboBox1,% this.winRoutId 146 | if(errorlevel) 147 | break 148 | controlGetText,t,ComboBox1,% this.winRoutId 149 | deviceList.push(t) 150 | } 151 | this.killIt() 152 | return deviceList 153 | } 154 | 155 | _method2(procName){ 156 | loop { 157 | controlGetText,cT,% "Static" . a_index,% "ahk_id " . this.hwnd 158 | if(errorlevel) 159 | break 160 | if(inStr(cT,procName)){ 161 | controlClick,% "Button" . a_index+1,% "ahk_id " . this.hwnd 162 | controlSend,% "Button" . a_index+1,{down 3}{enter},% "ahk_id " . this.hwnd 163 | break 164 | } 165 | } 166 | } 167 | */ 168 | } -------------------------------------------------------------------------------- /Lib/binSearch.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Perform binary search on array. 4 | 5 | Parameters: 6 | --------------- 7 | arr: array to search 8 | 9 | match: match to find 10 | 11 | r: array length 12 | 13 | l (optional): left starting position 14 | 15 | return: arr element matched 16 | --------------- 17 | 18 | Example: 19 | ------------ 20 | arr:=[200,500,1050,20000] 21 | msgbox % binSearch(arr,arr[3],arr.length()) 22 | ------------ 23 | 24 | */ 25 | 26 | binSearch(arr,match,r,l:=0){ 27 | return arr[mid:=(l+r)//2]=match?mid 28 | :arr[mid]>match?binSearch(arr,match,mid-1,l) 29 | :arr[mid]\s+",":"] 4 | ipInfoList:=["city","region","country","isp"] 5 | ipPage:=urlDownloadToVar("http://whatismyipaddress.com/") 6 | regExMatch(ipPage,">\K[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+",ipStart) 7 | ipInfo.insert("ip",ipStart) 8 | for i,a in ipInfoList 9 | ipInfo.insert(a,subStr(ipPage,tp:=inStr(ipPage,a tag[2])+strlen(a tag[2]),inStr(ipPage,"<",,tp)-tp)) 10 | return ipInfo 11 | } -------------------------------------------------------------------------------- /Lib/fileUnblock.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Removes the "This file came from another computer" flag on files. 4 | 5 | Parameters: 6 | --------------- 7 | path: path to file 8 | 9 | return: errorlevel of fileDelete 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | fileUnblock(a_desktop "\recently downloaded file.exe") 15 | ------------ 16 | 17 | */ 18 | 19 | fileUnblock(path){ 20 | fileDelete,% path ":Zone.Identifier:$DATA" 21 | return errorlevel 22 | } -------------------------------------------------------------------------------- /Lib/functionalAHK.ahk: -------------------------------------------------------------------------------- 1 | /* 2 | Library to remove traditional syntax/commands from _L/1.1 3 | by wrapping them all into functions. 4 | 5 | If command sets errorlevel, it will be returned. Any 6 | command that has a second function will not use byref, 7 | but will return an object with the data, including 8 | errorlevel. Any functions that create a pseudo-array 9 | use global (second function returns the array). 10 | 11 | */ 12 | 13 | autoTrim(onOff){ 14 | autoTrim,% onOff 15 | } 16 | 17 | blockInput(option){ 18 | blockInput,% option 19 | } 20 | 21 | click(params*){ 22 | for i,a in params 23 | param.=a_index=1?a:" " . a 24 | click,% param 25 | } 26 | 27 | clipWait(params*){ 28 | clipWait,% params[1],% params[2] 29 | return errorlevel 30 | } 31 | 32 | control(subCommand,params*){ 33 | control,% subCommand,% params[1],% params[2],% params[3],% params[4],% params[5],% params[6] 34 | return errorlevel 35 | } 36 | 37 | controlClick(params*){ 38 | controlClick,% params[1],% params[2],% params[3],% params[4],% params[5],% params[6],% params[7],% params[8] 39 | return errorlevel 40 | } 41 | 42 | controlFocus(params*){ 43 | controlFocus,% params[1],% params[2],% params[],% params[4],% params[5] 44 | return errorlevel 45 | } 46 | 47 | controlGet(byref outputVar,subCommand,params*){ 48 | controlGet,outputVar,% subCommand,% params[1],% params[2],% params[],% params[4],% params[5],% params[6] 49 | return errorlevel 50 | } 51 | 52 | controlGet2(subCommand,params*){ 53 | controlGet,outputVar,% subCommand,% params[1],% params[2],% params[],% params[4],% params[5],% params[6] 54 | return {out:outputVar,errorlevel:errorlevel} 55 | } 56 | 57 | controlGetFocus(byref outputVar,params*){ 58 | controlGetFocus,outputVar,% params[1],% params[2],% params[3],% params[4] 59 | return errorlevel 60 | } 61 | 62 | controlGetFocus2(params*){ 63 | controlGetFocus,outputVar,% params[1],% params[2],% params[3],% params[4] 64 | return {out:outputVar,errorlevel:errorlevel} 65 | } 66 | 67 | controlGetPos(byref x:="",byref y:="",byref width:="",byref height:="",params*){ 68 | controlGetPos,x,y,width,height,% params[1],% params[2],% params[3],% params[4],% params[5] 69 | } 70 | 71 | controlGetPos2(params*){ 72 | controlGetPos,x,y,width,height,% params[1],% params[2],% params[3],% params[4],% params[5] 73 | return {x:x,y:y,width:width,height:height} 74 | } 75 | 76 | controlGetText(byref outputVar,params*){ 77 | controlGetText,outputVar,% params[1],% params[2],% params[3],% params[4],% params[5] 78 | return errorlevel 79 | } 80 | 81 | controlGetText2(params*){ 82 | controlGetText,outputVar,% params[1],% params[2],% params[3],% params[4],% params[5] 83 | return {out:outputVar,errorlevel:errorlevel} 84 | } 85 | 86 | controlMove(control,x,y,width,height,params*){ 87 | controlMove,% control,x,y,width,height,% params[1],% params[2],% params[3],% params[4] 88 | return errorlevel 89 | } 90 | 91 | controlSend(params*){ 92 | controlSend,% params[1],% params[2],% params[4],% params[5],% params[6] 93 | return errorlevel 94 | } 95 | 96 | controlSendRaw(params*){ 97 | controlSendRaw,% params[1],% params[2],% params[4],% params[5],% params[6] 98 | return errorlevel 99 | } 100 | 101 | controlSetText(params*){ 102 | controlSetText,% params[1],% params[2],% params[4],% params[5],% params[6] 103 | return errorlevel 104 | } 105 | 106 | coordMode(targetType,relativeTo:=""){ 107 | coordMode,% targetType,% relativeTo 108 | } 109 | 110 | critical(onOffNumeric:=""){ 111 | critical,% onOffNumeric 112 | } 113 | 114 | detectHiddenText(onOff){ 115 | critical,% onOff 116 | } 117 | 118 | detectHiddenWindows(onOff){ 119 | detectHiddenWindows,% onOff 120 | } 121 | 122 | drive(subCommand,params*){ 123 | drive,% subCommand,% params[1],% params[2] 124 | return errorlevel 125 | } 126 | 127 | driveGet(byref outputVar,subCommand,value:=""){ 128 | driveGet,outputVar,% subCommand,% value 129 | return errorlevel 130 | } 131 | 132 | driveGet2(subCommand,value:=""){ 133 | driveGet,outputVar,% subCommand,% value 134 | return {out:outputVar,errorlevel:errorlevel} 135 | } 136 | 137 | driveSpaceFree(byref outputVar,path){ 138 | driveSpaceFree,outputVar,path) 139 | } 140 | 141 | driveSpaceFree2(path){ 142 | driveSpaceFree,outputVar,path) 143 | return {out:outputVar} 144 | } 145 | 146 | edit(){ 147 | edit 148 | } 149 | 150 | envAdd(byref outputVar,value,timeUnits:=""){ 151 | envAdd,outputVar,value,% timeUnits 152 | } 153 | 154 | envAdd2(value,timeUnits:=""){ 155 | envAdd,outputVar,value,% timeUnits 156 | return {out:outputVar} 157 | } 158 | 159 | envGet(byref outputVar,envVarName){ 160 | envGet,outputVar,% envVarName 161 | } 162 | 163 | envGet2(envVarName){ 164 | envGet,outputVar,% envVarName 165 | return {out:outputVar} 166 | } 167 | 168 | envSet(envVar,value){ 169 | envSet,% envVar,% value 170 | } 171 | 172 | envSub(byref outputVar,value,timeUnits:=""){ 173 | envSub,outputVar,% value,% timeUnits 174 | } 175 | 176 | envSub2(value,timeUnits:=""){ 177 | envSub,outputVar,% value,% timeUnits 178 | return {out:outputVar} 179 | } 180 | 181 | envUpdate(){ 182 | envUpdate 183 | } 184 | 185 | fileAppend(params*){ 186 | fileAppend,% params[1],% params[2],% params[3] 187 | return errorlevel 188 | } 189 | 190 | fileCopy(sourcePattern,destPattern,overwrite:=""){ 191 | fileCopy,% sourcePattern,% destPattern,% overwrite 192 | return errorlevel 193 | } 194 | 195 | fileCopyDir(source,dest,overwrite:=""){ 196 | fileCopyDir,% source,% desk,% overwrite 197 | return errorlevel 198 | } 199 | 200 | fileCreateDir(dirName){ 201 | fileCreateDir,% dirName 202 | return errorlevel 203 | } 204 | 205 | fileCreateShortcut(target,linkFile,params*){ 206 | fileCreateShortcut,% target,% linkFile,% params[1],% params[2],% params[3],% params[4],% params[5],% params[6],% params[7] 207 | return errorlevel 208 | } 209 | 210 | fileDelete(filePattern){ 211 | fileDelete,% filePattern 212 | return errorlevel 213 | } 214 | 215 | fileEncoding(encoding:=""){ 216 | fileEncoding,% encoding 217 | } 218 | 219 | fileGetAttrib(byref outputVar,fileName:=""){ 220 | fileGetAttrib,outputVar,% fileName 221 | return errorlevel 222 | } 223 | 224 | fileGetAttrib2(fileName:=""){ 225 | fileGetAttrib,outputVar,% fileName 226 | return {out:outputVar,errorlevel:errorlevel} 227 | } 228 | 229 | fileGetShortcut(linkFile,byref outTarget:="",byref outDir:="",byref outArgs:="",byref outDescription:="",byref outIcon:="",byref outIconNum:="",byref outRunState:=""){ 230 | fileGetShortcut,% linkFile,outTarget,outDir,outArgs,outDescription,outIcon,outIconNum,outRunState 231 | return errorlevel 232 | } 233 | 234 | fileGetShortcut2(linkFile){ 235 | fileGetShortcut,% linkFile,outTarget,outDir,outArgs,outDescription,outIcon,outIconNum,outRunState 236 | return {outTarget:outTarget,outDir:outDir,outArgs:outArgs,outDescription:outDescription,outIcon:outIcon,outIconNum:outIconNum,outRunState:outRunState,errorlevel:errorlevel} 237 | } 238 | 239 | fileGetSize(byref outputVar,params*){ 240 | fileGetSize,outputVar,% params[1],% params[2] 241 | return errorlevel 242 | } 243 | 244 | fileGetSize2(params*){ 245 | fileGetSize,outputVar,% params[1],% params[2] 246 | return {out:outputVar,errorlevel:errorlevel} 247 | } 248 | 249 | fileGetTime(byref outputVar,params*){ 250 | fileGetTime,outputVar,% params[1],% params[2] 251 | return errorlevel 252 | } 253 | 254 | fileGetTime2(params*){ 255 | fileGetTime,outputVar,% params[1],% params[2] 256 | return {out:outputVar,errorlevel:errorlevel} 257 | } 258 | 259 | fileGetVersion(byref outputVar,fileName:=""){ 260 | fileGetVersion,outputVar,% fileName 261 | return errorlevel 262 | } 263 | 264 | fileGetVersion2(fileName:=""){ 265 | fileGetVersion,outputVar,% fileName 266 | return {out:outputVar,errorlevel:errorlevel} 267 | } 268 | 269 | fileMove(sourcePattern,destPattern,overwrite:=""){ 270 | fileMove,% sourcePattern,% destPattern,% overwrite 271 | return errorlevel 272 | } 273 | 274 | fileMoveDir(source,dest,flag:=""){ 275 | fileMoveDir,% source,% dest,% flag 276 | return errorlevel 277 | } 278 | 279 | fileRead(byref outputVar,fileName){ 280 | fileRead,outputVar,% fileName 281 | return errorlevel 282 | } 283 | 284 | fileRead2(fileName){ 285 | fileRead,outputVar,% fileName 286 | return {out:outputVar,errorlevel:errorlevel} 287 | } 288 | 289 | fileReadLine(byref outputVar,fileName,lineNum){ 290 | fileReadLine,outputVar,% fileName,% lineNum 291 | return errorlevel 292 | } 293 | 294 | fileReadLine2(fileName,lineNum){ 295 | fileReadLine,outputVar,% fileName,% lineNum 296 | return {out:outputVar,errorlevel:errorlevel} 297 | } 298 | 299 | fileRecycle(filePattern){ 300 | fileRecycle,% filePattern 301 | return errorlevel 302 | } 303 | 304 | fileRecycleEmpty(driveLetter:=""){ 305 | fileRecycleEmpty,% driveLetter 306 | return errorlevel 307 | } 308 | 309 | fileRemoveDir(dirName,recurse:=""){ 310 | fileRemoveDir,% dirName,% recurse 311 | return errorlevel 312 | } 313 | 314 | fileSelectFile(byref outputVar,params*){ 315 | fileSelectFile,outputVar,% params[1],% params[2],% params[3] 316 | return errorlevel 317 | } 318 | 319 | fileSelectFile2(params*){ 320 | fileSelectFile,outputVar,% params[1],% params[2],% params[3] 321 | return {out:outputVar,errorlevel:errorlevel} 322 | } 323 | 324 | fileSelectFolder(byref outputVar,params*){ 325 | fileSelectFolder,outputVar,% params[1],% params[2],% params[3] 326 | return errorLevel 327 | } 328 | 329 | fileSelectFolder2(params*){ 330 | fileSelectFolder,outputVar,% params[1],% params[2],% params[3] 331 | return {out:outputVar,errorlevel:errorLevel} 332 | } 333 | 334 | fileSetAttrib(attributes,params*){ 335 | fileSetAttrib,% attributes,% params[1],% params[2],% params[3] 336 | return errorlevel 337 | } 338 | 339 | fileSetTime(params*){ 340 | fileSetTime,% params[1],% params[2],% params[3],% params[4],% params[5] 341 | return errorlevel 342 | } 343 | 344 | formatTime(byref outputVar,params*){ 345 | formatTime,outputVar,% params[1],% params[2] 346 | } 347 | 348 | formatTime2(params*){ 349 | formatTime,outputVar,% params[1],% params[2] 350 | return {out:outputVar} 351 | } 352 | 353 | groupActivate(groupName,mode:=""){ 354 | groupActivate,% groupName,% mode 355 | return errorlevel 356 | } 357 | 358 | groupAdd(groupName,params*){ 359 | groupAdd,% groupName,% params[1],% params[2],% params[3],% params[4],% params[5] 360 | } 361 | 362 | groupClose(groupName,mode:=""){ 363 | groupClose,% groupName,% mode 364 | } 365 | 366 | groupDeactivate(groupName,mode:=""){ 367 | groupDeactivate,% groupName,% mode 368 | } 369 | 370 | ; gui() 371 | 372 | guiControl(subCommand,controlID,value:=""){ 373 | guiControl,% subCommand,% controlID,% value 374 | return errorlevel 375 | } 376 | 377 | guiControlGet(byref outputVar,params*){ 378 | guiControlGet,outputVar,% params[1],% params[2],% params[3] 379 | return errorlevel 380 | } 381 | 382 | guiControlGet2(params*){ 383 | guiControlGet,outputVar,% params[1],% params[2],% params[3] 384 | return {out:outputVar,errorlevel:errorlevel} 385 | } 386 | 387 | hotkey(params*){ 388 | hotkey,% params[1],% params[2],% params[3] 389 | return errorlevel 390 | } 391 | 392 | ifMsgBox(buttonName){ 393 | ifMsgBox,% buttonName 394 | return 1 395 | return 0 396 | } 397 | 398 | imageSearch(byref x,byref y,x1,y1,x2,y2,imageFile){ 399 | imageSearch,x,y,x1,y1,x2,y2,% imageFile 400 | return errorlevel 401 | } 402 | 403 | imageSearch2(x1,y1,x2,y2,imageFile){ 404 | imageSearch,x,y,x1,y1,x2,y2,% imageFile 405 | return {x:x,y:y,errorlevel:errorlevel} 406 | } 407 | 408 | iniDelete(fileName,section,key:=""){ 409 | iniDelete,% fileName,% section,% key 410 | return errorlevel 411 | } 412 | 413 | iniRead(byref outputVar,fileName,params*){ 414 | switch params.count() { 415 | case 0: 416 | iniRead,outputVar,% fileName 417 | case 1: 418 | iniRead,outputVar,% fileName,% params[1] 419 | case 2: 420 | case 3: 421 | iniRead,outputVar,% fileName,% params[1],% params[2],% params[3] 422 | default: 423 | throw params.count() . " parameters passed, expected 0-3" 424 | } 425 | } 426 | 427 | iniRead2(fileName,params*){ 428 | switch params.count() { 429 | case 0: 430 | iniRead,outputVar,% fileName 431 | case 1: 432 | iniRead,outputVar,% fileName,% params[1] 433 | case 2: 434 | case 3: 435 | iniRead,outputVar,% fileName,% params[1],% params[2],% params[3] 436 | default: 437 | throw params.count() . " parameters passed, expected 0-3" 438 | } 439 | return {out:outputVar} 440 | } 441 | 442 | iniWrite(value,fileName,section,key:=""){ 443 | iniWrite,% value,% fileName,% section,% key 444 | return errorlevel 445 | } 446 | 447 | input(byref outputVar:="",params*){ 448 | input,outputVar,% params[1],% params[2],% params[3] 449 | return errorlevel 450 | } 451 | 452 | input2(params*){ 453 | input,outputVar,% params[1],% params[2],% params[3] 454 | return {out:outputVar,errorlevel:errorlevel} 455 | } 456 | 457 | inputBox(byref outputVar,params*){ 458 | inputBox,outputVar,% params[1],% params[2],% params[3],% params[4],% params[5],% params[6],% params[7],% params[8],% params[9],% params[10] 459 | return errorlevel 460 | } 461 | 462 | inputBox2(params*){ 463 | inputBox,outputVar,% params[1],% params[2],% params[3],% params[4],% params[5],% params[6],% params[7],% params[8],% params[9],% params[10] 464 | return {out:outputVar,errorlevel:errorlevel} 465 | } 466 | 467 | keyHistory(){ 468 | keyHistory 469 | } 470 | 471 | keyWait(keyName,options:=""){ 472 | keyWait,% keyName,% options 473 | return errorlevel 474 | } 475 | 476 | listHotkeys(){ 477 | listHotkeys 478 | } 479 | 480 | listLines(){ 481 | listLines 482 | } 483 | 484 | listVars(){ 485 | listVars 486 | } 487 | 488 | menu(menuName,subCommand,params*){ 489 | menu,% menuName,% subCommand,% params[1],% params[2],% params[3],% params[4] 490 | return errorlevel 491 | } 492 | 493 | mouseClick(params*){ 494 | mouseClick,% params[1],params[2],params[3],params[4],params[5],% params[6],% params[7] 495 | } 496 | 497 | mouseClickDrag(whichButton,x1,y1,x2,y2,params*){ 498 | mouseClickDrag,% whichButton,x1,y1,x2,y2,params[1],% params[2] 499 | } 500 | 501 | mouseGetPos(byref x:="",byref y:="",byref win:="",byref control:="",flag:=""){ 502 | mouseGetPos,x,y,win,control,% flag 503 | } 504 | 505 | mouseGetPos2(flag:=""){ 506 | mouseGetPos,x,y,win,control,% flag 507 | return {x:x,y:y,win:win,control:control} 508 | } 509 | 510 | mouseMove(x,y,params*){ 511 | mouseMove,x,y,params[1],% params[2] 512 | } 513 | 514 | msgBox(params*){ 515 | if(params.count()=1) 516 | msgBox,% params[1] 517 | else 518 | msgbox,% params[1],% params[2],% params[3],% params[4] 519 | } 520 | 521 | outputDebug(text){ 522 | outputDebug,text 523 | } 524 | 525 | pause(params*){ 526 | pause,% params[1],% params[2] 527 | } 528 | 529 | pixelGetColor(byref outputVar,byref x,byref y,mode:=""){ 530 | pixelGetColor,outputVar,x,y,% mode 531 | return errorlevel 532 | } 533 | 534 | pixelGetColor2(mode:=""){ 535 | pixelGetColor,outputVar,x,y,% mode 536 | return {out:outputVar,x:x,y:y,errorlevel:errorlevel} 537 | } 538 | 539 | pixelSearch(byref x,byref y,x1,y1,x2,y2,colorID,params*){ 540 | pixelSearch,x,y,x1,y1,x2,y2,% colorID,params[1],% params[2] 541 | return errorlevel 542 | } 543 | 544 | pixelSearch2(x1,y1,x2,y2,colorID,params*){ 545 | pixelSearch,x,y,x1,y1,x2,y2,% colorID,params[1],% params[2] 546 | return {x:x,y:y,errorlevel:errorlevel} 547 | } 548 | 549 | postMessage(msg,params*){ 550 | postMessage,% msg,% params[1],% params[2],% params[3],% params[4],% params[5],% params[6],% params[7] 551 | return errorlevel 552 | } 553 | 554 | process(subCommand,params*){ 555 | process,% subCommand,% params[1],% params[2] 556 | return errorlevel 557 | } 558 | 559 | progress(param1,params*){ 560 | progress,% param1,% params[1],% params[2],% params[3],% params[4] 561 | } 562 | 563 | random(byref outputVar:="",params*){ 564 | if(!outputVar) ; new seed 565 | random,,% params[1] 566 | else 567 | random,outputVar,% params[1],% params[2] 568 | } 569 | 570 | random2(params*){ 571 | random,outputVar,% params[1],% params[2] 572 | return {out:outputVar} 573 | } 574 | 575 | regDelete(keyName,valueName:=""){ 576 | regDelete,% keyName,% valueName 577 | return errorlevel 578 | } 579 | 580 | regRead(byref outputVar,keyName,valueName:=""){ 581 | regRead,outputVar,% keyName,% valueName 582 | return errorlevel 583 | } 584 | 585 | regRead2(keyName,valueName:=""){ 586 | regRead,outputVar,% keyName,% valueName 587 | return {out:outputVar,errorlevel:errorlevel} 588 | } 589 | 590 | regWrite(valueType,keyName,params*){ 591 | regWrite,% valueType,% keyName,% params[1],% params[2] 592 | return errorlevel 593 | } 594 | 595 | reload(){ 596 | reload 597 | } 598 | 599 | run(target,workingDir:="",options:="",byref outputVarPID:=""){ 600 | run,% target,% params[1],% params[2],outputVarPID 601 | return errorlevel 602 | } 603 | 604 | run2(target,workingDir:="",options:=""){ 605 | run,% target,% params[1],% params[2],outputVarPID 606 | return {PID:outputVarPID,errorlevel:errorlevel} 607 | } 608 | 609 | runAs(params*){ 610 | runAs,% params[1],% params[2],% params[3] 611 | } 612 | 613 | runWait(target,workingDir:="",options:="",byref outputVarPID:=""){ 614 | runWait,% target,% params[1],% params[2],outputVarPID 615 | return errorlevel 616 | } 617 | 618 | runWait2(target,workingDir:="",options:=""){ 619 | runWait,% target,% params[1],% params[2],outputVarPID 620 | return {PID:outputVarPID,errorlevel:errorlevel} 621 | } 622 | 623 | send(keys){ 624 | send,% keys 625 | } 626 | 627 | sendEvent(keys){ 628 | sendEvent,% keys 629 | } 630 | 631 | sendInput(keys){ 632 | sendInput,% keys 633 | } 634 | 635 | sendLevel(level){ 636 | sendLevel,% level 637 | } 638 | 639 | sendMessage(msg,params*){ 640 | postMessage,msg,params[1],params[2],% params[3],% params[4],% params[5],% params[6],% params[7],params[8] 641 | return errorlevel 642 | } 643 | 644 | sendMode(mode){ 645 | sendMode,% mode 646 | } 647 | 648 | sendPlay(keys){ 649 | sendPlay,% keys 650 | } 651 | 652 | sendRaw(keys){ 653 | sendRaw,% keys 654 | } 655 | 656 | setBatchLines(param){ 657 | setBatchLines,% param 658 | } 659 | 660 | setCapsLockState(state:=""){ 661 | setCapsLockState,% state 662 | } 663 | 664 | setControlDelay(delay){ 665 | setControlDelay,% delay 666 | } 667 | 668 | setDefaultMouseSpeed(speed){ 669 | setDefaultMouseSpeed,% speed 670 | } 671 | 672 | setKeyDelay(params*){ 673 | setKeyDelay,params[1],params[2],% params[3] 674 | } 675 | 676 | setMouseDelay(delay,play:=""){ 677 | setMouseDelay,delay,% play 678 | } 679 | 680 | setNumLockState(state:=""){ 681 | setNumLockState,% state 682 | } 683 | 684 | setRegView(regView){ 685 | setRegView,% regView 686 | } 687 | 688 | setScrollLockState(state:=""){ 689 | setScrollLockState,% state 690 | } 691 | 692 | setStoreCapsLockMode(onOff){ 693 | setStoreCapsLockMode,% onOff 694 | } 695 | 696 | setTimer(params*){ 697 | setTimer,% params[1],% params[2],% params[3] 698 | } 699 | 700 | setTitleMatchMode(param){ 701 | setTitleMatchMode,% param 702 | } 703 | 704 | setWinDelay(delay){ 705 | setWinDelay,delay 706 | } 707 | 708 | setWorkingDir(dirName){ 709 | setWorkingDir,% dirName 710 | } 711 | 712 | shutdown(code){ 713 | shutdown,% code 714 | } 715 | 716 | sleep(delayInMs){ 717 | sleep delayInMs 718 | } 719 | 720 | sort(byRef varName,options:=""){ 721 | sort,varName,% options 722 | } 723 | 724 | sort2(options:=""){ 725 | sort,varName,% options 726 | return {out:varName} 727 | } 728 | 729 | soundBeep(params*){ 730 | soundBeep,params[1],params[2] 731 | } 732 | 733 | soundGet(byref outputVar,params*){ 734 | soundGet,outputVar,% params[1],% params[2],params[3] 735 | return errorlevel 736 | } 737 | 738 | soundGet2(params*){ 739 | soundGet,outputVar,% params[1],% params[2],params[3] 740 | return {out:outputVar,errorlevel:errorlevel} 741 | } 742 | 743 | soundGetWaveVolume(byref outputVar,deviceNumber:=""){ 744 | soundGetWaveVolume,outputVar,% deviceNumber 745 | return errorlevel 746 | } 747 | 748 | soundGetWaveVolume2(deviceNumber:=""){ 749 | soundGetWaveVolume,outputVar,% deviceNumber 750 | return {out:outputVar,errorlevel:errorlevel} 751 | } 752 | 753 | soundPlay(fileName,wait:=""){ 754 | soundPlay,% fileName,% wait 755 | return errorlevel 756 | } 757 | 758 | soundSet(newSetting,params*){ 759 | soundSet,% newSetting,% params[1],% params[],% params[3] 760 | return errorlevel 761 | } 762 | 763 | soundSetWaveVolume(percent,deviceNumber:=""){ 764 | soundSetWaveVolume,percent,% deviceNumer 765 | return errorlevel 766 | } 767 | 768 | splashImage(params*){ 769 | splashImage,% params[1],% params[2],% params[3],% params[4],% params[5],% params[6] 770 | } 771 | 772 | splashTextOff(){ 773 | splashTextOff 774 | } 775 | 776 | splashTextOn(params*){ 777 | splashTextOn,% params[1],% params[2],% params[3],% params[4] 778 | } 779 | 780 | splitPath(inputVar,byref outFileName:="",byref outDir:="",byref outExt:="",byref outNameNoExt:="",byref outDrive:=""){ 781 | splitPath,inputVar,outFileName,outDir,outExt,outNameNoExt,outDrive 782 | } 783 | 784 | splitPath2(inputVar){ 785 | splitPath,inputVar,outFileName,outDir,outExt,outNameNoExt,outDrive 786 | return {fileName:outFileName,dir:outDir,ext:outExt,nameNoExt:outNameNoExt,drive:outDrive} 787 | } 788 | 789 | statusBarGetText(byref outputVar,params*){ 790 | statusBarGetText,outputVar,% params[1],% params[2],% params[3],% params[4],% params[5] 791 | return errorlevel 792 | } 793 | 794 | statusBarGetText2(params*){ 795 | statusBarGetText,outputVar,% params[1],% params[2],% params[3],% params[4],% params[5] 796 | return {out:outputVar,errorlevel:errorlevel} 797 | } 798 | 799 | statusBarWait(params*){ 800 | statusBarWait,% params[1],% params[2],% params[3],% params[4],% params[5],% params[6],% params[7],% params[8] 801 | return errorlevel 802 | } 803 | 804 | stringCaseSense(onOffLocale){ 805 | stringCaseSense,% onOffLocale 806 | } 807 | 808 | stringLower(byref outputVar,byref inputVar,t:=""){ 809 | stringLower,outputVar,% inputVar,% t 810 | } 811 | 812 | stringLower2(byref inputVar,t:=""){ 813 | stringLower,outputVar,% inputVar,% t 814 | return {out:outputVar} 815 | } 816 | 817 | stringUpper(byref outputVar,byref inputVar,t:=""){ 818 | stringUpper,outputVar,% inputVar,% t 819 | } 820 | 821 | stringUpper2(byref inputVar,t:=""){ 822 | stringUpper,outputVar,% inputVar,% t 823 | return {out:outputVar} 824 | } 825 | 826 | suspend(mode:=""){ 827 | suspend,% mode 828 | } 829 | 830 | sysGet(byref outputVar,subCommand,value:=""){ 831 | global 832 | sysGet,outputVar,% subCommand,% value 833 | } 834 | 835 | sysGet2(subCommand,value:=""){ 836 | sysGet,outputVar,% subCommand,% value 837 | if(subCommand="monitor" || subCommand="monitorWorkArea"){ 838 | return {left:outputVarLeft,top:outputVarTop,right:outputVarRight,bottom:outputVarBottom} 839 | } 840 | return {out:outputVar} 841 | } 842 | 843 | thread(subcommand,params*){ 844 | thread,% subCommand,% params[1],% params[2] 845 | } 846 | 847 | throw(expression:=""){ 848 | throw,% expression 849 | } 850 | 851 | toolTip(params*){ 852 | tooltip,% params[1],% params[2],% params[3],% params[4] 853 | } 854 | 855 | transform(byref outputVar,subCommand,value1,value2:=""){ 856 | transform,outputVar,% subCommand,% value1,% value2 857 | } 858 | 859 | transform2(subCommand,value1,value2:=""){ 860 | transform,outputVar,% subCommand,% value1,% value2 861 | return {out:outputVar} 862 | } 863 | 864 | trayTip(params*){ 865 | trayTip,% params[1],% params[2],% params[3],% params[4] 866 | } 867 | 868 | urlDownloadToFile(url,fileName){ 869 | urlDownloadToFile,% url,% fileName 870 | return errorlevel 871 | } 872 | 873 | winActivate(params*){ 874 | winActivate,% params[1],% params[2],% params[3],% params[4] 875 | } 876 | 877 | winActivateBottom(params*){ 878 | winActivateBottom,% params[1],% params[2],% params[3],% params[4] 879 | } 880 | 881 | winClose(params*){ 882 | winClose,% params[1],% params[2],% params[3],% params[4],% params[5] 883 | } 884 | 885 | winGet(byref outputVar,params*){ 886 | global 887 | winGet,outputVar,% params[1],% params[2],% params[3],% params[4],% params[5] 888 | } 889 | 890 | winGet2(params*){ 891 | winGet,outputVar,% params[1],% params[2],% params[3],% params[4],% params[5] 892 | if(params[1]="list"){ 893 | out:=[] 894 | loop,% outputVar 895 | out.push(outputVar%a_index%) 896 | return out 897 | } 898 | return {out:outputVar} 899 | } 900 | 901 | winGetActiveStats(byref title,byref width,byref height,byref x,byref y){ 902 | winGetActiveStats,title,width,height,x,y 903 | } 904 | 905 | winGetActiveStats2(){ 906 | winGetActiveStats,title,width,height,x,y 907 | return {title:title,width:width,height:height,x:x,y:y} 908 | } 909 | 910 | winGetActiveTitle(byref outputVar){ 911 | winGetActiveTitle,outputVar 912 | } 913 | 914 | winGetActiveTitle2(){ 915 | winGetActiveTitle,outputVar 916 | return {out:outputVar} 917 | } 918 | 919 | winGetClass(byref outputVar,params*){ 920 | winGetClass,outputVar,% params[1],% params[2],% params[3],% params[4] 921 | } 922 | 923 | winGetClass2(params*){ 924 | winGetClass,outputVar,% params[1],% params[2],% params[3],% params[4] 925 | return {out:outputVar} 926 | } 927 | 928 | winGetPos(byref x:="",byref y:="",byref width:="",byref height:="",params*){ 929 | winGetPos,x,y,width,height,% params[1],% params[2],% params[3],% params[4] 930 | } 931 | 932 | winGetPos2(params*){ 933 | winGetPos,x,y,width,height,% params[1],% params[2],% params[3],% params[4] 934 | return {x:x,y:y,width:width,height:height} 935 | } 936 | 937 | winGetText(byref outputVar,params*){ 938 | winGetText,outputVar,% params[1],% params[2],% params[3],% params[4] 939 | } 940 | 941 | winGetText2(params*){ 942 | winGetText,outputVar,% params[1],% params[2],% params[3],% params[4] 943 | return {out:outputVar} 944 | } 945 | 946 | winGetTitle(byref outputVar,params*){ 947 | winGetTitle,outputVar,% params[1],% params[2],% params[3],% params[4] 948 | } 949 | 950 | winGetTitle2(params*){ 951 | winGetTitle,outputVar,% params[1],% params[2],% params[3],% params[4] 952 | return {out:outputVar} 953 | } 954 | 955 | winHide(params*){ 956 | winHide,% params[1],% params[2],% params[3],% params[4] 957 | } 958 | 959 | winKill(params*){ 960 | winKill,% params[1],% params[2],% params[3],% params[4],% params[5] 961 | } 962 | 963 | winMaximize(params*){ 964 | winMaximize,% params[1],% params[2],% params[3],% params[4] 965 | } 966 | 967 | winMenuSelectItem(winTitle,winText,menu,params*){ 968 | winMenuSelectItem,% winTitle,% winText,% menu,% params[1],% params[2],% params[3],% params[4],% params[5],% params[6],% params[7],% params[8] 969 | return errorlevel 970 | } 971 | 972 | winMinimize(params*){ 973 | winMinimize,% params[1],% params[2],% params[3],% params[4] 974 | } 975 | 976 | winMinimizeAll(){ 977 | winMinimizeAll 978 | } 979 | 980 | winMinimizeAllUndo(){ 981 | winMinimizeAllUndo 982 | } 983 | 984 | winMove(params*){ 985 | winMove,% params[1],% params[2],% params[3],% params[4],% params[5],% params[6],% params[7],% params[8] 986 | } 987 | 988 | winRestore(params*){ 989 | winRestore,% params[1],% params[2],% params[3],% params[4] 990 | } 991 | 992 | winSet(subCommand,value,params*){ 993 | winSet,% subCommand,% value,% params[1],% params[2],% params[3],% params[4] 994 | } 995 | 996 | winSetTitle(params*){ 997 | winSetTitle,% params[1],% params[2],% params[3],% params[4],% params[5] 998 | } 999 | 1000 | winShow(params*){ 1001 | winShow,% params[1],% params[2],% params[3],% params[4] 1002 | } 1003 | 1004 | winWait(params*){ 1005 | winWait,% params[1],% params[2],% params[3],% params[4],% params[5] 1006 | return errorlevel 1007 | } 1008 | 1009 | winWaitActive(params*){ 1010 | winWaitActive,% params[1],% params[2],% params[3],% params[4],% params[5] 1011 | return errorlevel 1012 | } 1013 | 1014 | winWaitClose(params*){ 1015 | winWaitClose,% params[1],% params[2],% params[3],% params[4],% params[5] 1016 | } 1017 | 1018 | winWaitNotActive(params*){ 1019 | winWaitNotActive,% params[1],% params[2],% params[3],% params[4],% params[5] 1020 | return errorlevel 1021 | } 1022 | -------------------------------------------------------------------------------- /Lib/getCurrentTime.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Retrieves the current time by country/region/timezone in 12-hour format. 4 | 5 | Parameters: 6 | --------------- 7 | country: name of the country 8 | 9 | region: name of the region within the country, if applicable 10 | 11 | countryIsTimezone: changes country parameter to use it as a timezone instead; 12 | this makes the region parameter useless 13 | 14 | return: object containing time info with the following keys 15 | hour 16 | minute 17 | ampm 18 | date 19 | --------------- 20 | 21 | Example: 22 | ------------ 23 | dateTime:=getCurrentTime("IST",,1) 24 | msgbox % dateTime.hour ":" dateTime.minute " " dateTime.ampm ", " dateTime.date 25 | ------------ 26 | 27 | */ 28 | 29 | ; retrieve the current time by country [and region] or timezone 30 | getCurrentTime(country,region:="",countryIsTimezone:=0){ 31 | static regStr:="U)id=""fshrmin"">(\d{1,2}):(\d{1,2})<.*id=""fsampm"">(\w{2})<.*class=""fs-date"">([^<]+)<" 32 | static regStr2:="U)class=""ctm-hrmn"">(\d{1,2}):(\d{1,2})<.*ctm-ampm"">(\w{2})<.*ctm-date"">([^<]+)<" 33 | static url:="https://www.timeanddate.com/time/zone/" 34 | static url2:="https://www.timeanddate.com/time/zones/" 35 | 36 | if (countryIsTimezone) { 37 | regExMatch(urlDownloadToVar(url2 strToLower(country)),regStr2,cT) 38 | return cT?{hour: cT1,minute: cT2,ampm: cT3,date: cT4}:0 39 | } else { 40 | regExMatch(urlDownloadToVar(url country (region?"/" region:"")),regStr,cT) 41 | return cT?{hour: cT1,minute: cT2,ampm: cT3,date: cT4}:0 42 | } 43 | } -------------------------------------------------------------------------------- /Lib/getImageSize.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Retrieves the image width and height of an image file. 4 | 5 | Parameters: 6 | --------------- 7 | imagePath: path to image file 8 | 9 | return: object 10 | width 11 | height 12 | --------------- 13 | 14 | Example: 15 | ------------ 16 | iSize:=getImageSize(a_desktop . "\image.png") 17 | msgbox % iSize.width "x" iSize.height 18 | ------------ 19 | 20 | */ 21 | 22 | getImageSize(imagePath){ 23 | splitPath,imagePath,fN,fD 24 | 25 | oS:=comObjCreate("Shell.Application") 26 | oF:=oS.namespace(fD?fD:a_workingDir) 27 | oFn:=oF.parseName(fD?fN:imagePath) 28 | size:=strSplit(oFn.extendedProperty("Dimensions"),"x"," ?" chr(8234) chr(8236)) 29 | 30 | return {width: size[1],height: size[2]} 31 | } -------------------------------------------------------------------------------- /Lib/getPosFromAngle.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Calculates coords for a point based on a given point, 4 | length, and angle. 5 | 6 | Parameters: 7 | --------------- 8 | x1: x coord of starting point 9 | 10 | y1: y coord of starting point 11 | 12 | len: length (in pixels) from starting point 13 | 14 | ang: angle (in degrees) from starting point 15 | --------------- 16 | 17 | Example: 18 | ------------ 19 | getPosFromAngle(100,100,150,157) 20 | msgbox % floor(x) " x " floor(y) 21 | ------------ 22 | 23 | */ 24 | 25 | getPosFromAngle(x1,y1,len,ang){ 26 | ang:=(ang-90) * 0.0174532925 27 | return {"x": x1+len*cos(ang),"y": y1+len*sin(ang)} 28 | } -------------------------------------------------------------------------------- /Lib/getSelected.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Retrieves path of currently selected/highlighted item in explorer. 4 | 5 | Parameters: 6 | --------------- 7 | return: path of item 8 | --------------- 9 | 10 | Example: 11 | ------------ 12 | ; select an icon on the desktop and press F1 13 | F1::msgbox % getSelected() 14 | ------------ 15 | 16 | */ 17 | 18 | getSelected(){ 19 | cO:=clipboardAll 20 | clipboard:= 21 | send ^c 22 | clipWait,0.5 23 | if (errorlevel) { 24 | clipboard:=c0 25 | return 26 | } 27 | path:=clipboard 28 | clipboard:=cO 29 | return path 30 | } -------------------------------------------------------------------------------- /Lib/getUTCOffset.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Retrieves the UTC offset of a given timezone. 4 | 5 | Parameters: 6 | --------------- 7 | timezone: timezone code 8 | 9 | return: object containing offset 10 | sign: + or - 11 | hour 12 | minute 13 | --------------- 14 | 15 | Example: 16 | ------------ 17 | UTCOffset:=getUTCOffset("IST") 18 | nowUTC:=a_nowUTC 19 | if (UTCOffset.sign="+") { 20 | cTimeM:=(subStr(nowUTC,11,2)+UTCOffset.minute) 21 | cTimeH:=(subStr(nowUTC,9,2)+UTCOffset.hour) 22 | if (cTimeM>60) { 23 | cTimeM-=60 24 | cTimeH+=1 25 | } 26 | cTimeH:=cTimeH>24?cTimeH-24:cTimeH 27 | } else { 28 | cTimeH:=(subStr(nowUTC,9,2)-UTCOffset.hour) 29 | cTimeM:=(subStr(nowUTC,11,2)-UTCOffset.minute) 30 | if (cTimeM<0) { 31 | cTimeM+=60 32 | cTimeH-=1 33 | } 34 | cTimeH:=cTimeH<0?cTimeH+24:cTimeH 35 | } 36 | msgbox % "Offset: " UTCOffset.sign UTCOffset.hour ":" UTCOffset.minute "`nCurrent time: " format("{1:.2u}:{2:.2u}",cTimeH,cTimeM) "`nCurrent UTC: " subStr(nowUTC,9,2) ":" subStr(nowUTC,11,2) 37 | ------------ 38 | 39 | */ 40 | 41 | getUTCOffset(timezone){ 42 | static regStr:="U)UTC Offset:<\/a>[^+-]+([+-])(\d{1,2}):?(\d{1,2})?<" 43 | static url:="https://www.timeanddate.com/time/zones/" 44 | 45 | regExMatch(urlDownloadToVar(url strToLower(timezone)),regStr,cT) 46 | return cT?{sign: cT1,hour: cT2,minute: (cT3?cT3:0)}:0 47 | } -------------------------------------------------------------------------------- /Lib/getWinClientSize.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Retrieve the size of a windows client area. 4 | 5 | Parameters: 6 | --------------- 7 | hwnd: hwnd to window 8 | 9 | return: object 10 | width 11 | height 12 | --------------- 13 | 14 | Example: 15 | ------------ 16 | winGet,wHwnd,id,ahk_class Notepad ahk_exe notepad.exe 17 | cSize:=getWinClientSize(wHwnd) 18 | msgbox % "Client width: " cSize.width "`nClient height: " cSize.height 19 | ------------ 20 | 21 | */ 22 | 23 | getWinClientSize(hwnd){ 24 | varSetCapacity(rect,16,0) 25 | dllCall("GetClientRect","Ptr",hwnd,"Ptr",&rect) 26 | return {width: numGet(rect,8,"Int"), height: numGet(rect,12,"Int")} 27 | } -------------------------------------------------------------------------------- /Lib/hToMs.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Convert hours to milliseconds. 4 | 5 | Parameters: 6 | --------------- 7 | h: hours 8 | 9 | return: millisecond equivalent of given hours 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | ; sleep hToMs(0.5) 15 | msgbox % hToMs(1) 16 | ------------ 17 | 18 | */ 19 | 20 | hToMs(h){ 21 | return h*3.6e+6 22 | } -------------------------------------------------------------------------------- /Lib/hwndHung.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Check if a window is hung/non-responsive. 4 | 5 | Parameters: 6 | --------------- 7 | hwnd: hwnd of window 8 | 9 | return: 0 if responsive, 1 if unresponsive 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | winGet,wHwnd,id,ahk_class Notepad ahk_exe notepad.exe 15 | msgbox % hwndHung(wHwnd) 16 | ------------ 17 | 18 | */ 19 | 20 | hwndHung(hwnd){ 21 | return dllCall("user32\IsHungAppWindow","Ptr",hwnd) 22 | } -------------------------------------------------------------------------------- /Lib/ifContains.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Function wrapper for if-contains command. 4 | 5 | Parameters: 6 | --------------- 7 | haystack: string/value 8 | 9 | needle: csv matchlist 10 | 11 | return: 1 or null, if haystack does or does not contain an element in matchlist/needle 12 | --------------- 13 | 14 | Example: 15 | ------------ 16 | msgbox % ifContains("hello","nel,low") ifContains("hello","hel,not") 17 | ------------ 18 | 19 | */ 20 | 21 | ifContains(haystack,needle){ 22 | if haystack contains %needle% 23 | return 1 24 | } -------------------------------------------------------------------------------- /Lib/ifIn.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Function wrapper for if-in command. 4 | 5 | Parameters: 6 | --------------- 7 | needle: string/value 8 | 9 | haystack: csv matchlist 10 | 11 | return: 1 or null, if needle is or is not in haystack/matchlist 12 | --------------- 13 | 14 | Example: 15 | ------------ 16 | msgbox % ifIn("hello","hel,not") ifIn("hello","hello,not") 17 | ------------ 18 | 19 | */ 20 | 21 | ifIn(needle,haystack){ 22 | if needle in %haystack% 23 | return 1 24 | } -------------------------------------------------------------------------------- /Lib/imageSearchc.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | GDI+ based alternative to ImageSearch command. 4 | 5 | Dependencies: 6 | Gdip_All 7 | Gdip_ImageSearch (included in this repository's Gdip_All) 8 | ----------------- 9 | 10 | Parameters: 11 | --------------- 12 | byRef out1: variable to store found x position 13 | 14 | byRef out2: variable to store found y position 15 | 16 | x1: top-left x coord of search area 17 | 18 | y1: top-left y coord of search area 19 | 20 | x2: bottom-right x coord of search area 21 | 22 | y2: bottom-right y coord of search area 23 | 24 | image: path to image file to search the screen for 25 | 26 | vari (optional): variation level (0-255) 27 | 28 | trans (optional): hexadecimal color value to treat as transparent 29 | 30 | direction (optional): direction to search 31 | Vertical preference: 32 | 1 = top->left->right->bottom (matches top-left pixel) 33 | 2 = bottom->left->right->top (matches bottom-left pixel) 34 | 3 = bottom->right->left->top (matches bottom-right pixel) 35 | 4 = top->right->left->bottom (matches top-right pixel) 36 | Horizontal preference: 37 | 5 = left->top->bottom->right (matches top-left pixel) [default] 38 | 6 = left->bottom->top->right (matches bottom-left pixel) 39 | 7 = right->bottom->top->left (matches bottom-right pixel) 40 | 8 = right->top->bottom->left (matches top-right pixel) 41 | 42 | debug (optional): save the screen image to the working directory 43 | 44 | return: 1 or 0, if match was found or not found 45 | --------------- 46 | 47 | Example: 48 | ------------ 49 | sErrLev:=imageSearchc(fx,fy,0,0,a_screenWidth,a_screenHeight,a_desktop "\image.png") 50 | msgbox % sErrLev "`n" fx "x" fy 51 | ------------ 52 | 53 | */ 54 | 55 | #include 56 | 57 | imageSearchc(byRef out1,byRef out2,x1,y1,x2,y2,image,vari:=0,trans:="",direction:=5,debug:=0){ 58 | static ptok:=gdip_startup() 59 | imageB:=gdip_createBitmapFromFile(image) 60 | scrn:=gdip_bitmapfromscreen(x1 "|" y1 "|" x2 - x1 "|" y2 - y1) 61 | if(debug) 62 | gdip_saveBitmapToFile(scrn,a_now ".png") 63 | errorlev:=gdip_imageSearch(scrn,imageB,tempxy,0,0,0,0,vari,trans,direction) 64 | gdip_disposeImage(scrn) 65 | gdip_disposeImage(imageB) 66 | 67 | if (errorlev) { 68 | out:=strSplit(tempxy,"`,") 69 | out1:=out[1] + x1 70 | out2:=out[2] + y1 71 | return % errorlev 72 | } 73 | return 0 74 | } 75 | -------------------------------------------------------------------------------- /Lib/internetConnected.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Check if a url is accessible from your device. 4 | 5 | Parameters: 6 | --------------- 7 | url (optional): url to check 8 | 9 | return: 1 or 0, if a connection could be made or not 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % "Can connect to google: " internetConnected() 15 | ------------ 16 | 17 | */ 18 | 19 | internetConnected(url:="http://google.com"){ 20 | if (!dllCall("Wininet.dll\InternetCheckConnection","Str",url,"Uint",1,"Uint",0)) 21 | return 0 22 | return 1 23 | } -------------------------------------------------------------------------------- /Lib/invertCaseChr.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Inverts the case of a character. 4 | 5 | Parameters: 6 | --------------- 7 | char: character to invert 8 | 9 | return: case-inverted character 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % invertCaseChr("a") 15 | ------------ 16 | 17 | */ 18 | 19 | invertCaseChr(char){ 20 | return asc(char)>96?chr(asc(char)-32):chr(asc(char)+32) 21 | } -------------------------------------------------------------------------------- /Lib/invertCaseStr.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Inverts the case of a string. 4 | 5 | Parameters: 6 | --------------- 7 | str: string to invert 8 | 9 | return: case-inverted string 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % invertCaseStr("hELLO") 15 | ------------ 16 | 17 | */ 18 | 19 | invertCaseStr(str){ 20 | loop,parse,str 21 | nStr.=asc(a_loopField)>96?chr(asc(a_loopField)-32):chr(asc(a_loopField)+32) 22 | return nStr 23 | } -------------------------------------------------------------------------------- /Lib/is64bitExe.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Check if an executable is 64-bit. 4 | 5 | Parameters: 6 | --------------- 7 | path: path to executable 8 | 9 | return 1 or 0, if the executable is 64-bit or not 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % is64bitExe(a_winDir "\regedit.exe") 15 | ------------ 16 | 17 | */ 18 | 19 | is64bitExe(path){ 20 | dllCall("GetBinaryType","astr",path,"uint*",type) 21 | return 6=type 22 | } -------------------------------------------------------------------------------- /Lib/isAlpha.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Function wrapper of if-alpha. 4 | 5 | Parameters: 6 | --------------- 7 | in: value to check 8 | 9 | return: 1 or null 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % isAlpha("Hello") 15 | ------------ 16 | 17 | */ 18 | 19 | isAlpha(in){ 20 | if in is alpha 21 | return 1 22 | } -------------------------------------------------------------------------------- /Lib/isAlphaNum.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Function wrapper of if-alphanum. 4 | 5 | Parameters: 6 | --------------- 7 | in: value to check 8 | 9 | return: 1 or null 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % isAlphaNum("Hello123") 15 | ------------ 16 | 17 | */ 18 | 19 | isAlphaNum(in){ 20 | if in is alnum 21 | return 1 22 | } -------------------------------------------------------------------------------- /Lib/isBetween.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Function wrapper of if-between. 4 | 5 | Parameters: 6 | --------------- 7 | in: value to check 8 | 9 | return: 1 or 0 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % isBetween(1,50,99) 15 | ------------ 16 | 17 | */ 18 | 19 | isBetween(lower,check,upper){ 20 | if check between %lower% and %upper% 21 | return 1 22 | return 0 23 | } -------------------------------------------------------------------------------- /Lib/isDigit.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Function wrapper of if-digit. 4 | 5 | Parameters: 6 | --------------- 7 | in: value to check 8 | 9 | return: 1 or null 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % isDigit(15) 15 | ------------ 16 | 17 | */ 18 | 19 | isDigit(in){ 20 | if in is digit 21 | return 1 22 | } -------------------------------------------------------------------------------- /Lib/isFloat.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Function wrapper of if-float. 4 | 5 | Parameters: 6 | --------------- 7 | in: value to check 8 | 9 | return: 1 or null 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % isFloat(3.14) 15 | ------------ 16 | 17 | */ 18 | 19 | isFloat(in){ 20 | if in is float 21 | return 1 22 | } -------------------------------------------------------------------------------- /Lib/isHex.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Function wrapper of if-hex. 4 | 5 | Parameters: 6 | --------------- 7 | in: value to check 8 | 9 | return: 1 or null 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % isHex(0xBFE) 15 | ------------ 16 | 17 | */ 18 | 19 | isHex(in){ 20 | if in is xdigit 21 | return 1 22 | } -------------------------------------------------------------------------------- /Lib/isInt.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Function wrapper of if-int. 4 | 5 | Parameters: 6 | --------------- 7 | in: value to check 8 | 9 | return: 1 or null 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % isInt(123) 15 | ------------ 16 | 17 | */ 18 | 19 | isInt(in){ 20 | if in is integer 21 | return 1 22 | } -------------------------------------------------------------------------------- /Lib/isLower.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Function wrapper of if-lower. 4 | 5 | Parameters: 6 | --------------- 7 | in: value to check 8 | 9 | return: 1 or null 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % isLower("hello") 15 | ------------ 16 | 17 | */ 18 | 19 | isLower(in){ 20 | if in is lower 21 | return 1 22 | } -------------------------------------------------------------------------------- /Lib/isNum.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Function wrapper of if-num. 4 | 5 | Parameters: 6 | --------------- 7 | in: value to check 8 | 9 | return: 1 or null 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % isNum(123) 15 | ------------ 16 | 17 | */ 18 | 19 | isNum(in){ 20 | if in is number 21 | return 1 22 | } -------------------------------------------------------------------------------- /Lib/isSpace.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Function wrapper of if-space. 4 | 5 | Parameters: 6 | --------------- 7 | in: value to check 8 | 9 | return: 1 or null 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % isSpace(" ") 15 | ------------ 16 | 17 | */ 18 | 19 | isSpace(in){ 20 | if in is space 21 | return 1 22 | } -------------------------------------------------------------------------------- /Lib/isUpper.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Function wrapper of if-upper. 4 | 5 | Parameters: 6 | --------------- 7 | in: value to check 8 | 9 | return: 1 or null 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % isUpper("HELLO") 15 | ------------ 16 | 17 | */ 18 | 19 | isUpper(in){ 20 | if in is upper 21 | return 1 22 | } -------------------------------------------------------------------------------- /Lib/lanConnected.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Check if you are connected to a LAN. 4 | 5 | Parameters: 6 | --------------- 7 | return: 1 or 0, if connected or not 8 | --------------- 9 | 10 | Example: 11 | ------------ 12 | msgbox % lanConnected() 13 | ------------ 14 | 15 | */ 16 | 17 | lanConnected(){ 18 | if (!dllCall("Wininet.dll\InternetGetConnectedState","Str","","Int",0)) 19 | return 0 20 | return 1 21 | } -------------------------------------------------------------------------------- /Lib/mToMs.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Converts minutes to milliseconds. 4 | 5 | Parameters: 6 | --------------- 7 | m: minutes 8 | 9 | return: millisecond equivalent of given minutes 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % mToMs(5) 15 | ------------ 16 | 17 | */ 18 | 19 | mToMs(m){ 20 | return m*0.6e+5 21 | } -------------------------------------------------------------------------------- /Lib/mouseOverWin.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Check if a particular window is currently under the mouse. 4 | 5 | Parameters: 6 | --------------- 7 | winName: WinTitle to check against 8 | 9 | winText (optonal): window text to check against 10 | 11 | return: 1 or 0, if winName is under the mouse or not 12 | --------------- 13 | 14 | Example: 15 | ------------ 16 | msgbox % mouseOverWin("ahk_class Notepad ahk_exe notepad.exe") 17 | ------------ 18 | 19 | */ 20 | 21 | mouseOverWin(winName,winText:=""){ 22 | winGet,cH,id,% winName,% winText 23 | mouseGetPos,,,cHw 24 | return cH=cHw 25 | } -------------------------------------------------------------------------------- /Lib/msToH.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Convert milliseconds to hours. 4 | 5 | Parameters: 6 | --------------- 7 | ms: milliseconds 8 | 9 | return: hour equivalent of given milliseconds 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % msToH(3600000) 15 | ------------ 16 | 17 | */ 18 | 19 | msToH(ms){ 20 | return round(ms/3.6e+6,2) 21 | } -------------------------------------------------------------------------------- /Lib/msToM.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Converts milliseconds to minutes. 4 | 5 | Parameters: 6 | --------------- 7 | ms: milliseconds 8 | 9 | return: minute equivalent of given milliseconds 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % msToM(60000) 15 | ------------ 16 | 17 | */ 18 | 19 | msToM(ms){ 20 | return round(ms/0.6e+5,2) 21 | } -------------------------------------------------------------------------------- /Lib/msToS.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Converts milliseconds to seconds. 4 | 5 | Parameters: 6 | --------------- 7 | ms: milliseconds 8 | 9 | return: second equivalent of given milliseconds 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % msToS(30000) 15 | ------------ 16 | 17 | */ 18 | 19 | msToS(ms){ 20 | return round(ms/0.1e+4,2) 21 | } -------------------------------------------------------------------------------- /Lib/multiKeyStates.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Checks for multiple key states at once. 4 | 5 | Parameters: 6 | --------------- 7 | keyArray: array of keys to be checked 8 | 9 | andor (optional): 0, use 'and' to check, 1, use 'or' to check 10 | 11 | mode (optional): getKeyState mode 12 | 13 | return: 1 or 0, if keystates are pressed or released 14 | --------------- 15 | 16 | Example: 17 | ------------ 18 | ^F1:: 19 | f:=0 20 | while (multiKeyStates(["ctrl","F1"])) { 21 | tooltip,% f+=10 22 | sleep 10 23 | } 24 | return 25 | ------------ 26 | 27 | */ 28 | 29 | multiKeyStates(keyArray,andor:=0,mode:="P"){ 30 | for i,a in keyArray { 31 | state:=getKeyState(a,mode) 32 | statea+=state 33 | if (!andor && !state) 34 | return 0 35 | else if (andor && state) 36 | return 1 37 | } 38 | return !statea?0:1 39 | } -------------------------------------------------------------------------------- /Lib/muteWindow.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Mute a window. 4 | 5 | Dependencies: 6 | VA 7 | ----------------- 8 | 9 | Parameters: 10 | --------------- 11 | winName: WinTitle of window 12 | 13 | mode: t - toggle, 0 - off, 1 - on 14 | --------------- 15 | 16 | Example: 17 | ------------ 18 | F1::muteWindow() 19 | ------------ 20 | 21 | */ 22 | 23 | #include 24 | 25 | muteWindow(winName:="a",mode:="t"){ 26 | winGet,winPid,PID,% winName 27 | if !(volume:=GetVolumeObject(winPid)) 28 | return 29 | if (mode="t") { 30 | VA_ISimpleAudioVolume_GetMute(volume,Mute) ;Get mute state 31 | VA_ISimpleAudioVolume_SetMute(volume,!Mute) ;Toggle mute state 32 | } else if (mode<=1 && mode>=1) { 33 | VA_ISimpleAudioVolume_SetMute(volume,mode) 34 | } 35 | objRelease(volume) 36 | return 37 | } -------------------------------------------------------------------------------- /Lib/nicRestart.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Restart NIC (network interface card). 4 | 5 | Parameters: 6 | --------------- 7 | adapter: name of NIC 8 | --------------- 9 | 10 | Example: 11 | ------------ 12 | nicRestart("Wi-Fi") 13 | ------------ 14 | 15 | */ 16 | 17 | nicRestart(adapter){ 18 | runwait,% comspec " /c netsh interface set interface """ adapter """ disable&netsh interface set interface """ adapter """ enable",,hide 19 | } -------------------------------------------------------------------------------- /Lib/nicSetState.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Set NIC (network interface card) state. 4 | 5 | Parameters: 6 | --------------- 7 | adapter: name of NIC 8 | 9 | state: 0 - disabled, 1 - enabled 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | nicSetState("Wi-Fi",1) 15 | ------------ 16 | 17 | */ 18 | 19 | nicSetState(adapter,state){ 20 | runwait,% "netsh interface set interface """ adapter """ " (state?"enable":"disable"),,hide 21 | } -------------------------------------------------------------------------------- /Lib/processExist.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Function wrapper for 'process, exist' command. 4 | 5 | Parameters: 6 | --------------- 7 | im: PID or name of process 8 | 9 | return: PID of process or 0 if not found 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % processExist("system") 15 | ------------ 16 | 17 | */ 18 | 19 | processExist(im){ 20 | process,exist,% im 21 | return errorLevel 22 | } -------------------------------------------------------------------------------- /Lib/processPriority.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Returns current process priority of process. 4 | 5 | Parameters: 6 | --------------- 7 | PID: PID of process 8 | 9 | return: Priority ID 10 | Above Normal - 0x8000 or ‭32768‬ 11 | Below Normal - 0x4000 or ‭16384‬ 12 | High - 0x80 or 128 13 | Idle - 0x40 or 64 14 | Normal - 0x20 or 32 15 | Realtime - 0x100 or 400 16 | --------------- 17 | 18 | Example: 19 | ------------ 20 | msgbox % processPriority(dllCall("GetCurrentProcessId")) 21 | ------------ 22 | 23 | */ 24 | 25 | processPriority(PID){ 26 | return dllCall("GetPriorityClass","UInt",dllCall("OpenProcess","Uint",0x400,"Int",0,"UInt",PID)),dllCall("CloseHandle","Uint",hProc) 27 | } -------------------------------------------------------------------------------- /Lib/rand.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Function wrapper for 'random' command. 4 | 5 | Parameters: 6 | --------------- 7 | lowerBound: minimum possible value 8 | 9 | upperBound: maximum possible value 10 | 11 | return: random value 12 | --------------- 13 | 14 | Example: 15 | ------------ 16 | msgbox % rand(1,100) 17 | ------------ 18 | 19 | */ 20 | 21 | rand(lowerBound,upperBound){ 22 | random,rand,% lowerBound,% upperBound 23 | return rand 24 | } -------------------------------------------------------------------------------- /Lib/randStr.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Generates random string. 4 | 5 | Dependencies: 6 | ifContains() 7 | ----------------- 8 | 9 | Parameters: 10 | --------------- 11 | lowerBound: minimum length 12 | 13 | upperBound: maximum length 14 | 15 | mode (optional): possible character types (can be combined) 16 | 1 - lowercase, 2 - uppercase, 3 - digits, 4 - symbols 17 | --------------- 18 | 19 | Example: 20 | ------------ 21 | msgbox % randStr(3,5,1234) 22 | ------------ 23 | 24 | */ 25 | 26 | randStr(lowerBound,upperBound,mode:=1){ 27 | if (!isDigit(lowerBound)||!isDigit(upperBound)||!isDigit(mode)) 28 | return -1 29 | loop % rand(lowerBound,upperBound) { 30 | t:="" 31 | if (strLen(mode)=1) { 32 | t:=mode 33 | } else { 34 | while (!ifContains(mode,t)) 35 | t:=rand(1,4) 36 | } 37 | if (t=1) { 38 | str.=chr(rand(97,122)) 39 | } else if (t=2) { 40 | str.=chr(rand(65,90)) 41 | } else if (t=3) { 42 | str.=rand(0,9) 43 | } else if (t=4) { 44 | i:=rand(1,4) 45 | str.=i=1?chr(rand(33,47)):i=2?chr(rand(58,64)):i=3?chr(rand(91,96)):chr(rand(123,126)) 46 | } 47 | } 48 | return str 49 | } 50 | -------------------------------------------------------------------------------- /Lib/readHotkeys.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Create a list of all static hotkeys in an AHK script file (not perfect). 4 | Includes #if directives. 5 | 6 | Parameters: 7 | --------------- 8 | filepath: path to AHK file 9 | 10 | retObj (optional): 1 - return an object, 0 - return a string 11 | 12 | return: list of hotkeys in the form of '{line number} {hotkey or #if}' 13 | --------------- 14 | 15 | Example: 16 | ------------ 17 | msgbox % readHotkeys(a_scriptFullPath) 18 | 19 | ~F1:: 20 | ~F2:: 21 | return 22 | ------------ 23 | 24 | */ 25 | 26 | readHotkeys(filepath,retObj:=0){ 27 | local 28 | comment:=0,hlObj:={} 29 | static regExN:={singleComment:"^\s{0,};",blockComment:"^\s{0,}/\*",blockCommentEnd:"^\s{0,}\*/",directive:"i)^\s{0,}#if",hotskey:"::"} 30 | rFile:=fileOpen(filepath,"r") 31 | 32 | while (!rFile.atEOF) { 33 | cLine:=rFile.readLine() 34 | if (comment || cLine~=regExN.singleComment) { ; inside block comment/single-line comment 35 | if (cLine~=regExN.blockCommentEnd) { ; check for end block comment 36 | comment:=0 37 | } 38 | continue 39 | } else if (cLine~=regExN.blockComment) { ; check for block comment 40 | comment:=1 41 | continue 42 | } else if (cLine~=regExN.directive || cLine~=regExN.hotskey) { ; get if-directive/get hotstring/hotkey (literal) 43 | if (retObj) 44 | hlObj[a_index]:=cLine 45 | strOut.=a_index a_tab cLine 46 | } 47 | } 48 | rFile.close() 49 | if (retObj) { 50 | hlObj.str:=strOut 51 | return hlObj 52 | } 53 | return strOut 54 | } -------------------------------------------------------------------------------- /Lib/regExMatchI.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | String-inverted RegExMatch. Useful if you know it will match towards the end 4 | of a large string. 5 | 6 | Dependencies: 7 | strI() 8 | ----------------- 9 | 10 | Parameters: 11 | --------------- 12 | haystack: string to search 13 | 14 | needleRegEx: regex to use 15 | 16 | byRef unquotedOutputVar (optional): variable to store found string 17 | 18 | startingPosition (optional): string position to start at 19 | 20 | return: position of found match 21 | --------------- 22 | 23 | Example: 24 | ------------ 25 | msgbox % regExMatchI("Hello World",".{3}",foundStr) 26 | msgbox % foundStr "`n" strI(foundStr) 27 | ------------ 28 | 29 | */ 30 | 31 | regExMatchI(haystack,needleRegEx,byRef unquotedOutputVar:="",startingPosition:=1){ 32 | return abs(regExMatch(strI(haystack),needleRegEx,unquotedOutputVar,startingPosition)-strLen(haystack))+1 33 | } -------------------------------------------------------------------------------- /Lib/regExReplaceI.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | String-inverted RegExReplace. Useful if you know it will match towards the end 4 | of a large string. 5 | 6 | Dependencies: 7 | strI() 8 | ----------------- 9 | 10 | Parameters: 11 | --------------- 12 | haystack: string to search 13 | 14 | needleRegEx: regex to use 15 | 16 | replacement (optional): replacement text 17 | 18 | byRef outputVarCount (optional): variable to store found count 19 | 20 | limit (optional): maximum replacements allowed 21 | 22 | startingPosition (optional): string position to start at 23 | 24 | return: string after replacement 25 | --------------- 26 | 27 | Example: 28 | ------------ 29 | foundStr:=regExReplaceI("Hello World","[A-Z]","M") 30 | msgbox % foundStr "`n" strI(foundStr) 31 | ------------ 32 | 33 | */ 34 | 35 | regExReplaceI(haystack,needleRegEx,replacement:="",byref outputVarCount:="",limit:=-1,startingPosition:=1){ 36 | return strI(regExReplace(strI(haystack),needleRegEx,replacement,outputVarCount,limit,startingPosition)) 37 | } -------------------------------------------------------------------------------- /Lib/sToMs.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Converts seconds to Milliseconds. 4 | 5 | Parameters: 6 | --------------- 7 | s: seconds 8 | 9 | return millisecond equivalent of given seconds 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % sToMs(30) 15 | ------------ 16 | 17 | */ 18 | 19 | sToMs(s){ 20 | return s*0.1e+4 21 | } -------------------------------------------------------------------------------- /Lib/setWindowVol.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Set the volume of a given WinTitle. This is equivalent to 4 | opening the volume mixer and changing an applications volume. 5 | 6 | Dependencies: 7 | VA 8 | ----------------- 9 | 10 | Parameters: 11 | --------------- 12 | winName (optional): winTitle of any window, defaults to active 13 | 14 | vol: volume level between 0-100; can be + or - prefixed to step 15 | --------------- 16 | 17 | Example: 18 | ------------ 19 | setWindowVol("ahk_exe vlc.exe",50) ; set it to 50% 20 | setWindowVol("ahk_exe vlc.exe","+10") ; set it to +10 percent of its current volume 21 | setWindowVol("ahk_exe vlc.exe","-10") ; set it to -10 percent of its current volume 22 | ------------ 23 | 24 | */ 25 | 26 | #include 27 | 28 | setWindowVol(winName:="a",vol:="n"){ 29 | if (vol=="n") 30 | return 31 | winGet,winPid,PID,% winName 32 | if !(volume:=GetVolumeObject(winPid)) 33 | return 34 | vsign:=subStr(vol,1,1) 35 | if (vsign="+"||vsign="-") { 36 | vol:=subStr(vol,2),vol/=100 37 | 38 | VA_ISimpleAudioVolume_GetMasterVolume(volume,cvol) 39 | if (vsign="+") 40 | vol:=cvol+vol>1?1:cvol+vol 41 | else if (vsign="-") 42 | vol:=cvol-vol<0?0:cvol-vol 43 | } else 44 | vol/=100.0 45 | VA_ISimpleAudioVolume_SetMasterVolume(volume,vol),objRelease(volume) 46 | } 47 | -------------------------------------------------------------------------------- /Lib/strI.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Invert given string. 4 | 5 | Parameters: 6 | --------------- 7 | str: string to invert 8 | 9 | return: inverted string 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % strI("Hello World") 15 | ------------ 16 | 17 | */ 18 | 19 | strI(str){ 20 | static rev:=a_isUnicode?"_wcsrev":"_strrev" 21 | dllCall("msvcrt.dll\" . rev,"Ptr",&str,"CDECL") 22 | return str 23 | } -------------------------------------------------------------------------------- /Lib/strReplaceI.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | String-inverted StrReplace. Useful if you know it will match towards the end 4 | of a large string. 5 | 6 | Parameters: 7 | --------------- 8 | haystack: string to search 9 | 10 | searchText: text to find 11 | 12 | replaceText (optional): replacement text 13 | 14 | byRef outputVarCount (optional): variable to store found count 15 | 16 | limit (optional): maximum replacements allowed 17 | 18 | return: string after replacement 19 | --------------- 20 | 21 | Example: 22 | ------------ 23 | foundStr:=strReplaceI("Hello World","l","_") 24 | msgbox % foundStr "`n" strI(foundStr) 25 | ------------ 26 | 27 | */ 28 | 29 | strReplaceI(haystack,searchText,replaceText:="",byref outputVarCount:="",limit:=-1){ 30 | return strI(strReplace(strI(haystack),searchText,replaceText,outputVarCount,limit)) 31 | } -------------------------------------------------------------------------------- /Lib/strToLower.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Convert string to lowercase. 4 | 5 | Parameters: 6 | --------------- 7 | str: string to convert 8 | 9 | return: lowercase string 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | strToLower("hello world") 15 | ------------ 16 | 17 | */ 18 | 19 | strToLower(str){ 20 | stringLower,nStr,str 21 | return nStr 22 | } -------------------------------------------------------------------------------- /Lib/strToUpper.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Convert string to uppercase. 4 | 5 | Parameters: 6 | --------------- 7 | str: string to convert 8 | 9 | return: uppercase string 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | strToUpper("hello world") 15 | ------------ 16 | 17 | */ 18 | 19 | strToUpper(str){ 20 | stringUpper,nStr,str 21 | return nStr 22 | } -------------------------------------------------------------------------------- /Lib/stringify.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Converts an object into a string for debugging purposes. 4 | 5 | Parameters: 6 | --------------- 7 | obj: object to convert 8 | 9 | return: object string 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % stringify({"He":"lo","Wo":"rld"} 15 | ------------ 16 | 17 | */ 18 | 19 | stringify(obj){ 20 | local outStr,i,a 21 | 22 | for i,a in obj 23 | outStr.=(a_index!=1?",":"") (regExMatch(i,"\W")?"""" . i . """":i) . ": " . (isObject(a)?stringify(a):"""" a """") 24 | 25 | return "{" outStr "}" 26 | } -------------------------------------------------------------------------------- /Lib/threadMan.ahk: -------------------------------------------------------------------------------- 1 | #include <_MemoryLibrary> 2 | 3 | class threadMan { 4 | ahkDllPath:= 5 | dllObj:= 6 | tHandle:= 7 | quitTimeout:=1000 8 | 9 | ; meta-functions 10 | 11 | __New(ahkDllPath,isResource=0){ 12 | this.ahkDllPath:=ahkDllPath 13 | ; if(isResource) 14 | ; readResource(dlldata,ahkDllPath) 15 | ; else 16 | fileRead,dlldata,% "*c " . ahkDllPath 17 | this.dllObj:=new _MemoryLibrary(&dlldata) 18 | } 19 | 20 | __Delete(){ 21 | this.quit(this.quitTimeout) 22 | this.dllObj.free() 23 | this.dllObj:=this.tHandle:="" 24 | } 25 | 26 | ; methods 27 | 28 | newFromText(codeStr,options="",params=""){ 29 | if(this.status()) 30 | return 1 31 | this.tHandle:=dllCall(this.dllObj.getProcAddress("ahktextdll"),"Str",codeStr,"Str",options,"Str",params,"Cdecl UPtr") 32 | } 33 | 34 | newFromFile(filePath,options="",params=""){ 35 | if(this.status()) 36 | return 1 37 | this.tHandle:=dllCall(this.dllObj.getProcAddress("ahkdll"),"Str",filePath,"Str",options,"Str",params,"Cdecl UPtr") 38 | } 39 | 40 | addScript(codeStr,execute=0){ 41 | return dllCall(this.dllObj.getProcAddress("addScript"),"Str",codeStr,"Uchar",execute,"Cdecl UPtr") 42 | } 43 | 44 | ; ignoreError: 0=signal an error if there was problem adding file 45 | ; 1=ignore error 46 | ; 2=remove script lines added by previous calls to addFile() and start executing at the first line in the new script 47 | addFile(filePath,includeAgain=0,ignoreError=0){ 48 | return dllCall(this.dllObj.getProcAddress("addFile"),"Str",filePath,"Uchar",includeAgain,"Uchar",ignoreError,"Cdecl UPtr") 49 | } 50 | 51 | waitQuit(timeout="",sleepAccuracy=100){ 52 | if(timeout) 53 | while(this.status() && timePast < timeout){ 54 | sleep sleepAccuracy 55 | timePast+=sleepAccuracy 56 | } 57 | else 58 | while(this.status()) 59 | sleep sleepAccuracy 60 | return this.status() 61 | } 62 | 63 | quit(timeout=0){ 64 | dllCall(this.dllObj.getProcAddress("ahkTerminate"),"Int",timeout,"Cdecl Int") 65 | } 66 | 67 | status(){ 68 | return dllCall(this.dllObj.getProcAddress("ahkReady")) 69 | } 70 | 71 | reload(){ 72 | dllCall(this.dllObj.getProcAddress("ahkReload")) 73 | } 74 | 75 | pause(pauseState:="tog"){ 76 | if(pauseState="tog"){ 77 | pauseState:=!this.pauseState() 78 | ;pauseState:=!pauseState 79 | } 80 | pauseState:=dllCall(this.dllObj.getProcAddress("ahkPause"),"Str",pauseState,"Cdecl Int") 81 | return pauseState 82 | } 83 | 84 | pauseState(){ 85 | return dllCall(this.dllObj.getProcAddress("ahkPause"),"Str","","Cdecl Int") 86 | } 87 | 88 | state(){ 89 | running:=this.status() 90 | if(running){ 91 | pauseState:=this.pauseState() 92 | suspendState:=this.varGet("a_isSuspended") 93 | return pauseState?(suspendState?"P/S":"Paused"):(suspendState?"Suspended":"Running") 94 | } 95 | return "Stopped" 96 | } 97 | 98 | exec(codeStr){ 99 | if(this.pauseState()) 100 | msgbox,,Error,Code can not be executed while thread is paused. 101 | else 102 | return dllCall(this.dllObj.getProcAddress("ahkExec"),"Str",codeStr) 103 | } 104 | 105 | execLine(linePointer="",mode="",wait=""){ 106 | if(this.pauseState()) 107 | msgbox,,Error,Code can not be executed while thread is paused. 108 | else 109 | return dllCall(this.dllObj.getProcAddress("ahkExecuteLine"),"UPtr",linePointer,"UInt",mode,"UInt",wait,"Cdecl UPtr") 110 | } 111 | 112 | execLabel(label,wait=0){ 113 | if(this.pauseState()) 114 | msgbox,,Error,Code can not be executed while thread is paused. 115 | else 116 | return dllCall(this.dllObj.getProcAddress("ahkLabel"),"Str",label,"UInt",wait,"Cdecl UInt") 117 | } 118 | 119 | execFunc(func,params*){ 120 | if(this.pauseState()){ 121 | msgbox,,Error,Code can not be executed while thread is paused. 122 | return 123 | } 124 | 125 | if(!params.length()) 126 | return dllCall(this.dllObj.getProcAddress("ahkFunction"),"Str",func,"Cdecl UInt") 127 | if(params.length()=1) 128 | return dllCall(this.dllObj.getProcAddress("ahkFunction"),"Str",func,"Str",params[1],"Cdecl UInt") 129 | if(params.length()=2) 130 | return dllCall(this.dllObj.getProcAddress("ahkFunction"),"Str",func,"Str",params[1],"Str",params[2],"Cdecl UInt") 131 | if(params.length()=3) 132 | return dllCall(this.dllObj.getProcAddress("ahkFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Cdecl UInt") 133 | if(params.length()=4) 134 | return dllCall(this.dllObj.getProcAddress("ahkFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Str",params[4],"Cdecl UInt") 135 | if(params.length()=5) 136 | return dllCall(this.dllObj.getProcAddress("ahkFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Str",params[4],"Str",params[5],"Cdecl UInt") 137 | if(params.length()=6) 138 | return dllCall(this.dllObj.getProcAddress("ahkFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Str",params[4],"Str",params[5],"Str",params[6],"Cdecl UInt") 139 | if(params.length()=7) 140 | return dllCall(this.dllObj.getProcAddress("ahkFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Str",params[4],"Str",params[5],"Str",params[6],"Str",params[7],"Cdecl UInt") 141 | if(params.length()=8) 142 | return dllCall(this.dllObj.getProcAddress("ahkFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Str",params[4],"Str",params[5],"Str",params[6],"Str",params[7],"Str",params[8],"Cdecl UInt") 143 | if(params.length()=9) 144 | return dllCall(this.dllObj.getProcAddress("ahkFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Str",params[4],"Str",params[5],"Str",params[6],"Str",params[7],"Str",params[8],"Str",params[9],"Cdecl UInt") 145 | if(params.length()=10) 146 | return dllCall(this.dllObj.getProcAddress("ahkFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Str",params[4],"Str",params[5],"Str",params[6],"Str",params[7],"Str",params[8],"Str",params[9],"Str",params[10],"Cdecl UInt") 147 | } 148 | 149 | execAFunc(func,params*){ 150 | if(!params.length()) 151 | return dllCall(this.dllObj.getProcAddress("ahkPostFunction"),"Str",func,"Cdecl UInt") 152 | if(params.length()=1) 153 | return dllCall(this.dllObj.getProcAddress("ahkPostFunction"),"Str",func,"Str",params[1],"Cdecl UInt") 154 | if(params.length()=2) 155 | return dllCall(this.dllObj.getProcAddress("ahkPostFunction"),"Str",func,"Str",params[1],"Str",params[2],"Cdecl UInt") 156 | if(params.length()=3) 157 | return dllCall(this.dllObj.getProcAddress("ahkPostFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Cdecl UInt") 158 | if(params.length()=4) 159 | return dllCall(this.dllObj.getProcAddress("ahkPostFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Str",params[4],"Cdecl UInt") 160 | if(params.length()=5) 161 | return dllCall(this.dllObj.getProcAddress("ahkPostFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Str",params[4],"Str",params[5],"Cdecl UInt") 162 | if(params.length()=6) 163 | return dllCall(this.dllObj.getProcAddress("ahkPostFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Str",params[4],"Str",params[5],"Str",params[6],"Cdecl UInt") 164 | if(params.length()=7) 165 | return dllCall(this.dllObj.getProcAddress("ahkPostFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Str",params[4],"Str",params[5],"Str",params[6],"Str",params[7],"Cdecl UInt") 166 | if(params.length()=8) 167 | return dllCall(this.dllObj.getProcAddress("ahkPostFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Str",params[4],"Str",params[5],"Str",params[6],"Str",params[7],"Str",params[8],"Cdecl UInt") 168 | if(params.length()=9) 169 | return dllCall(this.dllObj.getProcAddress("ahkPostFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Str",params[4],"Str",params[5],"Str",params[6],"Str",params[7],"Str",params[8],"Str",params[9],"Cdecl UInt") 170 | if(params.length()=10) 171 | return dllCall(this.dllObj.getProcAddress("ahkPostFunction"),"Str",func,"Str",params[1],"Str",params[2],"Str",params[3],"Str",params[4],"Str",params[5],"Str",params[6],"Str",params[7],"Str",params[8],"Str",params[9],"Str",params[10],"Cdecl UInt") 172 | } 173 | 174 | varSet(varName,varVal){ 175 | return dllCall(this.dllObj.getProcAddress("ahkassign"),"Str",varName,"Str",varVal) 176 | } 177 | 178 | varGet(varName,pointer=0){ 179 | return dllCall(this.dllObj.getProcAddress("ahkgetvar"),"Str",varName,"UInt",pointer,"Cdecl Str") 180 | } 181 | } -------------------------------------------------------------------------------- /Lib/tool.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Tooltip with a timer. 4 | 5 | Parameters: 6 | --------------- 7 | str (optional): text to display in tooltip 8 | 9 | wait (optional): tooltip timeout in milliseconds 10 | 11 | x (optional): x coord for the tooltip 12 | 13 | y (optional): y coord for the tooltip 14 | 15 | return: given str (for inline debugging) 16 | --------------- 17 | 18 | Example: 19 | ------------ 20 | tool("Hello World",3000) 21 | sleep 5000 22 | ------------ 23 | 24 | */ 25 | 26 | tool(str:="",wait:=2500,x:="",y:=""){ 27 | static tf:=func("tool") 28 | 29 | if (!str) { 30 | tooltip 31 | } else { 32 | tooltip,% str,% x,% y 33 | setTimer,% tf,% "-" wait 34 | } 35 | return str 36 | } -------------------------------------------------------------------------------- /Lib/toolSpeak.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Speaks given string/TTS. 4 | 5 | Parameters: 6 | --------------- 7 | str: string to speak 8 | 9 | wait (optional): wait for speech to finish (1) or return immediately (0) 10 | 11 | return: given string (for inline debugging) 12 | --------------- 13 | 14 | Example: 15 | ------------ 16 | toolSpeak("Hello World",1) 17 | ------------ 18 | 19 | */ 20 | 21 | toolSpeak(str,wait:=0){ 22 | static tts:=comObjCreate("SAPI.SpVoice") 23 | tts.speak(str,wait?2:3) 24 | return str 25 | } -------------------------------------------------------------------------------- /Lib/urlDownloadToFile.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Downloads a file from a URL to a local file. 4 | 5 | Parameters: 6 | --------------- 7 | url: url to download from 8 | 9 | fileDest (optonal): local path to save to (defaults to script 10 | folder with name of file from the url) 11 | 12 | userAgent (optional): a valid useragent string to be used during 13 | the http request 14 | 15 | return: caught error message 16 | --------------- 17 | 18 | Example: 19 | ------------ 20 | urlDownloadToFile("https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png") 21 | ------------ 22 | 23 | */ 24 | 25 | urlDownloadToFile(url,fileDest:="",userAgent:=""){ 26 | if (!fileDest) { 27 | splitPath,url,fileDest 28 | fileDest:=a_scriptDir "\" fileDest 29 | } 30 | if (!regExMatch(url,"i)https?://")) 31 | url:="https://" url 32 | try { 33 | hObject:=comObjCreate("WinHttp.WinHttpRequest.5.1") 34 | hObject.open("GET",url) 35 | if (userAgent) 36 | hObject.setRequestHeader("User-Agent",userAgent) 37 | hObject.send() 38 | 39 | uBytes:=hObject.responseBody,cLen:=uBytes.maxIndex() 40 | fileHandle:=fileOpen(fileDest,"w") 41 | varSetCapacity(f,cLen,0) 42 | loop % cLen+1 43 | numPut(uBytes[a_index-1],f,a_index-1,"UChar") 44 | err:=fileHandle.rawWrite(f,cLen+1) 45 | } catch e 46 | return % e.message 47 | } -------------------------------------------------------------------------------- /Lib/urlDownloadToVar.ahk: -------------------------------------------------------------------------------- 1 | /* Written by maestrith, modified by Masonjar13 2 | 3 | Downloads a file from a URL and returns it. 4 | 5 | Parameters: 6 | --------------- 7 | url: url to download from 8 | 9 | raw (optional): return content as text (0, default) or raw binary (1) 10 | 11 | userAgent (optional): a valid useragent string to be used during 12 | the http request 13 | 14 | headers (optional): pass an array of headers 15 | 16 | return: file data or caught error message 17 | --------------- 18 | 19 | Example: 20 | ------------ 21 | ; msgbox external IP information in json 22 | msgbox % urlDownloadToVar("https://dazzlepod.com/ip/me.json") 23 | 24 | ; pass an API key to TheCatApi and msgbox the returned json 25 | msgbox % urlDownloadToVar("https://api.thecatapi.com/v1/images/search",,,{"x-api-key":myApiKey}) 26 | ------------ 27 | 28 | */ 29 | 30 | urlDownloadToVar(url,raw:=0,userAgent:="",headers:=""){ 31 | if (!regExMatch(url,"i)https?://")) 32 | url:="https://" url 33 | try { 34 | hObject:=comObjCreate("WinHttp.WinHttpRequest.5.1") 35 | hObject.open("GET",url) 36 | if (userAgent) 37 | hObject.setRequestHeader("User-Agent",userAgent) 38 | if (isObject(headers)) { 39 | for i,a in headers { 40 | hObject.setRequestHeader(i,a) 41 | } 42 | } 43 | hObject.send() 44 | return raw?hObject.responseBody:hObject.responseText 45 | } catch e 46 | return % e.message 47 | } 48 | -------------------------------------------------------------------------------- /Lib/urlFileGetSize.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Retrieve file size from a URL. 4 | 5 | Note: This may request permission from your firewall. 6 | 7 | Parameters: 8 | --------------- 9 | url: url file to check the size of 10 | 11 | units (optional): unit size to use (0 = bytes,1 = KiB, 12 | 2 = MiB, etc) 13 | 14 | return: size of url file 15 | --------------- 16 | 17 | Example: 18 | ------------ 19 | size1:=urlFileGetSize("ftp://speedtest:speedtest@ftp.otenet.gr/test5Gb-a.db",3) 20 | size2:=urlFileGetSize("ftp://speedtest:speedtest@ftp.otenet.gr/test10Gb.db",3) 21 | size3:=urlFileGetSize("ftp://speedtest:speedtest@ftp.otenet.gr/test100Mb.db",2) 22 | 23 | msgbox % size1 " GB`n" size2 " GB`n" size3 " MB`n`n" size 24 | ------------ 25 | 26 | */ 27 | 28 | urlFileGetSize(url,units:=0){ 29 | hMod:=dllCall("LoadLibrary",WStr,"wininet.dll") 30 | hIO:=dllCall("wininet\InternetOpenW" 31 | ,WStr,"Microsoft Internet Explorer" 32 | ,UInt,4 ; INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY 33 | ,Int,0,Int,0,UInt,0) 34 | 35 | hIU:=dllCall("wininet\InternetOpenUrlW" 36 | ,UInt,hIO,WStr,url,Int,0,Int,0 37 | ,UInt,0x84000000 ; INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD 38 | ,UInt,0) 39 | 40 | if (hIO&hIU) { 41 | if (subStr(url,1,4)="ftp:") { 42 | varSetCapacity(huint,4) 43 | fileSize:=dllCall("wininet\FtpGetFileSize",UInt,hIU,UIntP,huint,UInt) | huint << 32 44 | } else { 45 | dllCall("wininet\HttpQueryInfoW" 46 | ,UInt,hIU 47 | ,UInt,0x20000005 ; HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER 48 | ,UIntP,fileSize,UIntP,4,Int,0) 49 | } 50 | } 51 | 52 | dllCall("wininet\InternetCloseHandle",UInt,hIU) 53 | dllCall("wininet\InternetCloseHandle",UInt,hIO) 54 | dllCall("FreeLibrary",UInt,hMod) 55 | if (units) 56 | fileSize:=round(fileSize/(1024**units),2) 57 | return fileSize 58 | } -------------------------------------------------------------------------------- /Lib/winInfo.ahk: -------------------------------------------------------------------------------- 1 | /* Written by Masonjar13 2 | 3 | Retrieves window information of a given window. 4 | 5 | Parameters: 6 | --------------- 7 | winName (optional): winTitle of a window 8 | 9 | return: string of window data 10 | --------------- 11 | 12 | Example: 13 | ------------ 14 | msgbox % winInfo() 15 | ------------ 16 | 17 | */ 18 | 19 | winInfo(winName:="a"){ 20 | winGet,awp,processName,% winName 21 | winGet,awpid,PID,% winName 22 | winGetTitle,awn,ahk_pid %awpid% 23 | winGetPos,awx,awy,aww,awh,ahk_pid %awpid% 24 | winGetClass,awc,% winName 25 | winGet,awhwnd,ID,% winName 26 | winGet,awcl,controlList,% winName 27 | return "Window Name: " awn "`nW/H: " aww "x" awh "`nX/Y: " awx "," awy "`nClass: " awc "`nProcess: " awp "`nPID: " awpid "`nHWND: " awhwnd "`nControl List:`n" awcl 28 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AHK-Library 2 | [Most of my personal AHK stdlib.](https://autohotkey.com/boards/viewtopic.php?p=88651#p88651) 3 | 4 | 5 | ## Functions 6 | | Function | Description | 7 | |--------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 8 | | [binSearch()](Lib/binSearch.ahk) | Performs a binary search on a given index-based object. | 9 | | [borderlessMode()](Lib/borderlessMode.ahk) | Toggles AlwaysOnTop and caption for a specified window (active window, if unspecified). | 10 | | [borderlessMove()](Lib/borderlessMove.ahk) | Enables click-and-drag movement for windows without captions. | 11 | | [checkSession()](Lib/checkSession.ahk) | Creates a callback for user session messages, such as logging off or locking the session. | 12 | | [commaFormat()](Lib/commaFormat.ahk) | Performs a comma format on numbers, eg., `123456789.12345 > 123,456,789.12345`. | 13 | | [compileScript()](Lib/compileScript.ahk) | **Requires:** AHK to be installed on the system.

Allows compilation of a script from a script, which could be self-compilation. | 14 | | [downloadGithubRelease()](Lib/downloadGithubRelease.ahk) | **Requires:** [urlDownloadToVar()](Lib/urlDownloadToVar.ahk)

Downloads latest Git repo release from any repo. | 15 | | [dpiOffset()](Lib/dpiOffset.ahk) | Adds DPI offset to the given value, based on the current system DPI setting. | 16 | | [externalIP\[_old\]()](Lib/externalIP.ahk) | Retrieves the visible information of a given IP. If no IP is given, the information for the external IP of the local machine is retrieved. | 17 | | [fileUnblock()](Lib/fileUnblock.ahk) | Removes the "file came from another computer" security flag on a specified file. | 18 | | [getCurrentTime()](Lib/getCurrentTime.ahk) | **Requires:** [urlDownloadToVar()](Lib/urlDownloadToVar.ahk), [strToLower()](Lib/strToLower.ahk)

Retrieves the current time of the specified [region of a] country. Utilizing the boolean `countryIsTimezone` parameter, the `country` parameter may be a timezone acronym instead. | 19 | | [getImageSize()](Lib/getImageSize.ahk) | Returns the image resolution (width and height) of a given image file. | 20 | | [getPosFromAngle()](Lib/getPosFromAngle.ahk) | Calculates and returns a coordinate based off of a given coordinate, length/distance in pixels, and angle. | 21 | | [getSelected()](Lib/getSelected.ahk) | Returns the path[s] of selected file[s] when using a file explorer. | 22 | | [getUTCOffset()](Lib/getUTCOffset.ahk) | **Requires:** [urlDownloadToVar()](Lib/urlDownloadToVar.ahk), [strToLower()](Lib/strToLower.ahk)

Retrieves the UTC offset of a timezone. | 23 | | [getWinClientSize()](Lib/getWinClientSize.ahk) | Returns the size (width and height) of the client area of a specified window handle. | 24 | | [hToMs()](Lib/hToMs.ahk) | Converts hours into milliseconds. | 25 | | [hwndHung()](Lib/hwndHung.ahk) | Checks if a window handle is hung/frozen. | 26 | | [ifContains()](Lib/ifContains.ahk) | Function wrap for [if var contains matchList](https://autohotkey.com/docs/commands/IfIn.htm). | 27 | | [ifIn()](Lib/ifIn.ahk) | Function wrap for [if var in matchList](https://autohotkey.com/docs/commands/IfIn.htm). | 28 | | [imageSearchc()](Lib/imageSearchc.ahk) | **Requires:** [Gdip_All](Required-Libraries/Gdip_All.ahk)

GDI based image search, to replace [ImageSearch](https://autohotkey.com/docs/commands/ImageSearch.htm). | 29 | | [internetConnected()](Lib/internetConnected.ahk) | Pings given URL (Google if unspecified) to check connection. | 30 | | [invertCaseChr()](Lib/invertCaseChr.ahk) | Inverts the case of a given character. | 31 | | [invertCaseStr()](Lib/invertCaseStr.ahk) | Inverts the case of a given string. | 32 | | [is64bitExe()](Lib/is64bitExe.ahk) | Checks if a specified executable is 64-bit. | 33 | | [isAlpha()](Lib/isAlpha.ahk) | Wrap for [if var is alpha](https://autohotkey.com/docs/commands/IfIs.htm). | 34 | | [isAlphaNum()](Lib/isAlphaNum.ahk) | Wrap for [if var is alphaNum](https://autohotkey.com/docs/commands/IfIs.htm). | 35 | | [isBetween()](Lib/isBetween.ahk) | Wrap for [if var is between lowerBound and upperBound](https://autohotkey.com/docs/commands/IfBetween.htm). | 36 | | [isDigit()](Lib/isDigit.ahk) | Wrap for [if var is digit](https://autohotkey.com/docs/commands/IfIs.htm). | 37 | | [isFloat()](Lib/isFloat.ahk) | Wrap for [if var is float](https://autohotkey.com/docs/commands/IfIs.htm). | 38 | | [isHex()](Lib/isHex.ahk) | Wrap for [if var is hex](https://autohotkey.com/docs/commands/IfIs.htm). | 39 | | [isInt()](Lib/isInt.ahk) | Wrap for [if var is int](https://autohotkey.com/docs/commands/IfIs.htm). | 40 | | [isLower()](Lib/isLower.ahk) | Wrap for [if var is lower](https://autohotkey.com/docs/commands/IfIs.htm). | 41 | | [isNum()](Lib/isNum.ahk) | Wrap for [if var is num](https://autohotkey.com/docs/commands/IfIs.htm). | 42 | | [isSpace()](Lib/isSpace.ahk) | Wrap for [if var is space](https://autohotkey.com/docs/commands/IfIs.htm). | 43 | | [isUpper()](Lib/isUpper.ahk) | Wrap for [if var is upper](https://autohotkey.com/docs/commands/IfIs.htm). | 44 | | [lanConnected()](Lib/lanConnected.ahk) | Checks if the local device is connected to a local area network. | 45 | | [msToH()](Lib/msToH.ahk) | Converts milliseconds into hours. | 46 | | [msToM()](Lib/msToM.ahk) | Converts milliseconds into minutes. | 47 | | [msToS()](Lib/msToS.ahk) | Converts milliseconds into seconds. | 48 | | [mToMs()](Lib/mToMs.ahk) | Converts minutes into milliseconds. | 49 | | [multiKeyStates()](Lib/multiKeyStates.ahk) | Allows to check for multiple key states at a time, keeping the return boolean to match getKeyState(). | 50 | | [mouseOverWin()](Lib/mouseOverWin.ahk) | Checks if the mouse is over a specified window. | 51 | | [muteWindow()](Lib/muteWindow.ahk) | **Requires:** [VA](Required-Libraries/VA.ahk)

Mutes, unmutes, or toggles mute state for a specified window in the volume mixer. | 52 | | [nicRestart()](Lib/nicRestart.ahk) | **Requires:** [nicSetState()](Lib/nicSetState.ahk)

Disables and re-enables a specified network adapter. | 53 | | [nicSetState()](Lib/nicSetState.ahk) | Enables or disables a specified network adapter. | 54 | | [processExist()](Lib/processExist.ahk) | Wrap for [process, exist](https://autohotkey.com/docs/commands/Process.htm). | 55 | | [processPriority()](Lib/processPriority.ahk) | Returns the priority level of a given process/PID. | 56 | | [rand()](Lib/rand.ahk) | Wrap for [random](https://autohotkey.com/docs/commands/Random.htm). | 57 | | [randStr()](Lib/randStr.ahk) | Generates a random string of a given length, with options to include any combination of lowercase, uppercase, digits, and symbols. | 58 | | [readHotkeys()](Lib/readHotkeys.ahk) | Creates a list of all hotkeys/hotstrings and directives from a script file (from disk, not active). | 59 | | [regExMatchI()](Lib/regExMatchI.ahk) | **Requires:** [strI()](Lib/strI.ahk)

Performs an inverted (end to start) [regExMatch](https://autohotkey.com/docs/commands/RegExMatch.htm). | 60 | | [regExReplaceI()](Lib/regExReplaceI.ahk) | **Requires:** [strI()](Lib/strI.ahk)

Performs an inverted (end to start) [regExReplace](https://autohotkey.com/docs/commands/RegExReplace.htm). | 61 | | [setWindowVol()](Lib/setWindowVol.ahk) | **Requires:** [VA](Required-Libraries/VA.ahk)

Sets the volume for a specified window in the volume mixer. | 62 | | [StdOutStream()](Lib/StdOutStream.ahk) | Creates a callback for all standard output lines of a program. | 63 | | [StdOutToVar()](Lib/StdOutToVar.ahk) | Returns all standard output of a program. | 64 | | [strI()](Lib/strI.ahk) | Inverts a given string. | 65 | | [strReplaceI()](Lib/strReplaceI.ahk) | **Requires:** [strI()](Lib/strI.ahk)

Performs an inverted (end to start) [strReplace](https://autohotkey.com/docs/commands/StringReplace.htmunction). | 66 | | [strToLower()](Lib/strToLower.ahk) | Wrap for [stringLower](https://autohotkey.com/docs/commands/StringLower.htm). | 67 | | [strToUpper()](Lib/strToUpper.ahk) | Wrap for [stringUpper](https://autohotkey.com/docs/commands/StringLower.htm). | 68 | | [stringify()](Lib/stringify.ahk) | Returns a specified object in the form of a string. | 69 | | [tool()](Lib/tool.ahk) | Creates a tooltip for a specified amount of time. | 70 | | [toolSpeak()](Lib/toolSpeak.ahk) | Speaks a given string. | 71 | | [urlDownloadToFile()](Lib/urlDownloadToFile.ahk) | Downloads a URL resource to a file. | 72 | | [urlDownloadToVar()](Lib/urlDownloadToVar.ahk) | Downloads a URL resource to a variable. | 73 | | [urlFileGetSize()](Lib/urlFileGetSize.ahk) | Retrieves the file size of a URL resource. | 74 | | [winInfo()](Lib/winInfo.ahk) | Returns information about the specified window. | 75 | 76 | ## Classes 77 | | Class | Description | 78 | |------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 79 | | [audioRouter](Lib/audioRouter.ahk) | **Requires:** [VA](Required-Libraries/VA.ahk), [Audio Router](https://github.com/audiorouterdev/audio-router/releases)

Allows using/interacting with Audio Router from AHK. | 80 | | [IEObj](Lib/IEObj.ahk) | Contains an instance of IE via COM, with methods that wrap basic interactions, such as URL navigation. Features extensive error catching. | 81 | | [threadMan](Lib/threadMan.ahk) | **Requires:** [_MemoryLibrary](Required-Libraries/_MemoryLibrary.ahk), [_Struct](Required-Libraries/_Struct.ahk), [AutoHotkey.dll](https://hotkeyit.github.io/v2) (v1 zip download)

Wraps functionality of AutoHotkey.dll to allow multi-threading with AHK v1.1. | 82 | | [db](Lib/db.ahk) | Base DB class, with methods for reading, writing, and removing key-value pairs to/from a file. | 83 | 84 | ## Other 85 | | Name | Description | 86 | | ------------------------------------- | --------------------------------------------------------- | 87 | | [functionalAHK](Lib/functionalAHK.ahk) | Wraps all AHK commands, so functions may be used instead. | 88 | -------------------------------------------------------------------------------- /Required-Libraries/_MemoryLibrary.ahk: -------------------------------------------------------------------------------- 1 | /* 2 | SetBatchLines,-1 3 | start:=A_TickCount 4 | Loop 10 5 | MemLib:=new _MemoryLibrary("X:\AutoHotkey.dll") 6 | ,MemLib.Free() ;,MemLib:="" 7 | MsgBox % A_TickCount-start 8 | ExitApp 9 | If (!FileExist("X:\AutoHotkey.dll")){ 10 | MsgBox AutoHotkey.dll was not found 11 | ExitApp 12 | } 13 | IF !(MemLib:=new _MemoryLibrary("X:\AutoHotkey.dll")) 14 | MsgBox, AutoHotkey.dll could not be loaded 15 | ;Second method by passing the data pointer 16 | FileRead,data,*c X:\AutoHotkey.dll 17 | NewMemLib:=new _MemoryLibrary(&data) 18 | 19 | DllCall(MemLib.GetProcAddress("ahktextdll"),"Str","MsgBox Hello from Thread","Str","","Str","") ; start first AutoHotkey.dll thread 20 | DllCall(NewMemLib.GetProcAddress("ahktextdll"),"Str","MsgBox Hello from other Thread in %A_ScriptDir%","Str","","Str","") ; start another AutoHotkey.dll thread 21 | Sleep 1000 22 | MsgBox,0, AutoHotkey.dll started, press OK to terminate. 23 | DllCall(MemLib.GetProcAddress("ahkterminate")), MemLib.Free() 24 | DllCall(NewMemLib.GetProcAddress("ahkterminate")), NewMemLib.Free() 25 | MsgBox AutoHotkey.dll threads terminated and memory freed 26 | */ 27 | #Include <_Struct> 28 | Class _MemoryLibrary { 29 | static MEMORYMODULE :=(A_PtrSize=8?" 30 | (LTrim 31 | _MemoryLibrary.IMAGE_NT_HEADERS64 *hdrs; 32 | )":" 33 | (LTrim 34 | _MemoryLibrary.IMAGE_NT_HEADERS32 *hdrs; 35 | )") " 36 | (LTrim 37 | 38 | uchar *cdbs; 39 | HMODULE *mdls; 40 | int nummdls; 41 | int init; 42 | )" 43 | static IMAGE_RESOURCE_DIRECTORY_ENTRY := " 44 | (LTrim 45 | union { 46 | DWORD Name; 47 | WORD Id; 48 | }; 49 | union { 50 | DWORD OffsetToData; 51 | }; 52 | )" 53 | 54 | static IMAGE_RESOURCE_DATA_ENTRY := " 55 | (LTrim 56 | DWORD OffsetToData; 57 | DWORD Size; 58 | DWORD CodePage; 59 | DWORD Reserved; 60 | )" 61 | 62 | static IMAGE_RESOURCE_DIRECTORY:=" 63 | (LTrim 64 | DWORD Characteristics; 65 | DWORD TimeDateStamp; 66 | WORD MajorVersion; 67 | WORD MinorVersion; 68 | WORD NumberOfNamedEntries; 69 | WORD NumberOfIdEntries; 70 | )" 71 | static IMAGE_BASE_RELOCATION :=" 72 | (LTrim 73 | DWORD VirtualAddress; 74 | DWORD SizeOfBlock; 75 | )" 76 | 77 | static _ACTCTX := " 78 | (LTrim 79 | ULONG cbSize; 80 | DWORD dwFlags; 81 | LPCWSTR lpSource; 82 | USHORT wProcessorArchitecture; 83 | LANGID wLangId; 84 | LPCTSTR lpAssemblyDirectory; 85 | LPCTSTR lpResourceName; 86 | LPCTSTR lpApplicationName; 87 | HMODULE hModule; 88 | )" 89 | 90 | static IMAGE_IMPORT_DESCRIPTOR :=" 91 | (LTrim 92 | union { 93 | DWORD Characteristics; // 0 for terminating null import descriptor 94 | DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA) 95 | }; 96 | DWORD TimeDateStamp; // 0 if not bound, 97 | // -1 if bound, and real date\time stamp 98 | // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND) 99 | // O.W. date/time stamp of DLL bound to (Old BIND) 100 | 101 | DWORD ForwarderChain; // -1 if no forwarders 102 | DWORD Name; 103 | DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses) 104 | )" 105 | 106 | static IMAGE_DOS_HEADER :=" ; DOS .EXE header 107 | (LTrim 108 | WORD e_magic; // Magic number 109 | WORD e_cblp; // Bytes on last page of file 110 | WORD e_cp; // Pages in file 111 | WORD e_crlc; // Relocations 112 | WORD e_cparhdr; // Size of header in paragraphs 113 | WORD e_minalloc; // Minimum extra paragraphs needed 114 | WORD e_maxalloc; // Maximum extra paragraphs needed 115 | WORD e_ss; // Initial (relative) SS value 116 | WORD e_sp; // Initial SP value 117 | WORD e_csum; // Checksum 118 | WORD e_ip; // Initial IP value 119 | WORD e_cs; // Initial (relative) CS value 120 | WORD e_lfarlc; // File address of relocation table 121 | WORD e_ovno; // Overlay number 122 | WORD e_res[4]; // Reserved words 123 | WORD e_oemid; // OEM identifier (for e_oeminfo) 124 | WORD e_oeminfo; // OEM information; e_oemid specific 125 | WORD e_res2[10]; // Reserved words 126 | LONG e_lfanew; // File address of new exe header 127 | )" 128 | 129 | static IMAGE_FILE_HEADER :=" 130 | (LTrim 131 | WORD Machine; 132 | WORD NumberOfSections; 133 | DWORD TimeDateStamp; 134 | DWORD PointerToSymbolTable; 135 | DWORD NumberOfSymbols; 136 | WORD SizeOfOptionalHeader; 137 | WORD Characteristics; 138 | )" 139 | 140 | static IMAGE_NUMBEROF_DIRECTORY_ENTRIES:=16 141 | 142 | static IMAGE_DATA_DIRECTORY :=" 143 | (LTrim 144 | DWORD VirtualAddress; 145 | DWORD Size; 146 | )" 147 | 148 | static IMAGE_OPTIONAL_HEADER64 := " 149 | (LTrim 150 | WORD Magic; 151 | BYTE MajorLinkerVersion; 152 | BYTE MinorLinkerVersion; 153 | DWORD SizeOfCode; 154 | DWORD SizeOfInitializedData; 155 | DWORD SizeOfUninitializedData; 156 | DWORD AddressOfEntryPoint; 157 | DWORD BaseOfCode; 158 | ULONGLONG ImageBase; 159 | DWORD SectionAlignment; 160 | DWORD FileAlignment; 161 | WORD MajorOperatingSystemVersion; 162 | WORD MinorOperatingSystemVersion; 163 | WORD MajorImageVersion; 164 | WORD MinorImageVersion; 165 | WORD MajorSubsystemVersion; 166 | WORD MinorSubsystemVersion; 167 | DWORD Win32VersionValue; 168 | DWORD SizeOfImage; 169 | DWORD SizeOfHeaders; 170 | DWORD CheckSum; 171 | WORD Subsystem; 172 | WORD DllCharacteristics; 173 | ULONGLONG SizeOfStackReserve; 174 | ULONGLONG SizeOfStackCommit; 175 | ULONGLONG SizeOfHeapReserve; 176 | ULONGLONG SizeOfHeapCommit; 177 | DWORD LoaderFlags; 178 | DWORD NumberOfRvaAndSizes; 179 | _MemoryLibrary.IMAGE_DATA_DIRECTORY DataDirectory[" _MemoryLibrary.IMAGE_NUMBEROF_DIRECTORY_ENTRIES "]; 180 | )" 181 | 182 | static IMAGE_OPTIONAL_HEADER32 := " 183 | (LTrim 184 | // 185 | // Standard fields. 186 | // 187 | 188 | WORD Magic; 189 | BYTE MajorLinkerVersion; 190 | BYTE MinorLinkerVersion; 191 | DWORD SizeOfCode; 192 | DWORD SizeOfInitializedData; 193 | DWORD SizeOfUninitializedData; 194 | DWORD AddressOfEntryPoint; 195 | DWORD BaseOfCode; 196 | DWORD BaseOfData; 197 | 198 | // 199 | // NT additional fields. 200 | // 201 | 202 | DWORD ImageBase; 203 | DWORD SectionAlignment; 204 | DWORD FileAlignment; 205 | WORD MajorOperatingSystemVersion; 206 | WORD MinorOperatingSystemVersion; 207 | WORD MajorImageVersion; 208 | WORD MinorImageVersion; 209 | WORD MajorSubsystemVersion; 210 | WORD MinorSubsystemVersion; 211 | DWORD Win32VersionValue; 212 | DWORD SizeOfImage; 213 | DWORD SizeOfHeaders; 214 | DWORD CheckSum; 215 | WORD Subsystem; 216 | WORD DllCharacteristics; 217 | DWORD SizeOfStackReserve; 218 | DWORD SizeOfStackCommit; 219 | DWORD SizeOfHeapReserve; 220 | DWORD SizeOfHeapCommit; 221 | DWORD LoaderFlags; 222 | DWORD NumberOfRvaAndSizes; 223 | _MemoryLibrary.IMAGE_DATA_DIRECTORY DataDirectory[" _MemoryLibrary.IMAGE_NUMBEROF_DIRECTORY_ENTRIES "]; 224 | )" 225 | static IMAGE_NT_HEADERS64 := " 226 | (LTrim 227 | DWORD Signature; 228 | _MemoryLibrary.IMAGE_FILE_HEADER FileHeader; 229 | _MemoryLibrary.IMAGE_OPTIONAL_HEADER64 OptionalHeader; 230 | )" 231 | 232 | static IMAGE_NT_HEADERS32 := " 233 | (LTrim 234 | DWORD Signature; 235 | _MemoryLibrary.IMAGE_FILE_HEADER FileHeader; 236 | _MemoryLibrary.IMAGE_OPTIONAL_HEADER32 OptionalHeader; 237 | )" 238 | 239 | static IMAGE_SECTION_HEADER :=" 240 | (LTrim 241 | BYTE Name[8]; 242 | union { 243 | DWORD PhysicalAddress; 244 | DWORD VirtualSize; 245 | }; 246 | DWORD VirtualAddress; 247 | DWORD SizeOfRawData; 248 | DWORD PointerToRawData; 249 | DWORD PointerToRelocations; 250 | DWORD PointerToLinenumbers; 251 | WORD NumberOfRelocations; 252 | WORD NumberOfLinenumbers; 253 | DWORD Characteristics; 254 | )" 255 | static IMAGE_EXPORT_DIRECTORY :=" 256 | (LTrim 257 | DWORD Characteristics; 258 | DWORD TimeDateStamp; 259 | WORD MajorVersion; 260 | WORD MinorVersion; 261 | DWORD Name; 262 | DWORD Base; 263 | DWORD NumberOfFunctions; 264 | DWORD NumberOfNames; 265 | DWORD AddressOfFunctions; // RVA from base of image 266 | DWORD AddressOfNames; // RVA from base of image 267 | DWORD AddressOfNameOrdinals; // RVA from base of image 268 | )" 269 | static IMAGE_IMPORT_BY_NAME :=" 270 | (LTrim 271 | WORD Hint; 272 | BYTE Name[1]; 273 | )" 274 | 275 | __New(DataPTR){ 276 | static Is64:=A_PtrSize=8?"64":"32",MEM_RESERVE:=0x2000,PAGE_EXECUTE_READWRITE:=0x40,MEM_COMMIT:=4096 277 | If DataPTR is not digit 278 | { 279 | FileRead,Data,*c %DataPTR% 280 | DataPTR:=&Data 281 | } 282 | dh:=new _Struct(this.IMAGE_DOS_HEADER,DataPTR) 283 | if (dh.e_magic != IMAGE_DOS_SIGNATURE:=23117){ 284 | MsgBox ERROR: e_magic not found 285 | return 286 | } 287 | oh := new _Struct(this["IMAGE_NT_HEADERS" Is64],DataPTR + dh.e_lfanew) 288 | if (oh.Signature != IMAGE_NT_SIGNATURE:=17744){ 289 | MsgBox ERROR: Signature not found 290 | return 291 | } 292 | ; reserve memory for image of library 293 | code := DllCall("VirtualAlloc","PTR",oh.OptionalHeader.ImageBase,"PTR",oh.OptionalHeader.SizeOfImage 294 | ,"UINT",MEM_RESERVE,"UINT",PAGE_EXECUTE_READWRITE,"PTR") 295 | 296 | if (code = 0) { ; try to allocate memory at arbitrary position 297 | code := DllCall("VirtualAlloc","PTR",0,"PTR",oh.OptionalHeader.SizeOfImage 298 | ,"UINT",MEM_RESERVE,"UINT",PAGE_EXECUTE_READWRITE,"PTR") 299 | if (code = 0){ 300 | MsgBox ERROR: loading Library 301 | return 302 | } 303 | } 304 | this.MM := new _Struct(this.MEMORYMODULE,DllCall("HeapAlloc","PTR",DllCall("GetProcessHeap","PTR"),"UINT", 0,"PTR", sizeof(this.MEMORYMODULE),"PTR")) 305 | ,this.MM.cdbs[""]:=code,this.MM.nummdls := 0,this.MM.Alloc("mdls",4),this.MM.init := 0 306 | ,DllCall("VirtualAlloc","PTR",code,"PTR",oh.OptionalHeader.SizeOfImage,"UINT",MEM_COMMIT,"UINT",PAGE_EXECUTE_READWRITE,"PTR") 307 | ; commit memory for headers 308 | ,hdrs := DllCall("VirtualAlloc","PTR",code,"PTR",dh.e_lfanew + oh.OptionalHeader.SizeOfHeaders,"UINT",MEM_COMMIT,"UINT",PAGE_EXECUTE_READWRITE,"PTR") 309 | ; copy PE header to code 310 | ,DllCall("RtlMoveMemory","PTR",hdrs, "PTR",dh[""],"PTR", dh.e_lfanew + oh.OptionalHeader.SizeOfHeaders) 311 | ,this.MM.hdrs[""] := hdrs + dh.e_lfanew 312 | ; update position 313 | ,this.MM.hdrs.OptionalHeader.ImageBase := code 314 | ; copy sections from DLL file block to new memory location 315 | ,this.CopySections(DataPTR, oh) 316 | ; adjust base address of imported data 317 | ,locationDelta := code - oh.OptionalHeader.ImageBase 318 | if (locationDelta != 0) 319 | this.PerformBaseRelocation(locationDelta) 320 | ; load required dlls and adjust function table of imports 321 | if (!this.BuildImportTable()) { 322 | MsgBox ERROR: BuildImportTable failed 323 | Return 324 | } 325 | ; mark memory pages depending on section headers and release 326 | ; sections that are marked as "discardable" 327 | this.FinalizeSections() 328 | ; get entry point of loaded library 329 | if (this.MM.hdrs.OptionalHeader.AddressOfEntryPoint != 0){ 330 | DllEntry := code + this.MM.hdrs.OptionalHeader.AddressOfEntryPoint 331 | if (DllEntry = 0) { 332 | MsgBox ERROR: DllEntry not found 333 | Return 334 | } 335 | ; notify library about attaching to process 336 | successfull := DllCall(DllEntry,"PTR",code, "UInt",DLL_PROCESS_ATTACH:=1,"UInt", 0,"CHAR") 337 | if (!successfull){ 338 | MsgBox ERROR attaching process 339 | Return 340 | } 341 | this.MM.init := 1 342 | } 343 | } 344 | 345 | 346 | GetProcAddress(name){ 347 | cdbs := this.MM.cdbs[""],idx:=-1,i:=0,directory := this.MM.hdrs.OptionalHeader.DataDirectory[ 1 + IMAGE_DIRECTORY_ENTRY_EXPORT:=0] 348 | if (directory.Size = 0) ; no export table found 349 | return 0 350 | exports :=new _Struct(this.IMAGE_EXPORT_DIRECTORY,cdbs + directory.VirtualAddress) 351 | if (exports.NumberOfNames = 0 || exports.NumberOfFunctions = 0) ; DLL doesn't export anything 352 | return 0 353 | ; search function name in list of exported names 354 | nameRef := cdbs + exports.AddressOfNames,ordinal := cdbs + exports.AddressOfNameOrdinals 355 | While (i exports.NumberOfFunctions) ; name <-> ordinal number don't match 365 | return 0 366 | ; AddressOfFunctions contains the RVAs to the "real" functions 367 | return cdbs + NumGet(cdbs + exports.AddressOfFunctions + (idx*4),"UInt") 368 | } 369 | Free(){ 370 | i:=0 371 | if (this.MM.init != 0) { ; notify library about detaching from process 372 | DllEntry := this.MM.cdbs[""] + this.MM.hdrs.OptionalHeader.AddressOfEntryPoint 373 | ,DllCall(DllEntry,"Ptr",this.MM.cdbs[""],"UInt", DLL_PROCESS_DETACH:=0, "UInt",0) 374 | ,this.MM.init := 0 375 | } 376 | if (this.MM.nummdls != 0) { ; free previously opened libraries 377 | Loop % this.MM.nummdls 378 | if (this.MM.mdls[A_Index] != INVALID_HANDLE_VALUE:=-1) 379 | DllCall("FreeLibrary","PTR",this.MM.mdls[A_Index]) 380 | this.MM._SetCapacity("mdls",0) 381 | } 382 | if (this.MM.cdbs[""] != 0) ;release memory of library 383 | DllCall("VirtualFree","PTR",this.MM.cdbs[""],"PTR", 0,"UINT", MEM_RELEASE:=32768) 384 | DllCall("HeapFree","PTR",DllCall("GetProcessHeap","PTR"),"UINT", 0,"PTR", this.MM[""]) 385 | } 386 | 387 | ; Private functions 388 | CopySections(data, oh){ 389 | static PAGE_EXECUTE_READWRITE:=64,MEM_COMMIT:=4096 390 | cdbs := this.MM.cdbs[""] 391 | section:=new _Struct(this.IMAGE_SECTION_HEADER,this.MM.hdrs.OptionalHeader[""]+this.MM.hdrs.FileHeader.SizeOfOptionalHeader) 392 | While ((A_Index-1) 0) ; section is empty 396 | dest := DllCall("VirtualAlloc","PTR",cdbs + section.VirtualAddress,"PTR",size,"UINT",MEM_COMMIT,"UINT",PAGE_EXECUTE_READWRITE,"PTR") 397 | ,section.PhysicalAddress := dest,DllCall("RtlFillMemory","PTR",dest,"UINT", size,"CHAR", 0) 398 | section[]:=section[""]+sizeof(section) 399 | continue 400 | } 401 | ; commit memory block and copy data from dll 402 | dest := DllCall("VirtualAlloc","PTR",cdbs + section.VirtualAddress,"PTR",section.SizeOfRawData,"UINT",MEM_COMMIT,"UINT",PAGE_EXECUTE_READWRITE,"PTR") 403 | ,DllCall("RtlMoveMemory","PTR",dest,"PTR",data + section.PointerToRawData,"PTR", section.SizeOfRawData) 404 | ,section.PhysicalAddress := dest,section[]:=section[""]+sizeof(section) 405 | } 406 | } 407 | 408 | FinalizeSections(){ 409 | static ProtectionFlags := [[[PAGE_NOACCESS:=1, PAGE_WRITECOPY:=8],[PAGE_READONLY:=2, PAGE_EXECUTE_READWRITE:=64]], [[PAGE_EXECUTE:=16, PAGE_EXECUTE_READWRITE:=64],[PAGE_EXECUTE_READ:=32, PAGE_EXECUTE_READWRITE:=64]]] 410 | i:=0 411 | section := new _Struct(this.IMAGE_SECTION_HEADER,this.MM.hdrs.OptionalHeader[""] + this.MM.hdrs.FileHeader.SizeOfOptionalHeader) 412 | ,imageOffset := A_PtrSize=8?(NumGet(this.MM.hdrs.OptionalHeader.ImageBase[""]+4,"UInt") & 0xffffffff)<<32:0 413 | ; loop through all sections and change access flags 414 | While (i 0) ; change memory access flags 437 | if (DllCall("VirtualProtect","PTR",section.PhysicalAddress | imageOffset,"PTR", size,"UINT", protect,"PTR", &oldProtect) = 0) 438 | break 439 | i++, section[]:=section[""]+sizeof(section) 440 | } 441 | } 442 | PerformBaseRelocation(delta){ 443 | cdbs := this.MM.cdbs[""],this.MM.hdrs.OptionalHeader.DataDirectory[idx+1] 444 | ,directory := this.MM.hdrs.OptionalHeader.DataDirectory[ 1 + IMAGE_DIRECTORY_ENTRY_BASERELOC:=5] ; +1 because _Struct is 1 based 445 | if (directory.Size > 0) { 446 | relocation:=new _Struct(this.IMAGE_BASE_RELOCATION,cdbs + directory.VirtualAddress) 447 | While (relocation.VirtualAddress > 0 ) { 448 | dest := cdbs + relocation.VirtualAddress 449 | ,relInfo := relocation[""] + IMAGE_SIZEOF_BASE_RELOCATION:=sizeof(this.IMAGE_BASE_RELOCATION) 450 | While ((A_Index-1)<((relocation.SizeOfBlock-IMAGE_SIZEOF_BASE_RELOCATION) / 2)){ 451 | type := NumGet(relInfo+0,"UShort") >> 12 ; the upper 4 bits define the type of relocation 452 | ,offset := NumGet(relInfo+0,"UShort") & 0xfff ; the lower 12 bits define the offset 453 | If ((type=IMAGE_REL_BASED_HIGHLOW:=3) || (A_PtrSize=8 && type=IMAGE_REL_BASED_DIR64:=10)) ; change complete 32/64 bit address 454 | patchAddrHL := dest + offset,NumPut(NumGet(patchAddrHL+0,"PTR")+delta,patchAddrHL+0,"PTR") 455 | relInfo+=2 456 | } 457 | relocation[] := relocation[""] + relocation.SizeOfBlock ; advance to next relocation block 458 | } 459 | } 460 | } 461 | 462 | BuildImportTable(){ 463 | result := 1,VarSetCapacity(lpCookie,A_PtrSize,00),cdbs := this.MM.cdbs[""] 464 | ,directory := this.MM.hdrs.OptionalHeader.DataDirectory[ 1 + IMAGE_DIRECTORY_ENTRY_IMPORT:=1] ; +1 because _Struct is 1 based 465 | ,resource := this.MM.hdrs.OptionalHeader.DataDirectory[ 1 + IMAGE_DIRECTORY_ENTRY_RESOURCE:=2] ; +1 because _Struct is 1 based 466 | if (directory.Size > 0) 467 | { 468 | importDesc := new _Struct(this.IMAGE_IMPORT_DESCRIPTOR,cdbs + directory.VirtualAddress) 469 | ;~ MsgBox % resource.size 470 | if (resource.Size) ; Following will be used to resolve manifest in module 471 | { 472 | resDir := new _Struct(this.IMAGE_RESOURCE_DIRECTORY,cdbs + resource.VirtualAddress) 473 | ,resDirTemp := new _Struct(this.IMAGE_RESOURCE_DIRECTORY) 474 | ,resDirEntry := new _Struct(this.IMAGE_RESOURCE_DIRECTORY_ENTRY,resDir[""] + sizeof(this.IMAGE_RESOURCE_DIRECTORY)) 475 | ,resDirEntryTemp := new _Struct(this.IMAGE_RESOURCE_DIRECTORY_ENTRY) 476 | ,resDataEntry := new _Struct(this.IMAGE_RESOURCE_DATA_ENTRY) 477 | ,actctx :=new _Struct(this._ACTCTX) ; ACTCTX Structure 478 | ,actctx.cbSize := sizeof(actctx) 479 | ; Path to temp directory + our temporary file name 480 | ,VarSetCapacity(buf,1024) 481 | ,tempPathLength := DllCall("GetTempPath","UINT",256,"PTR", &buf,"UINT") 482 | ,DllCall("RtlMoveMemory","PTR",(&buf) + tempPathLength*2,"PTR",&_temp_:="AutoHotkey.MemoryModule.temp.manifest","PTR",74) 483 | ,actctx.lpSource[""]:=&buf 484 | ; Enumerate Resources 485 | ,i := 0 486 | While (i < resDir.NumberOfIdEntries + resDir.NumberOfNamedEntries){ 487 | ; Resolve current entry 488 | resDirEntry[] := resDir[""] + sizeof(this.IMAGE_RESOURCE_DIRECTORY) + (i*sizeof(this.IMAGE_RESOURCE_DIRECTORY_ENTRY)) 489 | ; If entry is directory and Id is 24 = RT_MANIFEST 490 | if ((resDirEntry.OffsetToData & 0x80000000) && resDirEntry.Id = 24) 491 | { 492 | resDirEntryTemp[] := resDir[""] + (resDirEntry.OffsetToData & 0x7FFFFFFF) + sizeof(this.IMAGE_RESOURCE_DIRECTORY) 493 | ,resDirTemp[] := resDir[""] + (resDirEntryTemp.OffsetToData & 0x7FFFFFFF) 494 | ,resDirEntryTemp[] := resDir[""] + (resDirEntryTemp.OffsetToData & 0x7FFFFFFF) + sizeof(this.IMAGE_RESOURCE_DIRECTORY) 495 | ,resDataEntry[] := resDir[""] + resDirEntryTemp.OffsetToData 496 | ; Write manifest to temportary file 497 | ; Using FILE_ATTRIBUTE_TEMPORARY will avoid writing it to disk 498 | ; It will be deleted after CreateActCtx has been called. 499 | ,hFile := DllCall("CreateFile,","STR",buf,"UINT",GENERIC_WRITE:=1073741824,"UINT",0,"PTR",0,"UINT",CREATE_ALWAYS:=2,"UINT",FILE_ATTRIBUTE_TEMPORARY:=256,"PTR",0,"PTR") 500 | if (hFile = INVALID_HANDLE_VALUE:=-1) 501 | break ; failed to create file, continue and try loading without CreateActCtx 502 | VarSetCapacity(byteswritten,A_PtrSize,0) 503 | ,DllCall("WriteFile","PTR",hFile,"PTR",(cdbs + resDataEntry.OffsetToData),"UINT",resDataEntry.Size,"PTR",&byteswritten,"PTR",0) 504 | ,DllCall("CloseHandle","PTR",hFile) 505 | if (NumGet(byteswritten,"PTR") = 0) 506 | break ; failed to write data, continue and try loading 507 | hActCtx := DllCall("CreateActCtx","PTR",actctx[""],"PTR") 508 | ; Open file and automatically delete on CloseHandle (FILE_FLAG_DELETE_ON_CLOSE) 509 | ,hFile := DllCall("CreateFile","STR",buf,"UINT",GENERIC_WRITE:=1073741824,"UINT",FILE_SHARE_DELETE:=4,"PTR",0,"UINT",OPEN_EXISTING:=3,"UINT",FILE_ATTRIBUTE_TEMPORARY:=256|FILE_FLAG_DELETE_ON_CLOSE:=67108864,"PTR",0,"PTR") 510 | ,DllCall("CloseHandle","PTR",hFile) 511 | if (hActCtx = INVALID_HANDLE_VALUE:=-1) 512 | break ; failed to create context, continue and try loading 513 | DllCall("ActivateActCtx","PTR",hActCtx,"PTR",&lpCookie) ; Don't care if this fails since we would countinue anyway 514 | break ; Break since a dll can have only 1 manifest 515 | } 516 | i++ 517 | } 518 | } 519 | thunkData:=new _Struct(this.IMAGE_IMPORT_BY_NAME) 520 | While (!DllCall("IsBadReadPtr","PTR",importDesc[""], "PTR", sizeof(this.IMAGE_IMPORT_DESCRIPTOR)) && importDesc.Name){ 521 | if (!(handle := DllCall("LoadLibraryA","PTR",(cdbs + importDesc.Name),"PTR")) && !result := 0) 522 | break 523 | If (this.Capacity("mdls")Lexikos AutoHotkey_L.exe
or other versions based on it.

new _Struct is used to create new structure. A structure must be defined as a global variable or an item of global class (e.g. "MyClass.Struct").
_Struct can handle structure in structure as well as Arrays of structures and Vectors.
Visit _Struct on AutoHotkey forum, any feedback is welcome. 7 | ; Syntax: MyStruct:= new _Struct(Structure_Definition,Address,initialization) 8 | ; Parameters: 9 | ; General Design - Class _Struct will create Object(s) that will manage fields of structure(s), for example
left,top,right,bottom
RC := new _Struct("RECT")
will create a RECT structure with fields left,top,right,bottom of type UInt. To pass the structure its pointer to a function, DllCall or SendMessage use RC[""].

To access fields you can use usual Object syntax: RC.left, RC.right ...
To set a field of the structure use RC.top := 100. 10 | ; Field types - Following AutoHotkey and Windows Data Types are supported:

AutoHotkey Data Types:
Int, Uint, Int64, UInt64, Char, UChar, Short, UShort, Fload and Double.

Windows Data Types:
ATOM,BOOL,BOOLEAN,BYTE,CHAR,COLORREF,DWORD,DWORDLONG,DWORD_PTR,
DWORD32,DWORD64,FLOAT,HACCEL,HALF_PTR,HANDLE,HBITMAP,HBRUSH,HCOLORSPACE,HCONV,HCONVLIST,HCURSOR,HDC,
HDDEDATA,HDESK,HDROP,HDWP,HENHMETAFILE,HFILE,HFONT,HGDIOBJ,HGLOBAL,HHOOK,HICON,HINSTANCE,HKEY,HKL,
HLOCAL,HMENU,HMETAFILE,HMODULE,HMONITOR,HPALETTE,HPEN,HRESULT,HRGN,HRSRC,HSZ,HWINSTA,HWND,INT,
INT_PTR,INT32,INT64,LANGID,LCID,LCTYPE,LGRPID,LONG,LONGLONG,LONG_PTR,LONG32,LONG64,LPARAM,LPBOOL,
LPBYTE,LPCOLORREF,LPCSTR,LPCTSTR,LPCVOID,LPCWSTR,LPDWORD,LPHANDLE,LPINT,LPLONG,LPSTR,LPTSTR,LPVOID,
LPWORD,LPWSTR,LRESULT,PBOOL,PBOOLEAN,PBYTE,PCHAR,PCSTR,PCTSTR,PCWSTR,PDWORD,PDWORDLONG,PDWORD_PTR,
PDWORD32,PDWORD64,PFLOAT,PHALF_PTR,PHANDLE,PHKEY,PINT,PINT_PTR,PINT32,PINT64,PLCID,PLONG,PLONGLONG,
PLONG_PTR,PLONG32,PLONG64,POINTER_32,POINTER_64,POINTER_SIGNED,POINTER_UNSIGNED,PSHORT,PSIZE_T,
PSSIZE_T,PSTR,PTBYTE,PTCHAR,PTSTR,PUCHAR,PUHALF_PTR,PUINT,PUINT_PTR,PUINT32,PUINT64,PULONG,PULONGLONG,
PULONG_PTR,PULONG32,PULONG64,PUSHORT,PVOID,PWCHAR,PWORD,PWSTR,SC_HANDLE,SC_LOCK,SERVICE_STATUS_HANDLE,
SHORT,SIZE_T,SSIZE_T,TBYTE,TCHAR,UCHAR,UHALF_PTR,UINT,UINT_PTR,UINT32,UINT64,ULONG,ULONGLONG,
ULONG_PTR,ULONG32,ULONG64,USHORT,USN,WCHAR,WORD,WPARAM 11 | ; Structure Definition - Description 12 | ; User defined - To create a user defined structure you will need to pass a string of predefined types and field names.
Default type is UInt, so for example for a RECT structure type can be omited: "left,top,right,left", which is the same as "Uint left,Uint top,Uint right,Uint bottom"

You can also use structures very similar to C#/C++ syntax, see example. 13 | ; Global - Global variables can be used to save structures, easily pass name of that variable as first parameter, e.g. new _Struct("MyStruct") where MyStruct must be a global variable with structure definition. Also new _Struct(MyStruct) can be used if variable is accessible. 14 | ; Array - To create an array of structures include a digit in the end of your string enclosed in squared brackets.
For example "RECT[2]" would create an array of 2 structures.
This feature can also be used for user defined arrays, for example "Int age,TCHAR name[10]". 15 | ; Union - Using {} you can create union, for example:
_AHKVar:="{Int64 ContentsInt64,Double ContentsDouble,object},... 16 | ; Struct - Using struct{} you can create structures in union or in structures. 17 | ; Pointer - To create a pointer you can use *, for example: CHR:="char *str" will hold a pointer to a character. Same way you can have a structure in structure so you can call it recursive, for example Label.NextLabel.NextLabel.NextLabel.JumpToLine 18 | ; Parameters - Description 19 | ; MyStruct - This is a variable that will hold the object representing the strucuture which is returned by new _Struct(...). 20 | ; Structure_Definition - C/C++ syntax or one-line definition e.g. "Int x,Int y". 21 | ; pointer - Pass a pointer as second parameter to occupy existing strucure. 22 | ; Initialization - Pass an object to initialize structure, e.g. {left:100,top:20}. If pointer is not used initialization can be specified in second parameter. 23 | ; Methods - Description 24 | ; Strct.Type(itm) - Returns type of item or structure 25 | ; Strct.AhkType(itm) - Returns AHK type of item or structure to be used with NumGet and NumPut as well as DllCall 26 | ; Strct.Size() - Returns size of structure, same as sizeof(MyStruct) 27 | ; Strct.SizeT(itm) - Returns size of an item 28 | ; Strct.Offset(itm) - Returns offset for items 29 | ; Strct.Encoding(itm) - Returns encoding for items, to be used with StrGet and StrPut 30 | ; Strct.Alloc(itm,size[,ptrsize]) - Allocates memory in bytes, ptrsize is used to create pointers 31 | ; Strct.Capacity(itm) - Returns memory capacity for items. 32 | ; Strct.IsPointer(itm) - Returns whether the item is a pointer (defined using *). 33 | ; Return Value: 34 | ; A class object representing your structure 35 | ; Remarks: 36 | ; NOTE!!! accessing a field that does not exist will cause recrusive calls and will crash your script, these errors are not catched for performance reasons.
TCHAR, UCHAR and CHAR return actual character rather than the value, use Asc() function to find out the value/code. 37 | ; Related: 38 | ; Example: 39 | ; file:Struct_Example.ahk 40 | ; 41 | #Include 42 | Class _Struct { 43 | ; Data Sizes 44 | static PTR:=A_PtrSize,UPTR:=A_PtrSize,SHORT:=2,USHORT:=2,INT:=4,UINT:=4,__int64:=8,INT64:=8,UINT64:=8,DOUBLE:=8,FLOAT:=4,CHAR:=1,UCHAR:=1,VOID:=A_PtrSize 45 | ,TBYTE:=A_IsUnicode?2:1,TCHAR:=A_IsUnicode?2:1,HALF_PTR:=A_PtrSize=8?4:2,UHALF_PTR:=A_PtrSize=8?4:2,INT32:=4,LONG:=4,LONG32:=4,LONGLONG:=8 46 | ,LONG64:=8,USN:=8,HFILE:=4,HRESULT:=4,INT_PTR:=A_PtrSize,LONG_PTR:=A_PtrSize,POINTER_64:=A_PtrSize,POINTER_SIGNED:=A_PtrSize 47 | ,BOOL:=4,SSIZE_T:=A_PtrSize,WPARAM:=A_PtrSize,BOOLEAN:=1,BYTE:=1,COLORREF:=4,DWORD:=4,DWORD32:=4,LCID:=4,LCTYPE:=4,LGRPID:=4,LRESULT:=4,PBOOL:=4 48 | ,PBOOLEAN:=A_PtrSize,PBYTE:=A_PtrSize,PCHAR:=A_PtrSize,PCSTR:=A_PtrSize,PCTSTR:=A_PtrSize,PCWSTR:=A_PtrSize,PDWORD:=A_PtrSize,PDWORDLONG:=A_PtrSize 49 | ,PDWORD_PTR:=A_PtrSize,PDWORD32:=A_PtrSize,PDWORD64:=A_PtrSize,PFLOAT:=A_PtrSize,PHALF_PTR:=A_PtrSize 50 | ,UINT32:=4,ULONG:=4,ULONG32:=4,DWORDLONG:=8,DWORD64:=8,ULONGLONG:=8,ULONG64:=8,DWORD_PTR:=A_PtrSize,HACCEL:=A_PtrSize,HANDLE:=A_PtrSize 51 | ,HBITMAP:=A_PtrSize,HBRUSH:=A_PtrSize,HCOLORSPACE:=A_PtrSize,HCONV:=A_PtrSize,HCONVLIST:=A_PtrSize,HCURSOR:=A_PtrSize,HDC:=A_PtrSize 52 | ,HDDEDATA:=A_PtrSize,HDESK:=A_PtrSize,HDROP:=A_PtrSize,HDWP:=A_PtrSize,HENHMETAFILE:=A_PtrSize,HFONT:=A_PtrSize 53 | static HGDIOBJ:=A_PtrSize,HGLOBAL:=A_PtrSize,HHOOK:=A_PtrSize,HICON:=A_PtrSize,HINSTANCE:=A_PtrSize,HKEY:=A_PtrSize,HKL:=A_PtrSize 54 | ,HLOCAL:=A_PtrSize,HMENU:=A_PtrSize,HMETAFILE:=A_PtrSize,HMODULE:=A_PtrSize,HMONITOR:=A_PtrSize,HPALETTE:=A_PtrSize,HPEN:=A_PtrSize 55 | ,HRGN:=A_PtrSize,HRSRC:=A_PtrSize,HSZ:=A_PtrSize,HWINSTA:=A_PtrSize,HWND:=A_PtrSize,LPARAM:=A_PtrSize,LPBOOL:=A_PtrSize,LPBYTE:=A_PtrSize 56 | ,LPCOLORREF:=A_PtrSize,LPCSTR:=A_PtrSize,LPCTSTR:=A_PtrSize,LPCVOID:=A_PtrSize,LPCWSTR:=A_PtrSize,LPDWORD:=A_PtrSize,LPHANDLE:=A_PtrSize 57 | ,LPINT:=A_PtrSize,LPLONG:=A_PtrSize,LPSTR:=A_PtrSize,LPTSTR:=A_PtrSize,LPVOID:=A_PtrSize,LPWORD:=A_PtrSize,LPWSTR:=A_PtrSize,PHANDLE:=A_PtrSize 58 | ,PHKEY:=A_PtrSize,PINT:=A_PtrSize,PINT_PTR:=A_PtrSize,PINT32:=A_PtrSize,PINT64:=A_PtrSize,PLCID:=A_PtrSize,PLONG:=A_PtrSize,PLONGLONG:=A_PtrSize 59 | ,PLONG_PTR:=A_PtrSize,PLONG32:=A_PtrSize,PLONG64:=A_PtrSize,POINTER_32:=A_PtrSize,POINTER_UNSIGNED:=A_PtrSize,PSHORT:=A_PtrSize,PSIZE_T:=A_PtrSize 60 | ,PSSIZE_T:=A_PtrSize,PSTR:=A_PtrSize,PTBYTE:=A_PtrSize,PTCHAR:=A_PtrSize,PTSTR:=A_PtrSize,PUCHAR:=A_PtrSize,PUHALF_PTR:=A_PtrSize,PUINT:=A_PtrSize 61 | ,PUINT_PTR:=A_PtrSize,PUINT32:=A_PtrSize,PUINT64:=A_PtrSize,PULONG:=A_PtrSize,PULONGLONG:=A_PtrSize,PULONG_PTR:=A_PtrSize,PULONG32:=A_PtrSize 62 | ,PULONG64:=A_PtrSize,PUSHORT:=A_PtrSize,PVOID:=A_PtrSize,PWCHAR:=A_PtrSize,PWORD:=A_PtrSize,PWSTR:=A_PtrSize,SC_HANDLE:=A_PtrSize 63 | ,SC_LOCK:=A_PtrSize,SERVICE_STATUS_HANDLE:=A_PtrSize,SIZE_T:=A_PtrSize,UINT_PTR:=A_PtrSize,ULONG_PTR:=A_PtrSize,ATOM:=2,LANGID:=2,WCHAR:=2,WORD:=2,USAGE:=2 64 | ; Data Types 65 | static _PTR:="PTR",_UPTR:="UPTR",_SHORT:="Short",_USHORT:="UShort",_INT:="Int",_UINT:="UInt" 66 | ,_INT64:="Int64",_UINT64:="UInt64",_DOUBLE:="Double",_FLOAT:="Float",_CHAR:="Char",_UCHAR:="UChar" 67 | ,_VOID:="PTR",_TBYTE:=A_IsUnicode?"USHORT":"UCHAR",_TCHAR:=A_IsUnicode?"USHORT":"UCHAR",_HALF_PTR:=A_PtrSize=8?"INT":"SHORT" 68 | ,_UHALF_PTR:=A_PtrSize=8?"UINT":"USHORT",_BOOL:="Int",_INT32:="Int",_LONG:="Int",_LONG32:="Int",_LONGLONG:="Int64",_LONG64:="Int64" 69 | ,_USN:="Int64",_HFILE:="UInt",_HRESULT:="UInt",_INT_PTR:="PTR",_LONG_PTR:="PTR",_POINTER_64:="PTR",_POINTER_SIGNED:="PTR",_SSIZE_T:="PTR" 70 | ,_WPARAM:="PTR",_BOOLEAN:="UCHAR",_BYTE:="UCHAR",_COLORREF:="UInt",_DWORD:="UInt",_DWORD32:="UInt",_LCID:="UInt",_LCTYPE:="UInt" 71 | ,_LGRPID:="UInt",_LRESULT:="UInt",_PBOOL:="UPTR",_PBOOLEAN:="UPTR",_PBYTE:="UPTR",_PCHAR:="UPTR",_PCSTR:="UPTR",_PCTSTR:="UPTR" 72 | ,_PCWSTR:="UPTR",_PDWORD:="UPTR",_PDWORDLONG:="UPTR",_PDWORD_PTR:="UPTR",_PDWORD32:="UPTR",_PDWORD64:="UPTR",_PFLOAT:="UPTR",___int64:="Int64" 73 | ,_PHALF_PTR:="UPTR",_UINT32:="UInt",_ULONG:="UInt",_ULONG32:="UInt",_DWORDLONG:="UInt64",_DWORD64:="UInt64",_ULONGLONG:="UInt64" 74 | ,_ULONG64:="UInt64",_DWORD_PTR:="UPTR",_HACCEL:="UPTR",_HANDLE:="UPTR",_HBITMAP:="UPTR",_HBRUSH:="UPTR",_HCOLORSPACE:="UPTR" 75 | ,_HCONV:="UPTR",_HCONVLIST:="UPTR",_HCURSOR:="UPTR",_HDC:="UPTR",_HDDEDATA:="UPTR",_HDESK:="UPTR",_HDROP:="UPTR",_HDWP:="UPTR" 76 | static _HENHMETAFILE:="UPTR",_HFONT:="UPTR",_HGDIOBJ:="UPTR",_HGLOBAL:="UPTR",_HHOOK:="UPTR",_HICON:="UPTR",_HINSTANCE:="UPTR",_HKEY:="UPTR" 77 | ,_HKL:="UPTR",_HLOCAL:="UPTR",_HMENU:="UPTR",_HMETAFILE:="UPTR",_HMODULE:="UPTR",_HMONITOR:="UPTR",_HPALETTE:="UPTR",_HPEN:="UPTR" 78 | ,_HRGN:="UPTR",_HRSRC:="UPTR",_HSZ:="UPTR",_HWINSTA:="UPTR",_HWND:="UPTR",_LPARAM:="UPTR",_LPBOOL:="UPTR",_LPBYTE:="UPTR",_LPCOLORREF:="UPTR" 79 | ,_LPCSTR:="UPTR",_LPCTSTR:="UPTR",_LPCVOID:="UPTR",_LPCWSTR:="UPTR",_LPDWORD:="UPTR",_LPHANDLE:="UPTR",_LPINT:="UPTR",_LPLONG:="UPTR" 80 | ,_LPSTR:="UPTR",_LPTSTR:="UPTR",_LPVOID:="UPTR",_LPWORD:="UPTR",_LPWSTR:="UPTR",_PHANDLE:="UPTR",_PHKEY:="UPTR",_PINT:="UPTR" 81 | ,_PINT_PTR:="UPTR",_PINT32:="UPTR",_PINT64:="UPTR",_PLCID:="UPTR",_PLONG:="UPTR",_PLONGLONG:="UPTR",_PLONG_PTR:="UPTR",_PLONG32:="UPTR" 82 | ,_PLONG64:="UPTR",_POINTER_32:="UPTR",_POINTER_UNSIGNED:="UPTR",_PSHORT:="UPTR",_PSIZE_T:="UPTR",_PSSIZE_T:="UPTR",_PSTR:="UPTR" 83 | ,_PTBYTE:="UPTR",_PTCHAR:="UPTR",_PTSTR:="UPTR",_PUCHAR:="UPTR",_PUHALF_PTR:="UPTR",_PUINT:="UPTR",_PUINT_PTR:="UPTR",_PUINT32:="UPTR" 84 | ,_PUINT64:="UPTR",_PULONG:="UPTR",_PULONGLONG:="UPTR",_PULONG_PTR:="UPTR",_PULONG32:="UPTR",_PULONG64:="UPTR",_PUSHORT:="UPTR" 85 | ,_PVOID:="UPTR",_PWCHAR:="UPTR",_PWORD:="UPTR",_PWSTR:="UPTR",_SC_HANDLE:="UPTR",_SC_LOCK:="UPTR",_SERVICE_STATUS_HANDLE:="UPTR" 86 | static _SIZE_T:="UPTR",_UINT_PTR:="UPTR",_ULONG_PTR:="UPTR",_ATOM:="Ushort",_LANGID:="Ushort",_WCHAR:="Ushort",_WORD:="UShort",_USAGE:="UShort" 87 | 88 | ; Following is used internally only to simplify setting field helpers 89 | ; the corresponding key can be set to invalid type (for string integer and vice versa) to set default if necessary, e.g. ___InitField(N,"") 90 | ___InitField(_this,N,offset=" ",encoding=0,AHKType=0,isptr=" ",type=0,arrsize=0,memory=0){ ; N = Name of field 91 | static _prefixes_:={offset:"`b",isptr:"`r",AHKType:"`n",type:"`t",encoding:"`f",memory:"`v",arrsize:" "} 92 | ,_testtype_:={offset:"integer",isptr:"integer",AHKType:"string",type:"string",encoding:"string",arrsize:"integer"} 93 | ,_default_:={offset:0,isptr:0,AHKType:"UInt",type:"UINT",encoding:"CP0",memory:"",arrsize:1} 94 | for _key_,_value_ in _prefixes_ 95 | { 96 | _typevalid_:=0 97 | If (_testtype_[_key_]="Integer"){ 98 | If %_key_% is integer 99 | useDefault:=1,_typevalid_:=1 100 | else if !_this.HasKey(_value_ N) 101 | useDefault:=1 102 | } else { 103 | If %_key_% is not integer 104 | useDefault:=1,_typevalid_:=1 105 | else if !_this.HasKey(_value_ N) 106 | useDefault:=1 107 | } 108 | If (useDefault) ; item does not exist or user supplied a valid type 109 | If (_key_="encoding") 110 | _this[_value_ N]:=_typevalid_?(InStr(",LPTSTR,LPCTSTR,TCHAR,","," %_key_% ",")?(A_IsUnicode?"UTF-16":"CP0") 111 | :InStr(",LPWSTR,LPCWSTR,WCHAR,","," %_key_% ",")?"UTF-16":"CP0") 112 | :_default_[_key_] 113 | else { 114 | _this[_value_ N]:=_typevalid_?%_key_%:_default_[_key_] 115 | } 116 | } 117 | } 118 | 119 | ; Struct Contstructor 120 | ; Memory, offset and definitions are saved in following character + given key/name 121 | ; `a = Allocated Memory 122 | ; `b = Byte Offset (related to struct address) 123 | ; `f = Format (encoding for string data types) 124 | ; `n = New data type (AHK data type) 125 | ; `r = Is Pointer (requred for __GET and __SET) 126 | ; `t = Type (data type, also when it is name of a Structure it is used to resolve structure pointers dynamically 127 | ; `v = Memory used to save string and pointer memory 128 | __NEW(_TYPE_,_pointer_=0,_init_=0){ 129 | static _base_:={__GET:_Struct.___GET,__SET:_Struct.___SET,__SETPTR:_Struct.___SETPTR,__Clone:_Struct.___Clone,__NEW:_Struct.___NEW 130 | ,IsPointer:_Struct.IsPointer,Offset:_Struct.Offset,Type:_Struct.Type,AHKType:_Struct.AHKType,Encoding:_Struct.Encoding 131 | ,Capacity:_Struct.Capacity,Alloc:_Struct.Alloc,Size:_Struct.Size,SizeT:_Struct.SizeT,Print:_Struct.Print,ToObj:_Struct.ToObj} 132 | local _,_ArrType_,_ArrName_:="",_ArrSize_,_align_total_,_defobj_,_IsPtr_,_key_,_LF_,_LF_BKP_,_match_,_offset_:="" 133 | ,_struct_,_StructSize_,_total_union_size_,_union_,_union_size_,_value_,_mod_,_max_size_,_in_struct_,_struct_align_ 134 | 135 | If (RegExMatch(_TYPE_,"^[\w\d\._]+$") && !_Struct.HasKey(_TYPE_)){ ; structures name was supplied, resolve to global var and run again 136 | If InStr(_TYPE_,"."){ ;check for object that holds structure definition 137 | Loop,Parse,_TYPE_,. 138 | If A_Index=1 139 | _defobj_:=%A_LoopField% 140 | else _defobj_:=_defobj_[A_LoopField] 141 | _TYPE_:=_defobj_ 142 | } else _TYPE_:=%_TYPE_%,_defobj_:="" 143 | } else _defobj_:="" 144 | ; If a pointer is supplied, save it in key [""] else reserve and zero-fill memory + set pointer in key [""] 145 | If (_pointer_ && !IsObject(_pointer_)) 146 | this[""] := _pointer_,this["`a"]:=0,this["`a`a"]:=sizeof(_TYPE_) 147 | else 148 | this._SetCapacity("`a",_StructSize_:=sizeof(_TYPE_)) ; Set Capacity in key ["`a"] 149 | ,this[""]:=this._GetAddress("`a") ; Save pointer in key [""] 150 | ,DllCall("RtlZeroMemory","UPTR",this[""],"UInt",this["`a`a"]:=_StructSize_) ; zero-fill memory 151 | ; C/C++ style structure definition, convert it 152 | If InStr(_TYPE_,"`n") { 153 | _struct_:=[] ; keep track of structures (union is just removed because {} = union, struct{} = struct 154 | _union_:=0 ; init to 0, used to keep track of union depth 155 | Loop,Parse,_TYPE_,`n,`r`t%A_Space%%A_Tab% ; Parse each line 156 | { 157 | _LF_:="" 158 | Loop,Parse,A_LoopField,`,`;,`t%A_Space%%A_Tab% ; Parse each item 159 | { 160 | If RegExMatch(A_LoopField,"^\s*//") ;break on comments and continue main loop 161 | break 162 | If (A_LoopField){ ; skip empty lines 163 | If (!_LF_ && _ArrType_:=RegExMatch(A_LoopField,"[\w\d_#@]\s+[\w\d_#@]")) ; new line, find out data type and save key in _LF_ Data type will be added later 164 | _LF_:=RegExReplace(A_LoopField,"[\w\d_#@]\K\s+.*$") 165 | If Instr(A_LoopField,"{"){ ; Union, also check if it is a structure 166 | _union_++,_struct_.Insert(_union_,RegExMatch(A_LoopField,"i)^\s*struct\s*\{")) 167 | } else If InStr(A_LoopField,"}") ; end of union/struct 168 | _offset_.="}" 169 | else { ; not starting or ending struct or union so add definitions and apply Data Type. 170 | If _union_ ; add { or struct{ 171 | Loop % _union_ 172 | _ArrName_.=(_struct_[A_Index]?"struct":"") "{" 173 | _offset_.=(_offset_ ? "," : "") _ArrName_ ((_ArrType_ && A_Index!=1)?(_LF_ " "):"") RegExReplace(A_LoopField,"\s+"," ") 174 | ,_ArrName_:="",_union_:=0 175 | } 176 | } 177 | } 178 | } 179 | _TYPE_:=_offset_ 180 | } 181 | 182 | _offset_:=0 183 | ,_union_:=[] ; keep track of union level, required to reset offset after union is parsed 184 | ,_struct_:=[] ; for each union level keep track if it is a structure (because here offset needs to increase 185 | ,_union_size_:=[] ; keep track of highest member within the union or structure, used to calculate new offset after union 186 | ,_struct_align_:=[] ; keep track of alignment before structure 187 | ,_total_union_size_:=0 ; used in combination with above, each loop the total offset is updated if current data size is higher 188 | ,_align_total_:=0 ; used to calculate alignment for total size of structure 189 | ,_in_struct_:=1 190 | 191 | ,this["`t"]:=0,this["`r"]:=0 ; will identify a Structure Pointer without members 192 | 193 | ; Parse given structure definition and create struct members 194 | ; User structures will be resolved by recrusive calls (!!! a structure must be a global variable) 195 | Loop,Parse,_TYPE_,`,`; ;,%A_Space%%A_Tab%`n`r 196 | { 197 | _in_struct_+=StrLen(A_LoopField)+1 198 | If ("" = _LF_ := trim(A_LoopField,A_Space A_Tab "`n`r")) 199 | continue 200 | _LF_BKP_:=_LF_ ;to check for ending brackets = union,struct 201 | _IsPtr_:=0 202 | ; Check for STARTING union and set union helpers 203 | While (_match_:=RegExMatch(_LF_,"i)^(struct|union)?\s*\{\K")) 204 | ; correct offset for union/structure, sizeof_maxsize returns max size of union or structure 205 | _max_size_:=sizeof_maxsize(SubStr(_TYPE_,_in_struct_-StrLen(A_LoopField)-1+(StrLen(_LF_BKP_)-StrLen(_LF_)))) 206 | ,_union_.Insert(_offset_+=(_mod_:=Mod(_offset_,_max_size_))?Mod(_max_size_-_mod_,_max_size_):0) 207 | ,_union_size_.Insert(0) 208 | ,_struct_align_.Insert(_align_total_>_max_size_?_align_total_:_max_size_) 209 | ,_struct_.Insert(RegExMatch(_LF_,"i)^struct\s*\{")?(1,_align_total_:=0):0) 210 | ,_LF_:=SubStr(_LF_,_match_) 211 | 212 | StringReplace,_LF_,_LF_,},,A ;remove all closing brackets (these will be checked later) 213 | 214 | ; Check if item is a pointer and remove * for further processing, separate key will store that information 215 | While % (InStr(_LF_,"*")){ 216 | StringReplace,_LF_,_LF_,* 217 | _IsPtr_:=A_Index 218 | } 219 | ; Split off data type, name and size (only data type is mandatory) 220 | RegExMatch(_LF_,"^(?[\w\d\._]+)?\s*(?[\w\d_]+)?\s*\[?(?\d+)?\]?\s*\}*\s*$",_) 221 | If (!_ArrName_ && !_ArrSize_){ 222 | If RegExMatch(_TYPE_,"^\**" _ArrType_ "\**$"){ 223 | _Struct.___InitField(this,"",0,_ArrType_,_IsPtr_?"PTR":_Struct.HasKey("_" _ArrType_)?_Struct["_" _ArrType_]:"PTR",_IsPtr_,_ArrType_) 224 | this.base:=_base_ 225 | If (IsObject(_init_)||IsObject(_pointer_)){ ; Initialization of structures members, e.g. _Struct(_RECT,{left:10,right:20}) 226 | for _key_,_value_ in IsObject(_init_)?_init_:_pointer_ 227 | { 228 | If !this["`r"]{ ; It is not a pointer, assign value 229 | If InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,","," this["`t" _key_] ",") 230 | this.Alloc(_key_,StrLen(_value_)*(InStr(".LPWSTR,LPCWSTR,","," this["`t"] ",")||(InStr(",LPTSTR,LPCTSTR,","," this["`t" _key_] ",")&&A_IsUnicode)?2:1)) 231 | if InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,CHAR,TCHAR,WCHAR,","," this["`t" _key_] ",") 232 | this[_key_]:=_value_ 233 | else 234 | this[_key_] := _value_ 235 | }else if (_value_<>"") ; It is not empty 236 | If _value_ is integer ; It is a new pointer 237 | this[_key_][""]:=_value_ 238 | } 239 | } 240 | Return this ;:= new _Struct(%_ArrType_%,_pointer_) ;only Data type was supplied, object/structure has got no members/keys 241 | } else 242 | _ArrName_:=_ArrType_,_ArrType_:="UInt" 243 | } 244 | If InStr(_ArrType_,"."){ ;check for object that holds structure definition 245 | Loop,Parse,_ArrType_,. 246 | If A_Index=1 247 | _defobj_:=%A_LoopField% 248 | else _defobj_:=_defobj_[A_LoopField] 249 | } 250 | if (!_IsPtr_ && !_Struct.HasKey(_ArrType_)){ ; _ArrType_ not found resolve to global variable (must contain struct definition) 251 | if (sizeof(_defobj_?_defobj_:%_ArrType_%,0,_align_total_) && mod:=Mod(_offset_,_align_total_)) 252 | _offset_+=Mod(_align_total_-_mod_,_align_total_) 253 | _Struct.___InitField(this,_ArrName_,_offset_,_ArrType_,0,0,_ArrType_,_ArrSize_) 254 | ; update current union size 255 | If (_uix_:=_union_.MaxIndex()) && (_max_size_:=_offset_ + sizeof(_defobj_?_defobj_:%_ArrType_%) - _union_[_uix_])>_union_size_[_uix_] 256 | _union_size_[_uix_]:=_max_size_ 257 | _max_size:=0 258 | ; if not a union or a union + structure then offset must be moved (when structure offset will be reset below 259 | If (!_uix_||_struct_[_struct_.MaxIndex()]) 260 | _offset_+=this[" " _ArrName_]*sizeof(_defobj_?_defobj_:%_ArrType_%) ; move offset 261 | ;Continue 262 | } else { 263 | If ((_IsPtr_ || _Struct.HasKey(_ArrType_))) 264 | _offset_+=(_mod_:=Mod(_offset_,_max_size_:=_IsPtr_?A_PtrSize:_Struct[_ArrType_]))=0?0:(_IsPtr_?A_PtrSize:_Struct[_ArrType_])-_mod_ 265 | ,_align_total_:=_max_size_>_align_total_?_max_size_:_align_total_ 266 | ,_Struct.___InitField(this,_ArrName_,_offset_,_ArrType_,_IsPtr_?"PTR":_Struct.HasKey(_ArrType_)?_Struct["_" _ArrType_]:_ArrType_,_IsPtr_,_ArrType_,_ArrSize_) 267 | ; update current union size 268 | If (_uix_:=_union_.MaxIndex()) && (_max_size_:=_offset_ + _Struct[this["`n" _ArrName_]] - _union_[_uix_])>_union_size_[_uix_] 269 | _union_size_[_uix_]:=_max_size_ 270 | _max_size_:=0 271 | ; if not a union or a union + structure then offset must be moved (when structure offset will be reset below 272 | If (!_uix_||_struct_[_uix_]) 273 | _offset_+=_IsPtr_?A_PtrSize:(_Struct.HasKey(_ArrType_)?_Struct[_ArrType_]:%_ArrType_%)*this[" " _ArrName_] 274 | } 275 | ; Check for ENDING union and reset offset and union helpers 276 | While (SubStr(_LF_BKP_,0)="}"){ 277 | If (!_uix_:=_union_.MaxIndex()){ 278 | MsgBox,0, Incorrect structure, missing opening braket {`nProgram will exit now `n%_TYPE_% 279 | ExitApp 280 | } ; Increase total size of union/structure if necessary 281 | ; reset offset and align because we left a union or structure 282 | if (_uix_>1 && _struct_[_uix_-1]){ 283 | if (_mod_:=Mod(_offset_,_struct_align_[_uix_])) 284 | _offset_+=Mod(_struct_align_[_uix_]-_mod_,_struct_align_[_uix_]) 285 | } else _offset_:=_union_[_uix_] 286 | if (_struct_[_uix_]&&_struct_align_[_uix_]>_align_total_) 287 | _align_total_ := _struct_align_[_uix_] 288 | ; Increase total size of union/structure if necessary 289 | _total_union_size_ := _union_size_[_uix_]>_total_union_size_?_union_size_[_uix_]:_total_union_size_ 290 | ,_union_._Remove(),_struct_._Remove(),_union_size_._Remove(),_struct_align_.Remove(),_LF_BKP_:=SubStr(_LF_BKP_,1,StrLen(_LF_BKP_)-1) ; remove latest items 291 | If (_uix_=1){ ; leaving top union, add offset 292 | if (_mod_:=Mod(_total_union_size_,_align_total_)) 293 | _total_union_size_ += Mod(_align_total_-_mod_,_align_total_) 294 | _offset_+=_total_union_size_,_total_union_size_:=0 295 | } 296 | } 297 | } 298 | this.base:=_base_ ; apply new base which uses below functions and uses ___GET for __GET and ___SET for __SET 299 | If (IsObject(_init_)||IsObject(_pointer_)){ ; Initialization of structures members, e.g. _Struct(_RECT,{left:10,right:20}) 300 | for _key_,_value_ in IsObject(_init_)?_init_:_pointer_ 301 | { 302 | If !this["`r" _key_]{ ; It is not a pointer, assign value 303 | If InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,","," this["`t" _key_] ",") 304 | this.Alloc(_key_,StrLen(_value_)*(InStr(".LPWSTR,LPCWSTR,","," this["`t"] ",")||(InStr(",LPTSTR,LPCTSTR,","," this["`t" _key_] ",")&&A_IsUnicode)?2:1)) 305 | if InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,CHAR,TCHAR,WCHAR,","," this["`t" _key_] ",") 306 | this[_key_]:=_value_ 307 | else 308 | this[_key_] := _value_ 309 | }else if (_value_<>"") ; It is not empty 310 | if _value_ is integer ; It is a new pointer 311 | this[_key_][""]:=_value_ 312 | } 313 | } 314 | Return this 315 | } 316 | ToObj(struct:=""){ 317 | obj:=[] 318 | for k,v in struct?struct:struct:=this 319 | if (Asc(k)=10) 320 | If IsObject(_VALUE_:=struct[_TYPE_:=SubStr(k,2)]) 321 | obj[_TYPE_]:=this.ToObj(_VALUE_) 322 | else obj[_TYPE_]:=_VALUE_ 323 | return obj 324 | } 325 | SizeT(_key_=""){ 326 | return sizeof(this["`t" _key_]) 327 | } 328 | Size(){ 329 | return sizeof(this) 330 | } 331 | IsPointer(_key_=""){ 332 | return this["`r" _key_] 333 | } 334 | Type(_key_=""){ 335 | return this["`t" _key_] 336 | } 337 | AHKType(_key_=""){ 338 | return this["`n" _key_] 339 | } 340 | Offset(_key_=""){ 341 | return this["`b" _key_] 342 | } 343 | Encoding(_key_=""){ 344 | return this["`b" _key_] 345 | } 346 | Capacity(_key_=""){ 347 | return this._GetCapacity("`v" _key_) 348 | } 349 | Alloc(_key_="",size="",ptrsize=0){ 350 | If _key_ is integer 351 | ptrsize:=size,size:=_key_,_key_:="" 352 | If size is integer 353 | SizeIsInt:=1 354 | If ptrsize { 355 | If (this._SetCapacity("`v" _key_,!SizeIsInt?A_PtrSize+ptrsize:size + (size//A_PtrSize)*ptrsize)="") 356 | MsgBox % "Memory for pointer ." _key_ ". of size " (SizeIsInt?size:A_PtrSize) " could not be set!" 357 | else { 358 | DllCall("RtlZeroMemory","UPTR",this._GetAddress("`v" _key_),"UInt",this._GetCapacity("`v" _key_)) 359 | If (this[" " _key_]>1){ 360 | ptr:=this[""] + this["`b" _key_] 361 | If (this["`r" _key_] || InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,","," this["`t" _key_] ",")) 362 | NumPut(ptrs:=this._GetAddress("`v" _key_),ptr+0,"PTR") 363 | else if _key_ 364 | this[_key_,""]:=ptrs:=this._GetAddress("`v" _key_) 365 | else this[""]:=ptr:=this._GetAddress("`v" _key_),ptrs:=this._GetAddress("`v" _key_)+(SizeIsInt?size:A_PtrSize) 366 | } else { 367 | If (this["`r" _key_] || InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,","," this["`t" _key_] ",")) 368 | NumPut(ptr:=this._GetAddress("`v" _key_),this[""] + this["`b" _key_],"PTR") 369 | else this[""]:=ptr:=this._GetAddress("`v" _key_) 370 | ptrs:=ptr+(size?size:A_PtrSize) 371 | } 372 | Loop % SizeIsInt?(size//A_PtrSize):1 373 | NumPut(ptrs+(A_Index-1)*ptrsize,ptr+(A_Index-1)*A_PtrSize,"PTR") 374 | } 375 | } else { 376 | If (this._SetCapacity("`v" _key_,SizeIsInt?size:A_PtrSize)=""){ 377 | MsgBox % "Memory for pointer ." _key_ ". of size " (SizeIsInt?size:A_PtrSize) " could not be set!" 378 | } else 379 | NumPut(ptr:=this._GetAddress("`v" _key_),this[""] + this["`b" _key_],"PTR"),DllCall("RtlZeroMemory","UPTR",ptr,"UInt",SizeIsInt?size:A_PtrSize) 380 | } 381 | return ptr 382 | } 383 | ___NEW(init*){ 384 | this:=this.base 385 | newobj := this.__Clone(1) ;clone structure and keep pointer (1), it will be changed below 386 | If (init.MaxIndex() && !IsObject(init.1)) 387 | newobj[""] := init.1 388 | else If (init.MaxIndex()>1 && !IsObject(init.2)) 389 | newobj[""] := init.2 390 | else 391 | newobj._SetCapacity("`a",_StructSize_:=sizeof(this)) ; Set Capacity in key ["`a"] 392 | ,newobj[""]:=newobj._GetAddress("`a") ; Save pointer in key [""] 393 | ,DllCall("RtlZeroMemory","UPTR",newobj[""],"UInt",_StructSize_) ; zero-fill memory 394 | If (IsObject(init.1)||IsObject(init.2)) 395 | for _key_,_value_ in IsObject(init.1)?init.1:init.2 396 | newobj[_key_] := _value_ 397 | return newobj 398 | } 399 | 400 | ; Clone structure and move pointer for new structure 401 | ___Clone(offset){ 402 | static _base_:={__GET:_Struct.___GET,__SET:_Struct.___SET,__SETPTR:_Struct.___SETPTR,__Clone:_Struct.___Clone,__NEW:_Struct.___NEW 403 | ,IsPointer:_Struct.IsPointer,Offset:_Struct.Offset,Type:_Struct.Type,AHKType:_Struct.AHKType,Encoding:_Struct.Encoding 404 | ,Capacity:_Struct.Capacity,Alloc:_Struct.Alloc,Size:_Struct.Size,SizeT:_Struct.SizeT,Print:_Struct.Print,ToObj:_Struct.ToObj} 405 | If offset=1 406 | return this 407 | newobj:={} ; new structure object 408 | for _key_,_value_ in this ; copy all values/objects 409 | If (_key_!="`a") 410 | newobj[_key_]:=_value_ ; add key to new object and assign value 411 | newobj._SetCapacity("`a",_StructSize_:=sizeof(this)) ; Set Capacity in key ["`a"] 412 | ,newobj[""]:=newobj._GetAddress("`a") ; Save pointer in key [""] 413 | ,DllCall("RtlZeroMemory","UPTR",newobj[""],"UInt",_StructSize_) ; zero-fill memory 414 | If this["`r"]{ ; its a pointer so we need too move internal memory 415 | NumPut(NumGet(this[""],"PTR")+A_PtrSize*(offset-1),newobj[""],"Ptr") 416 | newobj.base:=_base_ ;assign base of _Struct 417 | } else ; do not use internal memory, simply assign new pointer to new structure 418 | newobj.base:=_base_,newobj[]:=this[""]+sizeof(this)*(offset-1) 419 | return newobj ; return new object 420 | } 421 | ___GET(_key_="",p*){ 422 | If (_key_="") ; Key was not given so structure[] has been called, return pointer to structure 423 | Return this[""] 424 | else if !(idx:=p.MaxIndex()) 425 | _field_:=_key_,opt:="~" 426 | else { 427 | ObjInsert(p,1,_key_) 428 | opt:=ObjRemove(p),_field_:=_key_:=ObjRemove(p) 429 | for key_,value_ in p 430 | this:=this[value_] 431 | } 432 | If this["`t"] ; structure without keys/members 433 | _key_:="" ; set _key_ empty so items below will resolve to our structure 434 | If (opt!="~"){ 435 | If (opt=""){ 436 | If _field_ is integer 437 | return (this["`r"]?NumGet(this[""],"PTR"):this[""])+sizeof(this["`t"])*(_field_-1) 438 | else return this["`r" _key_]?NumGet(this[""]+this["`b" _key_],"PTR"):this[""]+this["`b" _key_] ;+sizeof(this["`t" _key_])*(_field_-1) 439 | } else If opt is integer 440 | { ;offset to a item e.g. struct.a[100] ("Uint a[100]") 441 | ; MsgBox % "ja " 442 | If (_Struct.HasKey("_" this["`t" _key_]) && this[" " _key_]>1) { 443 | If (InStr( ",CHAR,UCHAR,TCHAR,WCHAR," , "," this["`t" _key_] "," )){ ; StrGet 1 character only 444 | Return StrGet(this[""]+this["`b" _key_]+(opt-1)*sizeof(this["`t" _key_]),1,this["`f" _key_]) 445 | } else if InStr( ",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t" _key_] "," ){ ; StrGet string 446 | Return StrGet(NumGet(this[""]+this["`b" _key_]+(opt-1)*A_PtrSize,"PTR"),this["`f" _key_]) 447 | } else { 448 | Return NumGet(this[""]+this["`b" _key_]+(opt-1)*sizeof(this["`t" _key_]),this["`n" _key_]) 449 | } 450 | } else Return new _Struct(this["`t" _key_],this[""]+this["`b" _key_]+(opt-1)*sizeof(this["`t" _key_])) 451 | } else 452 | return this[_key_][opt] 453 | } else If _field_ is integer 454 | { ; array access (must be listed first because otherwise this["`r" _key_] cannot be resolved 455 | If (_key_){ ; Offset for item 456 | return this.__Clone(_field_) 457 | } else if this["`r"] { 458 | Pointer:="" 459 | Loop % (this["`r"]-1) ; dip into one step and return a new structure 460 | pointer.="*" 461 | If pointer 462 | Return new _Struct(pointer this["`t"],NumGet(this[""],"PTR")+A_PtrSize*(_field_-1)) 463 | else Return new _Struct(pointer this["`t"],NumGet(this[""],"PTR")+sizeof(this["`t"])*(_field_-1)).1 464 | } else if _Struct.HasKey("_" this["`t"]) { 465 | ; If this[" "] 466 | ; Return new _Struct(this["`t"],this[""]) 467 | ; else 468 | If (InStr( ",CHAR,UCHAR,TCHAR,WCHAR," , "," this["`t"] "," )){ ; StrGet 1 character only 469 | Return StrGet(this[""]+sizeof(this["`t"])*(_field_-1),1,this["`f"]) 470 | } else if InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t"] "," ){ ; StrGet string 471 | Return StrGet(NumGet(this[""]+A_PtrSize*(_field_-1),"PTR"),this["`f"]) 472 | } else { ; resolve pointer 473 | Return NumGet(this[""]+sizeof(this["`t"])*(_field_-1),this["`n"]) 474 | } 475 | } else { 476 | 477 | ; return this.__Clone(_field_) 478 | ; listVars 479 | ; MsgBox % this[""] "+" sizeof(this["`t"])*(_field_-1) "-" this["`t"] 480 | Return new _Struct(this["`t"],this[""]+sizeof(this["`t"])*(_field_-1)) 481 | } 482 | } else If this["`r" _key_] { ;pointer 483 | Pointer:="" 484 | Loop % (this["`r" _key_]-1) ; dip into one step and return a new structure 485 | pointer.="*" 486 | If (_key_=""){ 487 | return this[1][_field_] 488 | } else { 489 | Return new _Struct(pointer this["`t" _key_],NumGet(this[""]+this["`b" _key_],"PTR")) 490 | } 491 | } else if _Struct.HasKey("_" this["`t" _key_]) { ; default data type, not pointer 492 | If (this[" " _key_]>1) 493 | Return new _Struct(this["`t" _key_],this[""] + this["`b" _key_]) 494 | else If (InStr( ",CHAR,UCHAR,TCHAR,WCHAR," , "," this["`t" _key_] "," )){ ; StrGet 1 character only 495 | Return StrGet(this[""]+this["`b" _key_],1,this["`f" _key_]) 496 | } else if InStr( ",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t" _key_] "," ){ ; StrGet string 497 | Return StrGet(NumGet(this[""]+this["`b" _key_],"PTR"),this["`f" _key_]) 498 | } else { 499 | Return NumGet(this[""]+this["`b" _key_],this["`n" _key_]) 500 | } 501 | } else { ; the field is a non pointer structure 502 | Return new _Struct(this["`t" _key_],this[""]+this["`b" _key_]) 503 | } 504 | } 505 | ___SET(_key_,p*){ ;="",_value_=-0x8000000000000000 ,opt="~"){ 506 | If !(idx:=p.MaxIndex()) ; Set new Pointer, here a value was assigned e.g. struct[]:=&var 507 | return this[""] :=_key_,this._SetCapacity("`a",0) ; free internal memory, it will not be used anymore 508 | else if (idx=1) 509 | _value_:=p.1,opt:="~" 510 | else if (idx>1){ 511 | ObjInsert(p,1,_key_) 512 | If (p[idx]="") 513 | opt:=ObjRemove(p),_value_:=ObjRemove(p),_key_:=ObjRemove(p) 514 | else _value_:=ObjRemove(p),_key_:=ObjRemove(p),opt:="~" 515 | for key_,value_ in p 516 | this:=this[value_] 517 | } 518 | If this["`t"] ; structure without members 519 | _field_:=_key_,_key_:="" ; set _key_ empty so it will resolve to our structure 520 | else _field_:=_key_ 521 | If this["`r" _key_] { ; Pointer 522 | If opt is integer 523 | return NumPut(opt,this[""] + this["`b" _key_],"PTR") 524 | else if this.HasKey("`t" _key_) { 525 | Pointer:="" 526 | Loop % (this["`r" _key_]-1) ; dip into one step and return a new structure 527 | pointer.="*" 528 | If _key_ 529 | Return (new _Struct(pointer this["`t" _key_],NumGet(this[""] + this["`b" _key_],"PTR"))).1:=_value_ 530 | else Return (new _Struct(pointer this["`t"],NumGet(this[""],"PTR")))[_field_]:=_value_ 531 | } else If _field_ is Integer 532 | if (_key_="") ; replace this for the operation 533 | _this:=this,this:=this.__Clone(_Field_) 534 | If InStr( ",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t" _key_] "," ) 535 | StrPut(_value_,NumGet(NumGet(this[""]+this["`b" _key_],"PTR"),"PTR"),this["`f" _key_]) ; StrPut char to addr+A_PtrSize 536 | else if InStr( ",TCHAR,CHAR,UCHAR,WCHAR," , "," this["`t" _key_] "," ){ ; same as above but for 1 Character only 537 | StrPut(_value_,NumGet(this[""]+this["`b" _key_],"PTR"),this["`f" _key_]) ; StrPut char to addr 538 | } else 539 | NumPut(_value_,NumGet(this[""]+this["`b" _key_],"PTR"),this["`n" _key_]) 540 | If _field_ is integer ; restore this after operation 541 | this:=_this 542 | } else if (RegExMatch(_field_,"^\d+$") && _key_="") { 543 | if InStr( ",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t"] "," ){ 544 | StrPut(_value_,NumGet(this[""]+A_PtrSize*(_field_-1),"PTR"),this["`f"]) ; StrPut string to addr 545 | } else if InStr( ",TCHAR,CHAR,UCHAR,WCHAR," , "," this["`t" _key_] "," ){ 546 | StrPut(_value_,this[""] + sizeof(this["`t"])*(_field_-1),this["`f"]) 547 | } else 548 | NumPut(_value_,this[""] + sizeof(this["`t"])*(_field_-1),this["`n"]) ; NumPut new value to key 549 | } else if opt is integer 550 | { 551 | return NumPut(opt,this[""] + this["`b" _key_],"PTR") 552 | } else if InStr( ",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t" _key_] "," ){ 553 | StrPut(_value_,NumGet(this[""] + this["`b" _key_],"PTR"),this["`f" _key_]) ; StrPut string to addr 554 | } else if InStr( ",TCHAR,CHAR,UCHAR,WCHAR," , "," this["`t" _key_] "," ){ 555 | StrPut(_value_,this[""] + this["`b" _key_],this["`f" _key_]) ; StrPut character key 556 | } else 557 | NumPut(_value_,this[""]+this["`b" _key_],this["`n" _key_]) ; NumPut new value to key 558 | Return _value_ 559 | } 560 | } -------------------------------------------------------------------------------- /Required-Libraries/readResource.ahk: -------------------------------------------------------------------------------- 1 | readResource(ByRef Var, Name, Type="#10") { 2 | VarSetCapacity( Var, 128 ), VarSetCapacity( Var, 0 ) 3 | If ! ( A_IsCompiled ) { 4 | FileGetSize, nSize, %Name% 5 | FileRead, Var, *c %Name% 6 | Return nSize 7 | } 8 | If hMod := DllCall( "GetModuleHandle", UInt,0 ) 9 | If hRes := DllCall( "FindResource", UInt,hMod, Str, Name, Str, Type) ;RCDATA = #10 10 | If hData := DllCall( "LoadResource", UInt,hMod, UInt,hRes ) 11 | If pData := DllCall( "LockResource", UInt,hData ) 12 | Return VarSetCapacity( Var, nSize := DllCall( "SizeofResource", UInt,hMod, UInt,hRes ) ) 13 | , DllCall( "RtlMoveMemory", Str,Var, UInt,pData, UInt,nSize ) 14 | Return 0 15 | } --------------------------------------------------------------------------------