#include-once ; corz.org essential (Lite Version) v1.2.1.2 ; ; Commonly-used AutoIt functions. #include #include #include #include #include #include #include ; for clean ini.. #include #include #include ; Setup a few variables.. global const $LOG_LF = @CRLF ; for logs/saved text files/console global const $MSG_LF = @LF ; for dialog boxes, etc. ; These make great AutoIt Booleans for sooooooo many reasons.. global const $ON = $GUI_CHECKED ; 1 global const $OFF = $GUI_UNCHECKED ; 4 global const $UNSET = $GUI_INDETERMINATE ; 2 ; For "humanizing" AutoIt booleans (and for reporting/display purposes).. global const $STR_ENABLED = "enabled" global const $STR_DISABLED = "disabled" global const $DEF_MSG_TIME = 2000 ; Handy for Win10 GUI stuff.. global const $COLOR_LTGREY = 0xD0D0D0 ; So we can do GUICtrlSetData($ctrl, $state[$some_ON/OFF_bool]) ; global $state[5] = [0, $str_enabled, 0, 0, $str_disabled] ; Nice idea, but Human($pref) gets you the same result and is more easily understood. ; I use these variables meaningfully. Check them out! ; You can override these in your app, if required. global $dump_file global $debug_level = 10 global $max_debug_log_size = 0 ; 0 = no limit, or a number (in MB). Set in ini prefs. global $my_name, $my_domain, $data_dir, $ini_path global $log_string, $log_location global $max_log_size = 0 ; 0 = no limit, or a number (in MB) global $monitors_list[1][5] $monitors_list[0][0] = 0 global $do_tooltips global $tip_icon = @ScriptFullPath & ",0" global $tip_style = 1 global $tooltip_time = 10000 ; For UpdateIniFile().. global $file_array, $new_array[1] ; Set to true during Send() operations [SendWait()] global $am_sending ; Associative arrays in AutoIt? Hells yeah! global $oMyError = ObjEvent("AutoIt.Error", "AAError") ; Initialize a COM error handler ; Initialize your array in your script.au3 ... ; global $associative_array ; AAInit($associative_array) ; *** don't forget to.. AAWipe($associative_array) ; Enable the creation of a list of user token, for save/recall.. global $known_user_tokens[1][2] ; Constants for Special Folders in Windows.. Const $Internet_Explorer = 0x1 Const $Programs = 0x2 Const $Control_Panel = 0x3 Const $Printers_and_Faxes = 0x4 Const $My_Documents = 0x5 Const $Favorites = 0x6 Const $Startup = 0x7 Const $My_Recent_Documents = 0x8 Const $SendTo = 0x9 Const $Recycle_Bin = 0xa Const $Start_Menu = 0xb Const $My_Music = 0xd Const $My_Videos = 0xe Const $Desktop = 0x10 Const $My_Computer = 0x11 Const $My_Network_Places = 0x12 Const $NetHood = 0x13 Const $Fonts = 0x14 Const $Templates = 0x15 Const $All_Users_Start_Menu = 0x16 Const $All_Users_Programs = 0x17 Const $All_Users_Startup = 0x18 Const $All_Users_Desktop = 0x19 Const $Application_Data = 0x1a Const $PrintHood = 0x1b Const $Local_Settings_Application_Data = 0x1c Const $All_Users_Favorites = 0x19 Const $Local_Settings_Temporary_Internet_Files = 0x20 Const $Cookies = 0x21 Const $Local_Settings_History = 0x22 Const $All_Users_Application_Data = 0x23 Const $Windows = 0x24 Const $System32 = 0x25 Const $Program_Files = 0x26 Const $My_Pictures = 0x27 Const $User_Profile = 0x28 Const $Common_Files = 0x2b Const $All_Users_Templates = 0x2e Const $Administrative_Tools = 0x2f Const $Network_Connections = 0x31 Const $CD_Burning_Folder = 0x003b ; OpenSpecialFolder($Recycle_Bin) .. func OpenSpecialFolder($Folder_ID) local $ShellObj = ObjCreate("Shell.Application") $ShellObj.Open($ShellObj.NameSpace($Folder_ID)) $ShellObj = 0 endfunc ; func GetSpecialFolderPath($Folder_ID) ; $ShellObj = ObjCreate("Shell.Application") ; $objFolder = $ShellObj.NameSpace($Folder_ID) ; $objFolderItem = $objFolder.ParseName("Desktop") ; $ret = $objFolder.GetDetailsOf($objFolderItem, 0) ; ; $ShellObj = 0 ; return $ret ; endfunc ; Generic File & Folder Opening function. ; ; If it's a file, opens the given file in the user's editor. ; If it's a directory, opens in Explorer. ; func OpenSomething($filepath, $use_log_viewer=false) debug("OpenSomething: =>" & $filepath & "<=" , @ScriptLineNumber, 7);debug if not FileExists($filepath) then debug($filepath & " not found!", @ScriptLineNumber, 1);debug return false endif if IsDir($filepath) then if not WinExists($filepath) then debug("Opening: =>" & $filepath & "<=" , @ScriptLineNumber, 7);debug Run("Explorer.exe """ & $filepath & '"') ;ShellExecute($filepath) else WinActivate($filepath) endif else local $user_editor = DeTokenizeString(IniRead($ini_path, $my_name, "editor", "notepad.exe")) if $use_log_viewer then local $log_viewer = DeTokenizeString(IniRead($ini_path, $my_name, "log_viewer", "")) if FileExists($log_viewer) then $user_editor = $log_viewer endif if not Run($user_editor & " " & $filepath) then debug("ERROR! I couldn't run:" & '"' & $user_editor & '"', @ScriptLineNumber, 7);debug debug("You need to check your ini settings! ", @ScriptLineNumber, 7);debug endif endif endfunc ; Functions that use it.. ; These are standard in all apps that use this library.. ; Open debug dump file.. func OpenDumpFile() OpenSomething($dump_file) endfunc ; User data dir.. func OpenDataDir() OpenSomething($data_dir) endfunc ; Edit ini prefs.. func EditIniFile() ;OpenSomething($ini_path) ShellExecute($ini_path) endfunc ; Open log file.. func OpenLogFile() ShellExecute($log_location) endfunc ; Display a ToolTip message slightly up from the mouse position.. ; pass $screen=true to place it instead at the centre-top of the screen. func DisplayTooltipMessage($message, $time=$DEF_MSG_TIME, $title=$my_name, $screen=false) ; $DEF_MSG_TIME = 2000 debug("", @ScriptLineNumber, 7);debug debug("DisplayTooltipMessage(" & $message & "," & $time & "," & $title & ")", @ScriptLineNumber, 7);debug local $x, $y if not $screen then local $mousepos = MouseGetPos() $x = $mousepos[0] $y = $mousepos[1]-16 else $x = (@DesktopWidth/2)-StringLen($message)*3 $y = 32 endif ToolTip($message, $x, $y, $title, 1) debug("Displaying Message: =>" & $message & "<=" , @ScriptLineNumber, 7);debug AdLibRegister("ClearMessage", $time) endfunc ; Clears the above message. func ClearMessage() debug("", @ScriptLineNumber, 7);debug debug("ClearMessage()", @ScriptLineNumber, 7);debug ToolTip("") AdLibUnRegister("ClearMessage") endfunc #cs Optional ToolTips Set a tooltip or don't, dependant on the global $do_tooltips variable, which you should set first, generally when gathering global prefs. This is a drop-in replacement for GUICtrlSetTip() and will happily work in this simple state. $options: these numbers can be added together.. 1 = Display as Balloon Tip 2 = Centre the tip horizontally under the control And so on. See below this function for more details. #ce func GUICtrlSetTipOptional($control_ID, $tip_text=default, $title=default, $icon=default, $options=default) if $do_tooltips = $OFF then return if $tip_text = default then $tip_text = "" if $title = default then $title = "Information:" if $icon = default then $icon = $tip_icon if $options = default then $options = $tip_style ; $options = BitOr($tip_style, $TTF_SUBCLASS, $TTF_IDISHWND, $TTF_PARSELINKS) ; $options = $tip_style local $style = 0, $hicon, $ret $control_ID = GUICtrlGetHandle($control_ID) if BitAND($options, 1) then $style = $TTS_BALLOON $style = BitOr($style, $TTS_ALWAYSTIP) local $hToolTip = _GUIToolTip_Create(0, $style) $options = BitOr($options, $TTF_SUBCLASS, $TTF_IDISHWND) _GUIToolTip_AddTool($hToolTip, 0, $tip_text, $control_ID, default, default, default, default, $options, 0) ; Time the pointer must remain stationary within a tool's bounding rectangle before the window appears. _GUIToolTip_SetDelayTime($hToolTip, $TTDT_INITIAL, 400) ; (500ms) ; Time the ToolTip window remains visible if the pointer is stationary within a tool's bounding rectangle. _GUIToolTip_SetDelayTime($hToolTip, $TTDT_AUTOPOP, $tooltip_time) ; (5000ms) ; Time it takes for subsequent ToolTip windows to appear as the pointer moves from one tool to another. _GUIToolTip_SetDelayTime($hToolTip, $TTDT_RESHOW, 150) ; (100ms) if not StringInStr($icon, ".") then _GUIToolTip_SetTitle($hToolTip, $title, $icon) else $hicon = DllStructCreate("ptr") $icon = StringSplit($icon, ",") if $icon[0] > 1 then $ret = DllCall("shell32.dll", _ "uint", _ "ExtractIconExW", _ "wstr", $icon[$icon[0] - 1], _ "int", -1 * (Int($icon[$icon[0]])), _ "ptr", 0, _ "ptr", DllStructGetPtr($hicon), _ "uint", 1) if not @error and $ret[0] then $hicon = DllStructGetData($hicon, 1) else $hicon = 0 endif _GUIToolTip_SetTitle($hToolTip, $title, $hicon) DllCall("user32.dll", "none", "DestroyIcon", "handle", $hIcon) endif endif return $hToolTip endfunc #cs [optional] Flags that control the ToolTip display: global Const $TTF_IDISHWND = 0x00000001 - Indicates that $iID is a window or control handle, instead of the ID of the tool global Const $TTF_CENTERTIP = 0x00000002 - Centers the tooltip below the control specified by $iID global Const $TTF_RTLREADING = 0x00000004 - Indicates that text will be displayed in opposite direction of the parent window (see remarks) global Const $TTF_SUBCLASS = 0x00000010 - Indicates that the control should subclass the tool's window global Const $TTF_TRACK = 0x00000020 - Positions the tooltip window next to the tool to which it corresponds global Const $TTF_ABSOLUTE = 0x00000080 - Positions the window at the same coordinates provided by TTM_TRACKPOSITION. (see remarks) global Const $TTF_TRANSPARENT = 0x00000100 - Causes the control to forward mouse messages to the parent window global Const $TTF_PARSELINKS = 0x00001000 - Indicates that links in the control text should be displayed as links global Const $TTF_DI_SETITEM = 0x00008000 Default = BitOr($TTF_SUBCLASS, $TTF_IDISHWND) _GUIToolTip_Create STYLE $TTS_ALWAYSTIP (0x01) - Indicates that the ToolTip control appears when the cursor is on a tool even if the ToolTip control's owner window is inactive. Without this style, the ToolTip appears only when the tool's owner window is active. $TTS_NOPREFIX (0x02) - Prevents the system from stripping the ampersand character from a string. Without this style the system automatically strips ampersand characters. This allows an application to use the same string as both a menu item and as text in a ToolTip control. $TTS_NOANIMATE (0x10) - Disables sliding ToolTip animation. $TTS_NOFADE (0x20) - Disables fading ToolTip animation. $TTS_BALLOON (0x40) - Indicates that the ToolTip control has the appearance of a cartoon "balloon" $TTS_CLOSE (0x80) - Displays a close icon so that the tooltip can be cancelled Default: $_TT_ghTTDefaultStyle = BitOr($TTS_ALWAYSTIP, $TTS_NOPREFIX) Icon idx.. [optional] Set to one of the values below:. $TTI_NONE (0) - No icon [default] $TTI_INFO (1) - Information icon $TTI_WARNING (2) - Warning icon $TTI_ERROR (3) - Error Icon $TTI_INFO_LARGE (4) - Large Information Icon $TTI_WARNING_LARGE (5) - Large Warning Icon $TTI_ERROR_LARGE (6) - Large Error Icon #ce ; Dynamic @Tokens.. ; ; ; There are 10 path tokens, 8 time tokens and 2 dimension tokens, as well as one ; clipboard token, one date token and lastly, user-definable variable tokens. ; ; The usual error checking has been omitted here - let the user have some fun! ; func DeTokenizeString($string, $inipath=$ini_path, $section=$my_name, $pref="date_format") debug("", @ScriptLineNumber, 7);debug debug("DeTokenizeString(" & $string & ")", @ScriptLineNumber, 7);debug if not $string then return $string if not StringInStr($string, "@") then return $string ; Replace user @tokens first (they may contain other tokens) $string = DeUserTokenizeString($string) ; If not, return the string now.. if not StringInStr($string, "@") then return $string ; Special @ClipBoard @Token.. $string = StringReplace($string, "@ClipBoard", ClipGet()) ; Date/Time @tokens.. $string = DeTokenizeTimeStrings($string) $string = ReplaceDateTimeToken($string) $string = ReplaceDateToken($string, $inipath, $section, $pref) ; Path @tokens.. ; We still replace these when $path=false $string = ReplacePathToken($string) debug("DeTokenizeString() RETURNING: =>" & $string & "<=", @ScriptLineNumber, 7);debug return $string endfunc func DeTokenizeTimeStrings($string) $string = StringReplace($string, "@MSec", @MSec) $string = StringReplace($string, "@Sec", @Sec) $string = StringReplace($string, "@Min", @Min) $string = StringReplace($string, "@Hour", @Hour) $string = StringReplace($string, "@MDay", @MDay) $string = StringReplace($string, "@Mon", @Mon) $string = StringReplace($string, "@Year", @Year) $string = StringReplace($string, "@WDay", @WDay) $string = StringReplace($string, "@YDay", @YDay) $string = StringReplace($string, "@Time", _NowTime()) return $string endfunc func ReplaceDateToken($string, $inipath=$ini_path, $section=$my_name, $pref="date_format") $string = StringReplace($string, "@Date", GetUserDate($inipath, $section, $pref)) return $string endfunc ; DateTime0 >> DateTime5 func ReplaceDateTimeToken($string) local $test = StringRegExp ($string, "(@DateTime([0-5]))", $STR_REGEXPARRAYMATCH) if IsArray($test) and $test[0] and $test[1] then local $datetime = _DateTimeFormat(_NowCalc(), Int($test[1])) $string = StringReplace($string, $test[0], $datetime) endif return $string endfunc ; We may be inside DeTokenizeString() here.. func GetUserDate($inipath=$ini_path, $section=$my_name, $pref="date_format") return DeTokenizeTimeStrings(IniRead($inipath, $section, $pref, @Year & "-" & @Mon & "-" & @Mday)) endfunc func ReplacePathToken($string) if $data_dir <> "" then $string = StringReplace($string, "@DataDir", $data_dir) $string = StringReplace($string, "@ScriptsDir", $data_dir & "\Scripts") endif $string = StringReplace($string, "@Documents", @MyDocumentsDir) $string = StringReplace($string, "@MyDocuments", @MyDocumentsDir) $string = StringReplace($string, "@MyDocumentsdir", @MyDocumentsDir) $string = StringReplace($string, "@Desktop", @DesktopDir) $string = StringReplace($string, "@TempDir", @TempDir) $string = StringReplace($string, "@ThisApp", @ScriptFullPath) $string = StringReplace($string, "@KeyBind", @ScriptFullPath) $string = StringReplace($string, "@Me", @UserName) $string = StringReplace($string, "@User", @UserName) $string = StringReplace($string, "@UserName", @UserName) $string = StringReplace($string, "@ConfigEditor", GetParent(@ScriptFullPath) & "\" & $my_name & "Config.exe") $string = StringReplace($string, "@HomeDir", @HomeDrive & @HomePath) $string = StringReplace($string, "@HomeDrive", @HomeDrive) $string = StringReplace($string, "@HomePath", @HomePath) $string = StringReplace($string, "@ProgramFiles", @ProgramFilesDir) $string = StringReplace($string, "@UserDir", @UserProfileDir) $string = StringReplace($string, "@UserProfileDir", @UserProfileDir) ; $string = StringReplace($string, "@outputfile", $outputfile) return $string endfunc ; ; Debugging is like particles and waves. With a shitload of debugging lines, you ; can't read the code, but you can read the debug output OK. It's code or debug ; output, never both at once (unless you leave your debug output open and then ; remove the debug lines to study both, but hey! It's nice philosophy!). ; ; User @tokens. ; ; 16 AlphaNumeric Characters Maximum. ; ; User variables will be named "var_VARIABLE_NAME" ; They will be declared using Assign(), with the Global flag. ; ;2do.. dumb - doesn't know there are no user @tokens. or what @token are starndard @token ;2do - take this out of main Detokenize and call separately when required. ; func DeUserTokenizeString($string) debug("", @ScriptLineNumber, 7);debug debug("DeUserTokenizeString(" & $string & ")", @ScriptLineNumber, 7);debug debug_PrintArray($known_user_tokens, "cel.au3 :: $known_user_tokens:", @ScriptLineNumber, 7);debug if not StringInStr($string, "@") then return $string local $this_token, $maybe_token local $split_string = StringSplit($string, "@") for $i = 2 to $split_string[0] ; first element is /definitely/ not a @token. $this_token = "" $maybe_token = $split_string[$i] debug("$maybe_token: =>" & $maybe_token & "<=", @ScriptLineNumber, 7);debug ; Remove everything after the alphanumerics and underscores.. $this_token = StringRegExpReplace($maybe_token, "(\w+).*", "\1", 1) debug("Test $this_token: =>" & $this_token & "<=", @ScriptLineNumber, 7);debug ; We got the length of the first Alphanumeric string. ; Now test if that is a valid @token.. ; This @token assigned already (we double-check here).. if InArray2D($known_user_tokens, $this_token, 0) and IsDeclared ("var_" & $this_token) then debug("SUCCESS!! Found USER Variable: =>@" & $this_token & "<=", @ScriptLineNumber, 7);debug ; Replace the @token with the user's variable value.. local $token_val = Eval("var_" & $this_token) debug("Assign USER Value: " & $this_token & " => " & $token_val & "<=", @ScriptLineNumber, 7);debug $split_string[$i] = StringReplace($maybe_token, $this_token, $token_val) else ; no var of that name assigned., or empty ("@@")!!. debug("No Such User Token as @" & $this_token & "!", @ScriptLineNumber, 7);debug ; Continue on, use it as-is (was) replacing the @ we took.. $split_string[$i] = "@" & $maybe_token endif next ; 2do : check changes to CRT() have not impacted ArrayJoin() with empty delimiter. TEST! ; ; Pop all the pieces back together again.. debug_PrintArray($split_string, "cel.au3 :: $split_string:", @ScriptLineNumber, 7);debug $string = ArrayJoin($split_string, "") debug("DeUserTokenizeString() RETURNING: =>" & $string & "<=", @ScriptLineNumber, 7);debug return $string endfunc ; Tokenize a string (create macro tokens). ; Start with longest paths.. ; func TokenizeString($string, $path=true) if not $string then return $string if $path then $string = FixPathSlashes($string) if $data_dir <> "" then $string = StringReplace($string, $data_dir & "\Scripts", "@ScriptsDir") $string = StringReplace($string, $data_dir, "@DataDir") endif $string = StringReplace($string, @DesktopDir, "@Desktop") $string = StringReplace($string, @MyDocumentsDir, "@MyDocuments") $string = StringReplace($string, @HomeDrive & @HomePath, "@HomeDir") $string = StringReplace($string, @UserProfileDir, "@UserDir") $string = StringReplace($string, @TempDir, "@TempDir") $string = StringReplace($string, @ScriptFullPath, "@ThisApp") $string = StringReplace($string, @ProgramFilesDir, "@ProgramFiles") return $string endfunc ; Fix potentially messed-up slashes.. func FixPathSlashes($string) if StringInStr($string, "://") then return $string ; but not for URLs ; Watch out! We don't want to "fix" flags, like: del /f /q "C:\some/path\*.*" $string = StringRegExpReplace($string, "(.+)([^ ])/", "\1\2\\") $string = StringReplace($string, "\\", "\") return $string endfunc ; Conditional Right/Left Trim ; ; If the far-right character(s) is(are) such-and-such, remove it(them). ; Handy for normalizing path ends and other stuff. ; ; Because we need this sort of thing quite a lot.. ; ; if StringRight($string, 1) = "\" then $string = StringTrimRight($string, 1) ; ; Functions work on the string byref; you simply do: ; ; CRT("my string") ; ; The idea of the names is; quick to type. ; ; These functions return a positive integer if any changes were made, the ; integer being the number of changes performed. Otherwise 0, so you can ; optionally set a variable from their return value.. ; ; $contains_modifier = CRT("my string") ; ; or use them in conditional statements.. ; ; if CRT("my string") then ... ; ; So.. func CRT(byref $string, $character="\") local $ret = 0, $char_num = StringLen($character) if StringRight($string, $char_num) == $character then while StringRight($string, $char_num) == $character $ret += 1 $string = StringTrimRight($string, $char_num) wend endif return $ret endfunc ; And for the left-hand side.. ; The default character here is a space.. func CLT(byref $string, $character=" ") local $ret = 0, $char_num = StringLen($character) while StringLeft($string, $char_num) == $character $ret += 1 $string = StringTrimLeft($string, $char_num) wend return $ret endfunc ; And now both together.. ; Note different default character. ; This double-function wrapper is mostly used for prefs lists. ; ; You can, however, send your own replacement character(s).. ; ; Either specify one character to use it for both left and right, ; or specify both left and right characters. ; func CBT(byref $string, $character_left=default, $character_right=default) if $character_left = default then $character_left = "," if $character_right = default then $character_right = $character_left local $ret = 0 $ret += CLT($string, $character_left) $ret += CRT($string, $character_right) return $ret endfunc ; Strip off any leading white space and pad with exact number of <$pad_string>. ; Used to separate parameters on the command-line (we add a space " "). ; func PadLeft($string, $pad_string=" ", $number=1) $string = StringStripWS($string, 1) $string = _StringRepeat($pad_string, $number) & $string return $string endfunc ; Test if a file can be written to a location.. ; func TestFileWrite($tmpfile) local $t = FileWrite($tmpfile, "") if $t <> 1 then return false FileDelete($tmpfile) return true endfunc ; BubbleSort() ; ; A very basic, but very handy array sort. ; Designed for small lists; menus and such-like, where it excels. ; Purist can kiss my butt, this is simple, and elegant. ; ; NOTE: this is for "AutoIt Arrays", where the first value is ; the total number of elements. Basically, it will be left as-is. ; Also note, this is a case-insensitive search. ; ; To use.. BubbleSort($my_array) ; func BubbleSort(byref $bs_array) for $i = uBound($bs_array)-1 to 1 step -1 for $j = 2 to $i if $bs_array[$j-1] > $bs_array[$j] then local $temp = $bs_array[$j-1] $bs_array[$j-1] = $bs_array[$j] $bs_array[$j] = $temp endif next next return $bs_array endfunc ; ; By the way, it should be noted that I have no idea why this works. ; Technically, using strings as numbers in AutoIt should implicitly call ; Number() and all "words" would be 0. But it does work, and works great! ; Hmmm. ; InsertionSort() ; ; Slightly different results, here. ; Simple algo, good for lists of numbers, and pretty fast, too.. ; func InsertionSort(byref $is_array) for $i = 1 to uBound($is_array)-1 local $index = $is_array[$i] local $j = $i while $j > 1 and $is_array[$j-1] > $index $is_array[$j] = $is_array[$j-1] $j -= 1 wend $is_array[$j] = $index next return $is_array endfunc ; mail me if you want an AutoIt version of the QuickSort algo ; ShellSort() ; Invented by Donald Shell, 1959. ; ; More efficient than a BubbleSort. ; Good for repetative sorting of smaller lists. ; Neck-and-neck with InsertionSort in most of my tests. ; ; Note: This is designed for "AutoIt Arrays" (first element it the total). ; func ShellSort(byref $some_array) local $increment = 1 while $increment > 0 for $i = 2 to uBound($some_array)-1 local $j = $i local $temp = $some_array[$i] while $j >= $increment and $some_array[$j-$increment] > $temp $some_array[$j] = $some_array[$j-$increment] $j = $j - $increment wend $some_array[$j] = $temp next if $increment/2 <> 0 then ; ? $increment = int($increment/2) elseif $increment = 1 then $increment = 0 else $increment = 1 endif wend return $some_array endfunc ; MaxMax() ; ; Evaluates two or three numbers and returns the highest. ; Because _Max($a,(_Max($b,$c)) is just plain ugly. ; func MaxMax($num1, $num2, $num3=1.7E-308) if not IsNumber($num1) or not IsNumber($num2) or not IsNumber($num3) then return if $num1 > $num2 then if $num3 > $num1 then return $num3 return $num1 else if $num3 > $num2 then return $num3 return $num2 endif endfunc ; MinMin() ; ; Evaluates two or three numbers and returns the smallest. ; func MinMin($num1, $num2, $num3=1.7E+308) if not IsNumber($num1) or not IsNumber($num2) or not IsNumber($num3) then return if $num1 > $num2 then if $num3 < $num2 then return $num3 return $num2 else if $num3 < $num1 then return $num3 return $num1 endif endfunc ; String format, a-la C.. ; func printf($format, $var1, $var2=-1, $var3=-1) if $var2=-1 then return StringFormat($format, $var1) else return StringFormat($format, $var1, $var2, $var3) endif endfunc ; Repeats a given string a given number of times.. ; func StringRepeat($string, $count) $count = Int($count) if not $count then return "" if not StringLen($string) then return SetError(-1, 0, "Invalid Parameters sent.") local $return while $count $return &= $string $count -= 1 wend return $return endfunc ; A pipe is the delimiter used in ListViews, to separate columns. ; Obviously, literal pipes in our ListViews would cause all sorts of issues. ; ; So, when adding them to the ListView, we translate them into this identical- ; looking Unicode character. And back again when pulling them out. Simple. ; ; This is all completely transparent to the user, unless they happen across ; these comments somehow, in which case the game is up and I'm sure they will be ; absolutely furious. ; ; On Hebrew systems it probably shows up as a Star of David and then the joke is ; on me. ; ; These two functions are for when, for some reason, we can't do.. ; ; AutoItSetOption("GUIDataSeparatorChar", "") ; A Record Separator, Chr(30). ; ; FYI, good ole ASCII provides.. ; ; Chr(28):  File separator ; Chr(29):  Group separator ; ; ..in addition to the most appropriate separator for ListViews.. ; ; Chr(30):  Record separator ; ; By the way, if you /don't/ see a cute box with "RS" in it (or similar cute ; character), I can only assume you are using some piece-of-shit text editor not ; fit to view this code. In that case, go upgrade to something decent, eh! ; Notepad++ is free! >> https://notepad-plus-plus.org/ ; func Str2LV($string) return StringReplace($string, "|", "ǀ") ; ǀ <> | ! [U+01C0] endfunc func LV2Str($string) return StringReplace($string, "ǀ", "|") endfunc ; ; NOTE: If you grab a task from the ListView in your code and forget to use this ; translations, you will be in for a debugging nightmare trying to figure out ; why "ǀfoo" is not equal to "|foo" when, you know, they LOOK THE SAME ... ; CleanPath() ; ; Clean-up potentially problematic file path characters.. ; func CleanPath($string, $chr="~") ; $string = StringReplace($string, " ", "_") $string = StringReplace($string, "|", $chr) $string = StringReplace($string, '"', "'") $string = StringReplace($string, ":", $chr) $string = StringReplace($string, "*", $chr) $string = StringReplace($string, "/", $chr) $string = StringReplace($string, "\", $chr) $string = StringReplace($string, ">", $chr) $string = StringReplace($string, "<", $chr) $string = StringReplace($string, "?", $chr) return $string endfunc ; CleanPrefName() ; ; Make a string safe to use in an ini [section pref name].. ; func CleanPrefName($string, $translate_spaces=true) $string = CleanPath($string) if $translate_spaces then $string = StringReplace($string, " ", "_") $string = StringReplace($string, '"', "_") $string = StringReplace($string, "'", "_") $string = StringReplace($string, "=", "_") $string = StringReplace($string, "[", "_") $string = StringReplace($string, "]", "_") $string = StringReplace($string, "(", "_") $string = StringReplace($string, ")", "_") $string = StringReplace($string, ".", "_") $string = StringReplace($string, ",", "_") $string = StringReplace($string, "-", "_") return $string endfunc ; BaseName() ; ; Get the base name of a file from a full path.. ; In other words; returns the path name without the folders part (ie. file name only) func BaseName($bn_path) $bn_path = StringReplace($bn_path, "/", "\") CRT($bn_path) local $parts = StringSplit($bn_path, "\") local $bn_tmp = $parts[$parts[0]] CRT($bn_tmp, ":") return $bn_tmp endfunc ; GetParent() ; ; Returns the parent directory of a given file or directory path.. func GetParent($gp_dir) local $gp_full_path = StringSplit($gp_dir, "\") ; array return StringTrimRight($gp_dir, StringLen($gp_full_path[$gp_full_path[0]]) + 1) ; 1 = "\" endfunc ; GetExtension() ; ; Returns the extension of a file name, e.g. "txt" ; If the file has no extension, returns a blank "" string func GetExtension($some_name) local $parts = StringSplit($some_name, ".") local $e = $parts[$parts[0]] ; "." was not found - extensionless file, possibly in a path with a dot.. if $e <> $some_name and not StringInStr($e, "\") then return $e else return "" endif endfunc ; RemoveExtension() ; ; Removes the extension of a file name (including the dot ".") ; Requires the above functions. ; Also works for folders. ; func RemoveExtension($some_name) local $add = 0 if StringInStr(BaseName($some_name), ".") then $add = 1 ; might not have an extension return StringTrimRight($some_name, StringLen(GetExtension($some_name)) + $add) endfunc ; CleanName() ; ; Returns a file name minus the path AND the extension. ; Basically does two of the above functions, all-in-one.. ; func CleanName($some_name) return RemoveExtension(BaseName($some_name)) endfunc ; SimpleProper() ; ; Very simple version of StringProper ; Capitalizes the first letter of a given ASCII string. ; func SimpleProper($string) local $first_chr = Asc(StringLeft($string, 1)) if $first_chr < 97 or $first_chr > 122 then return $string $string = Chr($first_chr-32) & StringMid($string, 2) return $string endfunc ; A2RBool() ; ; Convert my AutoIt boolean ($ON=1,$OFF=4) to regular boolean (on=1,off=0) ; Handy for converting prefs to functions that require regular normal booleans, ; e.g.. ; ; WinSetOnTop($GUI, "", A2RBool($always_on_top)) ; ; Basically converts 4 into 0 and anything else into 1. ; func A2RBool($autoit_boolean) if $autoit_boolean == $OFF then return 0 return 1 endfunc ; MakeTheParents() ; ; If the parent directories of a file do not exist, create them.. ; func MakeTheParents(byref $file_path) if not FileExists(GetParent($file_path)) then DirCreate(GetParent($file_path)) endif endfunc ; MakeAFile() ; ; If a file does not exist, create it.. ; func MakeAFile(byref $file_path) if not FileExists($file_path) then local $target_file = FileOpen($file_path, 2) FileClose($target_file) endif endfunc #cs AppendFileData() Append the contents of $data_file to the end of $target_file.. $flags are the usual FileOpen flags, which apply to opening $data_file. Obviously you don't want to send any WRITE flags. Nincompoop! But this is handy for forcing binary reading, or whatever.. Useful flags: $FO_READ (0) = Read mode (default) (Auto-Detects Encoding) $FO_BINARY (16) = Force binary (byte) data mode. $FO_UNICODE or $FO_UTF16_LE (32) = Use Unicode UTF16 Little Endian reading and writing mode. $FO_UTF16_BE (64) = Use Unicode UTF16 Big Endian reading and writing mode. $FO_UTF8 (128) = Use Unicode UTF8 (with BOM) reading and writing mode. $FO_UTF8_NOBOM (256) = Use Unicode UTF8 (without BOM) reading and writing mode. $FO_ANSI (512) = Use ANSI reading and writing mode. $FO_UTF16_LE_NOBOM (1024) = Use Unicode UTF16 Little Endian (without BOM) reading and writing mode. $FO_UTF16_BE_NOBOM (2048) = Use Unicode UTF16 Big Endian (without BOM) reading and writing mode. $FO_FULLFILE_DETECT (16384) = When opening for reading and no BOM is present, use the entire file to determine if it is UTF8 or UTF16. If this is not used then only the initial part of the file (up to 64KB) is checked for performance reasons. #ce func AppendFileData($target_file, $data_file, $flags=0) $data_file = FileOpen($data_file, $flags) local $file_data = FileRead($data_file) FileClose($data_file) $target_file = FileOpen($target_file, 1) local $return = FileWrite($target_file, $file_data) FileClose($target_file) return $return endfunc ; GetWinDrive() ; ; Returns the parent DRIVE of a given path.. ; ; "I:\temp\test\musk.mp3" >> returns: I ; ; Invalid (or UNC) paths return an empty string. ; func GetWinDrive($gd_path) select case StringMid($gd_path, 2, 1) == ":" return StringLeft($gd_path, 1) case else return "" endselect endfunc ; LnkToReal() ; ; Convert shortcut to its real target path. ; If link is invalid, returns false. ; If file path sent is not a .lnk file, returns the path that was sent. ; So you can safely insert it into any user's path choosing operation. ; func LnkToReal($file) if GetExtension($file) = "lnk" then local $lnk_arr = FileGetShortCut($file) if IsArray($lnk_arr) and FileExists($lnk_arr[0]) then return $lnk_arr[0] else return $file endif return false endfunc ; DateToDayOfWeekISO all-in-one.. ; func DateToDayOfWeekISO($iYear, $iMonth, $iDay) local $i_aFactor, $i_yFactor, $i_mFactor, $i_dFactor $i_aFactor = Int((14 - $iMonth) / 12) $i_yFactor = $iYear - $i_aFactor $i_mFactor = $iMonth + (12 * $i_aFactor) - 2 $i_dFactor = Mod($iDay + $i_yFactor + Int($i_yFactor / 4) - Int($i_yFactor / 100) _ + Int($i_yFactor / 400) + Int((31 * $i_mFactor) / 12), 7) if $i_dFactor >= 1 then return $i_dFactor - 1 return 6 endfunc ; For use in logs, etc.. ; func DateTimeString($msec=false, $sec=true, $time=true) local $addm, $adds if $time then $time = " @ " & @Hour & "." & @Min if $sec then $adds = ":" & @Sec if $msec then $addm = "." & @Msec return @Year & "-" & @Mon & "-" & @Mday & $time & $adds & $addm endfunc ; For backup files, etc.. ; func FileDateStamp() return @Year & "-" & @Mon & "-" & @Mday & "@" & @Hour & "." & @Min endfunc ; FolderIsEmpty() ; ; Empty the folder is? ; ; Returns 0 is folder is not empty ; Returns 1 if the given folder path is empty ; Returns 2 if the path does not exist ; func FolderIsEmpty($fie_folder) if not FileExists($fie_folder) then return 2 local $ret = 0 local $fie_search_files = FileFindFirstFile($fie_folder & "\*.*") if $fie_search_files = -1 then ; No files! Good! if @error = 1 then $ret = 1 else $ret = 2 endif endif FileClose($fie_search_files) return $ret endfunc func IsWild($string) if StringInStr($string, "*") or StringInStr($string, "?") then return true return false endfunc ; Check if a string is a directory path string and if so, add standard wildcards.. ; If the supplied path is valid, return true, otherwise false. ; func CheckDirWild(byref $pathstring) if IsDir($pathstring) and not IsWild($pathstring) then $pathstring &= "\*" endif local $testfiles = FileFindFirstFile($pathstring) if $testfiles = -1 then return false return true endfunc ; IsDir() ; ; Is the given path a directory? func IsDir($some_path) ; simple but slow.. ; (although the fastest of all the methods I've tried - a lot) return StringInStr(FileGetAttrib($some_path), "D") ;, 2 = slower! endfunc ; ReadDir() ; ; Open a folder and return files with a particular $extension (no "." dot) ; as an array of file names. See RecurseDir() (below) for ; more functionality. ; ; NO Wild-Cards Allowed. ; ; Alternatively, supply full file name. Wilcards allowed. func ReadDir($folder, $extension, $full_filename="") ; AutoIt array handling is basic, to say the least! local $files[1] local $new_array[2] local $filename = "*." if $full_filename then $filename = $full_filename $extension = "" else CLT($extension, ".") endif local $init_dir = $folder & "\" & $filename & $extension ; Create a "search handle" of all the *.$extension files in the folder local $search_files = FileFindFirstFile($init_dir) if $search_files = -1 then FileClose($search_files) $search_files = FileFindFirstFile($init_dir) endif local $i = 1 do local $tmp = FileFindNextFile($search_files) $files[$i-1] = $tmp $i += 1 ; like php, same as $i = $i + 1 redim $files[$i] until @error FileClose($search_files) ; close the search handle ; This removes the extraneous/empty elements from the array $i = 2 for $this_file in $files local $entry = StringStripWS($this_file, 3) if $entry then redim $new_array[$i] $new_array[0] = $i-1 $new_array[$i-1] = $entry $i = $i + 1 endif next ; Wipe this array.. $files = 0 if $new_array[0] = "" then return 0 ; Return the array of filenames.. return $new_array endfunc ; ; RecurseDir() v2.3 ; ; Recursively search a directory structure for files matching a pattern ; and return its files as an array of file paths, the first value being the ; total number of file paths in the array (a-la "AutoIt Array"). ; ; I spent some time testing many different routines. _GetFileList, by Jos van ; der Zande, always gave me the best results, and nicely coded, but around ten ; times slower (52s) than Larry (and Beerman's) recursion routines (4.9s) when ; recursing my home folder.** ; ; ** 1000 folders, 4773 files, 702MB. [cpu:1.3GHz, 640MB RAM] at time of writing ; ; This function is based on _GetFileList, but after a few hacks and tweaks is now ; more than fifteen times faster than the original.** The results are still as good, ; but instead of 50+ seconds to recurse my home folder, it now takes 3.3 seconds, ; making it fastest and bestest of all the AutoIt recursion routines! *tic* ; ; Note: you can now supply multiple file masks (needed for backup). It makes a lot ; of sense to grab any other extensions while we are in a directory. ; The delimiter is a comma.. ; ; RecurseDir("C:\Program Files", "*.reg,*.ini,*.cfg") ; ; When searching for multiple masks the speed improvements are *staggering*, and ; logarithmic; basically multiply the number of masks. For instance, a backup of ; all the pref files in my Program Files folder is scanned, copied, zipped and ; completed in around a minute. pretty good, considering it's over 12GB; all ; tools, no big game installs, and ten file masks to search. ; ; The optional third parameter "$top_level_only" tells RecurseDir() to only ; return matches for files in the top level directory, no deeper. (true/false) ; see also ReadDir() above. ; ; You can also supply an optional fourth parameter which is a string; the path to ; a "dump file" to dump (log) the paths of all matched files; for debugging only, ; because it will slow things down some. ; ; In v2.2 you can also supply an optional fifth parameter, "$return_dirs" which ; will do exactly that, returning an AutoIt array of all the directories in the ; path, and *only* the directories. (true/false) ; ; The optional 6th parameter ($max) is the maximum limit for returned paths, ; which is normally 1,000,000 (one million). Bigger sizes use more memory, roughly ; 10MB per million (for the initial *empty* array - before it gets filled with ; values). The absolute maximum size for an array is around 8,388,606, so don't ; go above that, or you will get errors. Also, ensure this value is never zero. ; ; This function gets used a lot in my apps. ; ; ** A lot to do with using the "&=" operator. Those wee differences mount up. ; Probably that operator wasn't available when the code was first written. ; ;global $quit = false func RecurseDir($dir, $mask, $top_level_only=false, $dump="", $return_dirs=false, $mx=1000000) local $n_dirnames[$mx] ; Maximum number of directories which can be scanned. local $n_dircount = 0 ; ^ Could be set much higher, if required. local $n_file local $n_search local $n_tfile local $file_array local $filenames ; local $filecount local $dircount = 1 ; if there was an "\" on the end of the given directory, remove that.. CRT($dir) debug("$dir: =>" & $dir & "<=", @ScriptLineNumber, 7);debug $n_dirnames[$dircount] = $dir if not FileExists($dir) then return 0 ; Keep on looping until all directories are scanned.. while $dircount > $n_dircount ; if $quit = 1 then return $n_dircount += 1 $n_search = FileFindFirstFile($n_dirnames[$n_dircount] & "\*.*") if @Error then debug("@Error: =>" & @Error & "<=", @ScriptLineNumber, 7);debug debug("$n_search: =>" & $n_search & "<=", @ScriptLineNumber, 7);debug ; Find all subdirs in this directory and store them in a array.. while true $n_file = FileFindNextFile($n_search) if @Error then exitloop ; Skip directory references.. if $n_file = "." or $n_file = ".." then continueloop $n_tfile = $n_dirnames[$n_dircount] & "\" & $n_file ; If it's a directory, add it to the list of directories to be processed.. if StringInStr(FileGetAttrib($n_tfile ), "D") and not $top_level_only then $dircount += 1 $n_dirnames[$dircount] = $n_tfile endif wend FileClose($n_search) ; Multiple masks.. if StringInStr($mask, ",", 2) then local $mask_array = StringSplit($mask, ",") else ; or else create a dummy array.. local $mask_array[2] = [1, $mask] endif ; Loop through the array of masks.. for $mask_c = 1 to $mask_array[0] ; Find all files that match this mask.. $n_search = FileFindFirstFile($n_dirnames[$n_dircount] & "\" & $mask_array[$mask_c] ) if $n_search = -1 then continueloop while true $n_file = FileFindNextFile($n_search) if @Error then exitloop ; end of dir if $n_file = "." or $n_file = ".." then continueloop $n_tfile = $n_dirnames[$n_dircount] & "\" & $n_file if not StringInStr(FileGetAttrib( $n_tfile ), "D") then ; $filecount += 1 $filenames &= $n_tfile & @LF endif wend FileClose($n_search) next wend ; Flip to a string and back to remove extraneous entries. ; This is much quicker than redimming on every loop. if $return_dirs then local $tmp_str = "" local $i = 1 while $n_dirnames[$i] <> "" $tmp_str &= $n_dirnames[$i] & "|" $i += 1 wend $tmp_str = StringTrimRight($tmp_str, 1) $n_dirnames = StringSplit($tmp_str, "|") return $n_dirnames endif $filenames = StringTrimRight($filenames, 1) if $filenames = "" then return 0 $file_array = StringSplit($filenames, @LF) ; Dump results to a file.. if $dump then local $dumpfile = FileOpen($dump, 2) FileWrite($dumpfile, $filenames) FileClose($dumpfile) endif return($file_array) endfunc #cs IniReadCheckBoxValue() Slightly altered for BlobDrop and its "tristate" checkboxes.. This function "transforms" an AutoIt or human unchecked value (4 or 0, respectively), into plain old 4, which AutoIt can understand. this function is intended as a drop-in replacement for the IniRead command, simply replace the function name. Of course, it's only useful when reading checkbox values, e.g.. $big_switch = IniReadCheckBoxValue($ini_path, $my_name, "big_switch", $GUI_UNCHECKED) However I've gotten into the habit of using $GUI_CHECKED and $GUI_UNCHECKED as general booleans, which has proven to be very effective, especially when coupled with these two functions. I have them set to $ON and $OFF. global const $ON = $GUI_CHECKED ; 1 global const $OFF = $GUI_UNCHECKED ; 4 Why? Windows uses 1 as the value for checked checkboxes, and 4 as the value for unchecked checkboxes.* This makes passing the values directly in and out of ini files undesirable, because "4" is not a logical value, and most humans would expect it to be 0 (zero). The following two functions act as interface between the program and the ini file, making sense of the "human" equivalents. Other "human" values are also understood, just in case. Using these custom booleans enables us to pass values directly back-and- forth between user settings and GUI Controls and tray menu items DIRECTLY, e.g.. TrayItemSetState($tray_menu, $some_pref) #ce func IniReadCheckBoxValue($rcbv_inifile, $rcbv_section, $rcbv_key, $rcbv_default, $three_state=false) ; IF key NOT FOUND, returns DEFAULT ; IF key BLANK (empty) returns INTERMEDIATE local $ircbv_val = IniRead($rcbv_inifile, $rcbv_section, $rcbv_key, "---") if $ircbv_val = "---" then $ircbv_val = $rcbv_default if $three_state and $ircbv_val = "" then return $GUI_INDETERMINATE switch $ircbv_val case $GUI_UNCHECKED ; 4 return $GUI_UNCHECKED case "false", "off", "no", "not", "nope", "nay", "nay!", "nah", "nah!", "no way!", _ "no sir!", "negative", "neg", "no!", "disable", "disabled" return $GUI_UNCHECKED case "true", "on", "yes", "yes!", "yay", "yay!", "yup", "hell yes!", "indeed", _ "yes sir!", "yessir!", "affirmative", "cool", "enable", "enabled" return $GUI_CHECKED case "2", 2, "unset", "-", "maybe" return $GUI_INDETERMINATE case "0" return $GUI_UNCHECKED case "1", $GUI_CHECKED ; 1 return $GUI_CHECKED case else ; some special value return $ircbv_val endswitch endfunc ; IniWriteCheckBoxValue() ; ; This function transforms an AutoIt checkbox value into a 'human' unchecked value (4 into 0, basically) ; this is intended as a drop-in replacement for the IniWrite command, simply replace the function name. ; Of course, it's only useful when writing checkbox values that will be read by 'IniReadCheckBoxValue' ; above. Instead of 0, you can also write "no", "off", or whatever, by passing the optional 5th parameter.. func IniWriteCheckBoxValue($wcbv_inifile, $wcbv_section, $wcbv_key, $wcbv_val, $tru_val="true", $fal_val="false") debug("IniWriteCheckBoxValue() : "&$wcbv_inifile&" : "&$wcbv_section&" : "&$wcbv_key&" : "&$wcbv_val, @ScriptLineNumber, 8);debug switch $wcbv_val case $GUI_CHECKED ; 1 $wcbv_val = $tru_val case $GUI_UNCHECKED ; 4 $wcbv_val = $fal_val case $GUI_INDETERMINATE ; 2 $wcbv_val = "" endswitch if $wcbv_val then IniWrite($wcbv_inifile, $wcbv_section, $wcbv_key, $wcbv_val) else ; We delete empty values - then they are "unset" proper! IniDelete($wcbv_inifile, $wcbv_section, $wcbv_key) endif endfunc ; The above functions are useful until you create a proper preferences interface for your application! ; actually, I tend to use $GUI_CHECKED and $GUI_UNCHECKED as general-purpose booleans these days. func ProcessReadHumanCheckBoxValue($some_string) switch $some_string case $OFF ; 4 return $OFF case "false", "off", "n", "no", "not", "nope", "nay", "nay!", "nah", "nah!", "no way!", "no sir!", "negative", "neg", "no!" return $OFF case "true", "on", "y", "yes", "yes!", "yay", "yay!", "yup", "hell yes!", "indeed", "yes sir!", "yessir!", "affirmative", "cool" return $ON case "0" return $OFF case $ON ; 1 return $ON case else ; one last try for positive! .. if StringLeft($some_string, 1) = "y" then return $ON else return $OFF endif endswitch endfunc ; func ProcessWriteHumanCheckBoxValue($some_string) ; switch $some_string ; case $ON ; return "enabled" ; case $OFF ; return "disabled" ; case else ; return $some_string ; endswitch ; endfunc ; For display purposes.. func ProcessWriteHumanCheckBoxValue($some_string, $on_str=$str_enabled, $off_str=$str_disabled, $indet_str="unset") switch $some_string case $ON return $on_str case $OFF return $off_str case $GUI_INDETERMINATE, "" return $indet_str case else return $some_string endswitch endfunc ; Alias.. func Human($some_string, $on_str=$str_enabled, $off_str=$str_disabled,$indet_str="unset") return ProcessWriteHumanCheckBoxValue($some_string, $on_str, $off_str, $indet_str) endfunc ; ; IniKeyExists() ; ; Feed it a 2-dimensional array (as supplied by IniReadSeaction) ; if the key exists, IniKeyExists() returns its value; if not, it returns false. ; The search is case-insensitive, but otherwise must be an exact (not partial) match. ; sometimes handy. ; func IniKeyExists(byref $search_array, $search_string) if not IsArray($search_array) then return false endif for $i = 1 to $search_array[0][0] if $search_string = $search_array[$i][0] then return $search_array[$i][1] endif next return false endfunc ; Simply creates an empty ini section you can later fill.. ; func CreateEmptyIniSection($inipath, $inisection) IniWrite($inipath, $inisection, "", "") IniDelete($inipath, $inisection, "") endfunc #cs UpdateIniFile() Add any new prefs from our master ini file. Keep all user's old prefs (see forced_settings for exceptions). Optionally clean out all info comments from new ini file. Optionally copy certain sections "RAW". UpdateIniFile([clean comments {BOOL}[, forced prefs {STRING(comma-delimited list)}[, Raw Section {STRING}]]]) NOTE: This function isn't exactly 100% portable. Your default ini file MUST be: ./Resources/Default.ini In other words a folder next to this source called "resource" with "Default.ini" inisde it. You must also insure that $ini_path and $my_name are correctly set. The first parameter controls whether nor not the updated ini file will contain all the comments from the master ini file. For new users, these are probably very handy. For old-hats, they are more likely annoying. So let the user disable them, if required. Send $ON or $OFF, e.g.. local $clean_ini = IniReadCheckBoxValue($ini_path, $my_name, "clean_ini", $OFF) if not $installed_ini then UpdateIniFile($clean_ini) If you have settings in your master ini file that you MUST put in the user's ini, overwriting their own setting (CAREFUL!) add the names of those settings to $forced_settings, in a comma-delimited list, e.g.. UpdateIniFile(default, "commands,click_commands") The final parameter, $raw_section is the name of any sections you would like written (from the user's ini) as-is. This is useful for sections which have more than one preference with the exact same name, e.g.. [Window Triggers] Downloads=WinMove(@DesktopWidth/5+4,@DesktopHeight/4-32,@DesktopWidth/1.25,@DesktopHeight/2+64) Chrome=^t Research=WinMove(0,12,@DesktopWidth/2,@DesktopHeight-20) Downloads={End} Using the normal IniWrite mechanism, the second "Downloads" would overwrite the first, basically destroying the setting. UpdateIniFile($clean_ini, default, "Window Triggers") #ce ; func UpdateIniFileOld(byref $new_version, $clean_comments=$OFF, $forced_settings="", $raw_section="") ; if $clean_comments = default then $clean_comments = $OFF ; if $forced_settings = default then $forced_settings = "" ; if $raw_section = default then $raw_section = "" ; debug("Update Ini File: " & $ini_path & $LOG_LF, @ScriptLineNumber, 7);debug ; local $old_version = IniRead($ini_path, $my_name, "version", 0) ; local $vcomp = _VersionCompare($new_version, $old_version) ; ; user's ini is up-to-date.. ; switch $vcomp ; case 0, -1 ; both equal ; return false ; endswitch ; if $forced_settings then ; $forced_settings = StringSplit($forced_settings, ",") ; endif ; ; drop a temporary ini file somewhere.. ; local $tmp_ini = @TempDir & "\" & $my_name & ".new.ini" ; FileInstall("./Resources/Default.ini", $tmp_ini, 1) ; ; purge the new ini file of all comments.. ; if $clean_comments = $ON then ; if _FileReadToArray($tmp_ini, $file_array) then ; for $i = 1 to $file_array[0] ; local $line = StringStripWS($file_array[$i], 3) ; if StringLeft($line, 1) <> ";" then ; if $line then ArrayAdd($new_array, $line) ; endif ; next ; _FileWriteFromArray($tmp_ini, $new_array, 1) ; endif ; endif ; ; delete all non-application prefs from the new (temp) ini ; local $existing_sections = IniReadSectionNames($tmp_ini) ; for $a = 1 to $existing_sections[0] ; if $existing_sections[$a] <> $my_name then IniDelete($tmp_ini, $existing_sections[$a]) ; next ; ; grab sections from user's old ini file.. ; $existing_sections = IniReadSectionNames($ini_path) ; ; write user prefs to the temporary ini file.. (overwriting tmp_ini) ; for $a = 1 to $existing_sections[0] ; debug("Existing SECTION:: =>" & $existing_sections[$a] & "<=", @ScriptLineNumber, 7);debug ; local $section = IniReadSection($ini_path, $existing_sections[$a]) ; debug_PrintArray($section, "$section:", @ScriptLineNumber, 7);debug ; if IsArray($section) then ; ; We write this section on its own - as-is, ; ; to get any duplicated prefs (2+ commands for one window) ; if $raw_section and $existing_sections[$a] = $raw_section then ; IniWriteSection($tmp_ini, $existing_sections[$a], $section) ; continueloop ; endif ; ; Regular ini section.. ; for $b = 1 to $section[0][0] ; if not InArray($forced_settings, $section[$b][0]) then ; IniWrite($tmp_ini, $existing_sections[$a], $section[$b][0], $section[$b][1]) ; endif ; next ; endif ; next ; ; Backup/rename their existing app.ini to "[@date] app.ini" ; FileMove($ini_path, GetParent($ini_path) & "\[" & @Year & "-" & @Mon & "-" & @Mday & "@" & _ ; @Hour & "." & @Min & "]_v" & $old_version & "_" & $my_name & ".ini") ; ; move the newly created ini into place, and delete temp file.. ; FileMove($tmp_ini, $ini_path, 1) ; ; finally, update the version info in the ini file.. ; IniWrite($ini_path, $my_name, "version", $new_version) ; endfunc ; Update the users ini with any new settings (unless we force settings) ; Leave their old examples and comments intact. ; func UpdateIniFile($new_version, $clean_comments=$OFF, $forced_settings="", $no_new_prefs="") debug("", @ScriptLineNumber, 7);debug debug("UpdateIniFile(" & $new_version & "," & $clean_comments & "," & $forced_settings & ")", @ScriptLineNumber, 7);debug if $clean_comments = default then $clean_comments = $OFF if $forced_settings = default then $forced_settings = "" if $no_new_prefs = default then $no_new_prefs = "" debug("Update Ini File: " & $ini_path & $LOG_LF, @ScriptLineNumber, 7);debug local $old_version = IniRead($ini_path, $my_name, "version", 0) local $vcomp = _VersionCompare($new_version, $old_version) ; user's ini is up-to-date.. switch $vcomp case 0, -1 ; both equal return false endswitch ; Backup/rename their existing app.ini to "[@date] app.ini" FileCopy($ini_path, GetParent($ini_path) & "\[" & @Year & "-" & @Mon & "-" & @Mday & "@" & _ @Hour & "." & @Min & "][v" & $old_version & "]" & $my_name & ".ini") if $forced_settings then $forced_settings = StringSplit($forced_settings, ",") endif local $wrote = 0 if not FileExists($ini_path) then FileInstall($my_name & ".ini", $ini_path) else ; Create a temporary default strings.ini.. local $tmp_ini_path = @TempDir & "\TEMP_.ini" FileInstall($my_name & ".ini", $tmp_ini_path) local $existing_sections = IniReadSectionNames($tmp_ini_path) ; 2do.. for sections, e.g. menus, it is not desirable to add default values ; onto the end of their prefs. Need raw for this. But WITH comments. ; Interrogate user ini file for missing prefs and add default/new prefs as required.. if IsArray($existing_sections) then for $i = 1 to $existing_sections[0] local $current_section = $existing_sections[$i] debug("SECTION:: =>" & $current_section & "<=", @ScriptLineNumber, 7);debug if $current_section <> $no_new_prefs then debug("Writing prefs to:: =>" & $current_section & "<=", @ScriptLineNumber, 7);debug local $this_section_data = IniReadSection($tmp_ini_path, $current_section) debug_PrintArray($this_section_data, "cel.au3 :: $this_section_data:", @ScriptLineNumber, 7);debug if IsArray($this_section_data) then for $k = 1 to $this_section_data[0][0] local $current_setting = $this_section_data[$k][0] debug("$current_setting: =>" & $current_setting & "<=", @ScriptLineNumber, 7);debug local $user_value = IniRead($ini_path, $current_section, $current_setting, "") local $default_value = IniRead($tmp_ini_path, $current_section, $current_setting, "") debug("$user_value: =>" & $user_value & "<=", @ScriptLineNumber, 7);debug debug("$default_value: =>" & $default_value & "<=", @ScriptLineNumber, 7);debug ; If empty or gone, write the setting.. ; If it's different, leave it alone - they edited it. ; unless it's a forced pref, in which case they get the (new) default value.. if not $user_value or InArray($forced_settings, $current_setting) then $wrote += 1 IniWrite($ini_path, $current_section, $current_setting, $default_value) endif next endif endif next endif endif FileDelete($tmp_ini_path) ; Purge the ini file of all comments.. if $clean_comments = $ON then if _FileReadToArray($ini_path, $file_array) then for $i = 1 to $file_array[0] local $line = StringStripWS($file_array[$i], 3) if StringLeft($line, 1) <> ";" then if $line then ArrayAdd($new_array, $line) endif next local $file_handle = Fileopen($ini_path, $FO_UNICODE+$FO_OVERWRITE) _FileWriteFromArray($file_handle, $new_array, 1) FileClose($file_handle) endif endif ; Insert this flag in your defualt.ini for a neat way to check for a "new install".. IniDelete($ini_path, $my_name, "new_install") ; Finally, update the version info in the ini file.. IniWrite($ini_path, $my_name, "version", $new_version) debug($ini_path & " updated. Wrote: " & $wrote & " ini settings", @ScriptLineNumber, 1);debug endfunc ; The AutoIt built-in function moves the "new" section to the bottom of the ini ; file, which is annoying. This Blunderbuss approach works well, and leaves ; the section order as-is, meaning menus and such that rely on section order (or ; at least use it) won't find themselves reshuffled.. ; ; Usage: BetterIniRenameSection(, , ) ; func BetterIniRenameSection($inifile, $old_name, $new_name) debug("", @ScriptLineNumber, 8);debug debug("cel.au3 :: BetterIniRenameSection($inifile=" & $inifile & ", $old_name=" & $old_name & ", $new_name=" & $new_name & "):", @ScriptLineNumber, 8);debug local $existing_sections = IniReadSectionNames($inifile) if not InArray($existing_sections, $old_name) then return SetError(1, 0, false) local $inifile_contents = FileRead($inifile) local $new_ini_string = StringReplace($inifile_contents, "[" & $old_name & "]", "[" & $new_name & "]") local $temp_inifile = _WinAPI_GetTempFileName(@TempDir, "cel") FileDelete($temp_inifile) FileWrite($temp_inifile, $new_ini_string) ; Compare ini files for matching (other) section names.. local $compare1 = ArrayJoin($existing_sections, "|") $compare1 = StringReplace($compare1, $old_name, "|") local $new_sections = IniReadSectionNames($temp_inifile) local $compare2 = ArrayJoin($new_sections, "|") $compare2 = StringReplace($compare2, $new_name, "|") if StringCompare($compare1, $compare2) == 0 then BackupFile($inifile) FileMove($temp_inifile, $inifile, 1) return true endif return SetError(2, 0, false) endfunc ; This tiny function saves a HEAP of code.. ; func TogglePref(byref $variable) if $variable = $ON then $variable = $OFF else $variable = $ON endif endfunc ; Save one of the above tray prefs to the ini and set the state of the tray to ; match the setting.. ; func SaveTrayPref($tray_control, $pref_var, $pref_name) IniWriteCheckBoxValue($ini_path, $my_name, $pref_name, $pref_var) TrayItemSetState($tray_control, $pref_var) endfunc ; InArray() [for single-dimension arrays] ; ; Feed it an AutoIt array and a string, returns true if $ia_string ; is one of the $ia_array's *values*. Non-AutoIt arrays work fine, ; the first element is not relied upon, it is simply ignored. ; ; The search is case-insensitive, but must be an exact (not partial) match. ; There's probably a real function for this these days. (Not yet!) ; func InArray(byref $ia_array, $ia_string, $match_case=false) if not IsArray($ia_array) then return false local $ia_limit = UBound($ia_array) - 1 for $i = 1 to $ia_limit ; not 0, which would return the total as a positive result if $ia_array[0]= e.g. "1" switch $match_case case true if $ia_string == $ia_array[$i] then return $i case false if $ia_string = $ia_array[$i] then return $i endswitch next return false endfunc ; InArrayValue() [for single-dimension arrays] ; ; Feed it an AutoIt (zero-indexed) array and a string, returns true if ; $ia_string is inside one of the $ia_array's *values*. Non-AutoIt arrays work ; fine, the first element is not relied upon, it is simply ignored. ; ; The search is case-insensitive, and can be a partial) match. ; Returns the index of the first value containing the string. ; func InArrayValue(byref $ia_array, $ia_string) if not IsArray($ia_array) then return SetError(1, -8, false) local $ia_limit = UBound($ia_array) - 1 for $i = 1 to $ia_limit if StringInStr($ia_array[$i], $ia_string) then return $i next return false endfunc ; InArrayColumn() [for single-dimension arrays, with columned indexes] ; ; Feed it an AutoIt array and a string, returns true if $ia_string ; is a column of one of the $ia_array's *values*. Non-AutoIt arrays work ; fine, the first element is not relied upon, it is simply ignored. ; ; Because AutoIt's array-handling is almost non-existant, and redimming ; amazingly slow, other methods need to be devised to work with indexed ; lists. A "column marker" is simply a delimiter within the value which ; can be used to further split a value into multiple values. ; ; This function is designed to find text (e.g. "path/name.ext") inside a ; value that may look like.. "path/name.ext|179|20080621114934". ; ; The search is case-insensitive, and must be an exact match for a ; particular column. Columns are numbered from 1, which is the value of ; the first column, and the correct match in the above example. ; ; Success: Returns the index of the first value containing the string. ; Fail: Returns false ; func InArrayColumn(byref $ia_array, $ia_string, $col=1, $marker="*") if not IsArray($ia_array) then return SetError(1, -8, false) local $ia_limit = UBound($ia_array) - 1 for $i = 1 to $ia_limit local $columns = StringSplit($ia_array[$i], $marker, $STR_ENTIRESPLIT) if $columns[$col] == $ia_string then return $i next return false endfunc ; MakeDummyArray() ; ; We need an array, but only have a string, what to do? this function returns an ; "AutoIt array" with a single data element, that is, two elements; $dummy_array[1] ; containing your string, and $dummy_array[0] being the total number of data elements, ; AutoIt-style, which will always be 1, of course. ; ; Although this is simple enough to do in place, it's more readable to do use a function. ; func MakeDummyArray($regular_string) local $dummy_array[2] = [1, $regular_string] return $dummy_array endfunc ; Send it a regular 1-D AutoIt array and get back a 2-D array, with ; the original array filling the first column, and a second, blank column ; for you to fill with "associated" data. See also Associative Array ; Functions, below. func OneToTwoDArray($array) debug("OneToTwoDArray()", @ScriptLineNumber, 9);debug local $new_array[1][2] $new_array[0][0] = $array[0] for $e = 1 to $array[0] redim $new_array[$e+1][2] ; an extra 1! $new_array[$e][0] = $array[$e] $new_array[$e][1] = "" debug_PrintArray($new_array, "cel.au3 :: 1D->2D Array:", @ScriptLineNumber, 9);debug next debug_PrintArray($new_array, "cel.au3 :: 1D->2D RETURNING Array:", @ScriptLineNumber, 9);debug return $new_array endfunc ; TwoD2OneDArray() ; ; Convert a 2-dimensional array into a 1-dimensional array ; of all the *values* of the original 2D array.. ; ; Pass true as the 2nd parameter to instead have it made from the /keys/. ; ; The 3rd parameter is any character or string of characters you with to strip ; (replace with "") from each key or value. Handy for trimming @Macros and such. ; func TwoD2OneDArray(byref $Array2D, $keys=false, $strip="") if not IsArray($Array2D) then return false local $array[$Array2D[0][0]+1] $array[0] = $Array2D[0][0] for $i = 1 to $Array2D[0][0] if $keys then local $key = $Array2D[$i][0] local $value = $Array2D[$i][1] if $strip then if $keys then $key = StringReplace($key, $strip, "") $value = StringReplace($value, $strip, "") endif if $keys then $array[$i] = $key else $array[$i] = $value endif next return $array endfunc ; Take a two-dimensional array and convert it to a one-dimensional array ; using the chosen column of data.. func TwoDCol2OneDArray($Array2D, $col=0) debug("TwoDCol2OneDArray()", @ScriptLineNumber, 9);debug debug_PrintArray($Array2D, "cel.au3 :: $Array2D:", @ScriptLineNumber, 7);debug if not IsArray($Array2D) then return false local $array[$Array2D[0][0]+1] $array[0] = $Array2D[0][0] for $i = 1 to $Array2D[0][0] $array[$i] = $Array2D[$i][$col] debug_PrintArray($array, "cel.au3 :: $array:", @ScriptLineNumber, 9);debug next debug_PrintArray($array, "cel.au3 :: 2D->1D RETURNING Array:", @ScriptLineNumber, 9);debug return $array endfunc ; Takes a 2-dimensional array as input and splits it into two arrays, ; the first, all the indexes, the second, all the values. ; func TwoD22OneDArrays(byref $Array2D) if not IsArray($Array2D) then return false local $array[$Array2D[0][0]+1] local $array2[$Array2D[0][0]+1] $array[0] = $Array2D[0][0] $array2[0] = $Array2D[0][0] for $i = 1 to $Array2D[0][0] $array[$i] = $Array2D[$i][0] $array2[$i] = $Array2D[$i][1] next local $newarray[2] = [$array, $array2] return $newarray endfunc #cs ArrayAdd() Add a single item to an AutoIt array.. ArrayAdd() automatically increases the [0] index, but DOES NOT rely upon it. Enable the third parameter to NOT add items which already exist in the array. Set the fourth parameter to true, and when an item is added which already exists, the array is re-indexed, moving the entry to the END of the array. In other words, it becomes the "most recent entry". #ce func ArrayAdd(byref $array, $item, $unique=false, $update=false) if not IsArray($array) then return local $size = UBound($array) if $unique and $update = false then if InArray($array, $item) then return endif if $update then local $idx = InArray($array, $item) if $idx then for $i = $idx to $size-2 $array[$i] = $array[$i+1] next $size -= 1 endif endif redim $array[$size+1] $array[$size] = $item $array[0] = $size endfunc #cs ArrayRemove() If $item is a number, that index is removed, otherwise the array is searched for values matching {String} $item and that key is removed. Remaining elements are moved down to fill the gap and the resulting array is one element shorter. The [0] count element is updated with the new total. Returns true is changes were made, false otherwise. #ce func ArrayRemove(byref $array, $item) debug("", @ScriptLineNumber, 7);debug debug("ArrayRemove(" & $item & ")", @ScriptLineNumber, 7);debug if not IsArray($array) then return SetError(1, 0, false) debug_PrintArray($array, "cel.au3 :: Remove from this: $array:", @ScriptLineNumber, 7);debug local $match = false local $total_rows = UBound($array, $UBOUND_ROWS)-1 debug("$total_rows: =>" & $total_rows & "<=", @ScriptLineNumber, 7);debug if IsNumber($item) then $match = $item else for $i = 1 to $total_rows debug("$array[$i] =>" & $array[$i] & "<=", @ScriptLineNumber, 7);debug if $array[$i] == $item then $match = $i ; Stop here. Run through remaining rows.. exitloop endif next endif if $match then for $k = $match to $total_rows-1 ; Fill /this/ row with the /next/ row's values.. debug("$array[$k+1]: =>" & $array[$k+1] & "<=", @ScriptLineNumber, 7);debug $array[$k] = $array[$k+1] next Redim $array[$total_rows] $array[0] = $total_rows-1 return true endif endfunc ; An alias for the above function. func ArrayDelete(byref $array, $item) return ArrayRemove($array, $item) endfunc #cs Very simple 2D array add. Param 1: The array to add to. Param 2: A pipe delimited list of values. ArrayAdd2D($my_array, "foo|bar|sheep|shoe") If your list has less items than there are columns, the remaining columns will be empty. If you list contains more items than there are columns, the extra items will be ignored. It's okay to send blank vaules. ArrayAdd2D($my_array, "||foo||bar") The index value $my_array[0][0] is automatically updated. Set the 3rd parameter to true to ensure no duplicate entries. Only the first column is checked. Set the 4th parameter to true to replace existing values, otherwise if a key already exists, it will we left alone. ArrayAdd2D($array, "foo|bar|sheep|shoe", $unique, $replace_existing) #ce func ArrayAdd2D(byref $array, $items, $unique=false, $replace=false, $delim="|") if not IsArray($array) then return SetError(1, 0, false) $items = StringSplit($items, $delim, $STR_ENTIRESPLIT) debug("$items[1]: =>" & $items[1] & "<=", @ScriptLineNumber, 7);debug local $exists = InArray2D($array, $items[1]) debug("$exists: =>" & $exists & "<=", @ScriptLineNumber, 7);debug if $exists and $unique and not $replace then return SetError(2, 0, false) ; Column 1 is empty, forget matching! if not $items[1] then $exists = false local $rows if $exists and $replace then $rows = $exists local $columns = UBound($array, $UBOUND_COLUMNS) if not $exists then $rows = UBound($array, $UBOUND_ROWS) redim $array[$rows+1][$columns] $array[0][0] += 1 debug("$array[0][0]: =>" & $array[0][0] & "<=", @ScriptLineNumber, 7);debug endif ; Add the items to this row.. for $i = 1 to $items[0] $array[$rows][$i-1] = $items[$i] if $i = $columns then exitloop next return true endfunc #cs ArrayRemove2D(byref $array, $item, $column) Remove the first row of a 2D array where $array[row][$column] matches $item. Supply the array to search, a string to search for (This is a CaSe-sEnsItiVe search), and the column to search in for that string. When a match is found, the entire row is removed and the remaining rows are re-indexed from the removal point and the array is one row shorter. The count [0][0] element is not relied upon when removing rows, but it is updated with the correct new total, which will usually be the old total minus one. Returns true if changes were made, otherwise false. #ce func ArrayRemove2D(byref $array, $item, $column) debug("", @ScriptLineNumber, 7);debug debug("ArrayRemove2D([" & $item & "," & $column & "])", @ScriptLineNumber, 7);debug if not IsArray($array) then return SetError(1, 0, false) debug_PrintArray($array, "cel.au3 :: Remove from: $array:", @ScriptLineNumber, 7);debug local $total_columns = UBound($array, $UBOUND_COLUMNS) local $total_rows = UBound($array, $UBOUND_ROWS)-1 debug("$total_columns: =>" & $total_columns & "<=", @ScriptLineNumber, 7);debug debug("$total_rows: =>" & $total_rows & "<=", @ScriptLineNumber, 7);debug for $i = 1 to $total_rows debug("$array[$i][$column]: =>" & $array[$i][$column] & "<=", @ScriptLineNumber, 7);debug if $array[$i][$column] == $item then ; Stop here. Run through remaining rows.. for $k = $i to $total_rows-1 ; Fill /this/ row with the /next/ row's values.. for $m = 0 to $total_columns-1 debug("$array[$k+1][$m]: =>" & $array[$k+1][$m] & "<=", @ScriptLineNumber, 7);debug $array[$k][$m] = $array[$k+1][$m] next next Redim $array[$total_rows][$total_columns] $array[0][0] = $total_rows-1 return true endif next endfunc #cs InArray2D($array, $search_string, $search_column) Very Simple 2D Array Search. Suppy: param 1: The 2D Array to search. param 2: The string to search for (CaSe-sEnsItiVe match). param 3: (optional) The column to search. If this is omitted, all columns are searched. Returns the number of the row which contained the string as one of its column's values. Otherwise returns false. If you can suppply the search column, it will increase speed slightly. Column numbering begins at zero (0). Example.. global $array[1][7] ArrayAdd2D($array, "|apple|pear||orange") ArrayAdd2D($array, "dog|cat|cow|pig|goat") ArrayAdd2D($array, "||||nut|seed|") local $row = InArray2D($array, "pig", 3) if $row then debug("PIG IN THE DUNGEON!!!", @ScriptLineNumber, 7);debug Will print out "PIG IN THE DUNGEON!!!" $row will equal 2. #ce func InArray2D(byref $array, $string, $search_column=false) if not IsArray($array) then return false local $rows = UBound($array, $UBOUND_ROWS) - 1 local $columns = UBound($array, $UBOUND_COLUMNS) for $i = 1 to $rows if $search_column then if $string == $array[$i][$search_column] then return $i else for $k = 0 to $columns-1 if $string == $array[$i][$k] then return $i next endif next return false endfunc ; Take a comma-delimited list, usually an ini pref, check it's formatted okay ; and then convert to an array. It all happens ByRef. ; func CommaDelimListToArray(byref $my_list) CBT($my_list, ",") $my_list = StringSplit(StringReplace($my_list, ",,", ","), ",") ; now an array endfunc ; Improvements on the UDF-supplied versions; posted in the AutoIt forum.. ; ; This is the fastest FileReadToArray, but uses the most memory for big files (x64: 4.5s/1.02GB on a 106MB file, 912515 lines) ; ; #FUNCTION# ==================================================================================================================== ; Name...........: FileReadIntoArray ; Description ...: Reads the specified file into an array. ; Syntax.........: FileReadIntoArray($TmpFile, ByRef $aArray [, $iFlag]) ; Parameters ....: $TmpFile - Full path and filename of the file to be read. ; $aArray - The array in which to store the contents of the file. ; $iFlag - Optional: (add the flags together for multiple operations): ; |$iFlag = 0 Return the array count in the [0] element (create 1-based array index - the Default) ; |$iFlag = 1 Don't return the array count (create 0-based array index) ; |$iFlag = 2 Don't return Line empty (ignores @CR & @LF & @CRLF) ; |$iFlag = 4 Don't return Line empty or lines containing only whitespace character (ignores @CRLF, " ", @CR, @TAB, @CR, @LF, etc.) ; |$iFlag = 8 Strip Line leading white space ; Return values .: Success - Returns a 1 ; Failure - Returns a 0 ; @error - 0 = No error. ; |1 = Error opening specified file ; |2 = Unable to Split the file ; Authors ........: Jonathan Bennett, Valik, Jpm, Gary, guinness, DXRW4E, Cor ; =============================================================================================================================== func FileReadIntoArray($TmpFile, byref $aArray, $iFlag = 0) local $ArrayCount, $RegExp = "(?:\r\n|\n|\r)([^\r\n]*)" local $hFileOpen = FileOpen($TmpFile, 0) if $hFileOpen = -1 then return SetError(1, 0, 0) local $sFileRead = StringStripWS(FileRead($hFileOpen), 3) FileClose($hFileOpen) ; Flags.. if not BitAND($iFlag, 1) then $ArrayCount = "ArrayCount" & @LF if BitAND($iFlag, 2) then $RegExp = "(?:\r\n|\n|\r)([^\r\n]+)" if BitAND($iFlag, 4) then $RegExp = "s*(?:\r\n|\n|\r)([^\r\n]+)" if BitAND($iFlag, 8) then $RegExp = StringReplace($RegExp, ")", ")h*", 1, 1) $aArray = StringRegExp(@LF & $ArrayCount & $sFileRead, $RegExp, 3) if @error then if StringLen($sFileRead) then local $ret[2] = [1, $sFileRead] $aArray = $ret else return SetError(2, 0, 0) endif elseif $ArrayCount then $aArray[0] = UBound($aArray) - 1 endif return 1 endfunc ; func ArrayAddRow(byref $array, $row_data) ; local $size = UBound($array, $UBOUND_COLUMNS) ; endfunc ; Associative Array Functions ; ; Before you start using your associative array, you need to initialize it. Put ; this code somewhere before you start using the array, probably at the top-ish ; of your script.. ; ; ; Initialize your array in your script.au3 ... ; global $associative_array ; AAInit($associative_array) ; ; Obviously, "$associative_array" will be your own array variable. ; ; You can initialize and use multiple associative arrays in your script. ; ; There is another essential line, to initialize a COM error handler, but that ; is already added to the top of THIS script, waiting.. ; ; global $oMyError = ObjEvent("AutoIt.Error", "AAError") ; ; func AAInit(byref $dict_obj) $dict_obj = ObjCreate("Scripting.Dictionary") endfunc ; Adds a key and item pair to a Dictionary object. func AAAdd(byref $dict_obj, $key, $val, $unique=false) if $unique and AAExists($dict_obj, $key) then return SetError(1, 1, -2) $dict_obj.Add($key, $val) If @error Then return SetError(1, 1, -1) endfunc ; Removes a key and item pair from a Dictionary object.. func AARemove(byref $dict_obj, $key) $dict_obj.Remove($key) If @error Then return SetError(1, 1, -1) endfunc ; Returns true if a specified key exists in the associative array, false if not.. func AAExists(byref $dict_obj, $key) return $dict_obj.Exists($key) endfunc ; Returns a value for a specified key in the associative array.. func AAGetItem(byref $dict_obj, $key) return $dict_obj.Item($key) endfunc ; Returns the total number of keys in the array.. func AACount(byref $dict_obj) return $dict_obj.Count endfunc ; List all the "Key" => "Item" pairs in the array.. func AAList(byref $dict_obj, $title="Associative Array:", $level=1) if $level > $debug_level then return false debug($title & " [" & AACount($dict_obj) & " items] :=>", @ScriptLineNumber, 7);debug local $k = $dict_obj.Keys ; Get the keys ; local $a = $dict_obj.Items ; Get the items for $i = 0 to AACount($dict_obj) -1 ; Iterate the array debug($k[$i] & " ==> " & AAGetItem($dict_obj, $k[$i])) next endfunc ; Wipe the array, obviously. func AAWipe(byref $dict_obj) $dict_obj.RemoveAll() endfunc ; Oh oh! func AAError() Local $err = $oMyError.number If $err = 0 Then $err = -1 SetError($err) endfunc #cs SaveComboSelection() SaveComboSelection( array{this combo box's special selection array}, string{value to store}) Does what it says on the tin (erm, also works for regular drop-downs!) If the user deletes an item, the previous item will be selected This makes multiple deltions easier, and more. This code is also more compact than checking for even a single "previous" entry on each combo box individually. It's neater, too. To use, simply create a global "AutoIt" array for the values, with the number of values you would like to remember (remember to set element 0 to the total).. global $previous_combo_selections[501] = [500] ; plenty! Make one for each combo. Rather than set a limit, we could use redim, but it's slow. Anyway, when the user selects something, store that.. SaveComboSelection($previous_combo_selections, $current_preset) And when they delete an item, recall the previous item with.. $previous_selection = GetComboSelection($previous_combo_selections_array, $valid_names_array) Or use it directly.. ControlCommand($GUI_foo, "", $Control_ID, "SelectString", _ GetComboSelection($previous_combo_selections_array, $valid_names_array)) If your deleted entry is still in the list at the point you need to get this information, simply repeat the command. Essentially, go "back two".. ; this selects and removes the currently selected item.. GetComboSelection($previous_combo_selections_array, $valid_names_array) ; now the previous one.. ControlCommand($GUI_foo, "", $Control_ID, "SelectString", _ GetComboSelection($previous_combo_selections_array, $valid_names_array)) #ce func SaveComboSelection(byref $combo_array, $value) for $i = 1 to $combo_array[0] if $combo_array[$i] = "" then if $combo_array[$i-1] <> $value then $combo_array[$i] = $value endif exitloop ; store or not, we're outta here endif next endfunc ; GetComboSelection() ; ; Get back the user's previous drop-down selection after a delete operation.. ; ; We simply iterate the saved-combo strings array backwards, deleting all non- ; valid entries until the most recent valid entry is found. Then we delete it ; from the array and return the value. ; ; In the absence of a stored value, we return the "last" value in the names ; list. If deleting newly imported/created presets, this will get you the ; most recent addition, even when it hasn't been selected this session. ; ; It would be trivial to store this array in an ini file between launches, and ; keep a selection "history", if you require that. ; ; $String = GetComboSelection( array{this combo box's special selection array}, array{list of current valid names in this combo}) ; func GetComboSelection(byref $combo_array, byref $names_list) local $new_val = "" local $i = $combo_array[0] while $i > 0 if $combo_array[$i] <> "" then if not InArray($names_list, $combo_array[$i]) then $combo_array[$i] = "" $i -= 1 continueloop endif $new_val = $combo_array[$i] $combo_array[$i] = "" exitloop endif $i -= 1 wend if $new_val = "" then $new_val = $names_list[$names_list[0]] return $new_val endfunc ; VisitUrl() ; ; Send the "default browser" to our URL.. ; This uses the USER'S SYSTEM BROWSER! (eg. Firefox) func VisitUrl($VisitURL="http://corz.org/") debug("VisitURL: =>" & $VisitURL & "<=" , @ScriptLineNumber, 7);debug ShellExecute($VisitURL) if @Error <> 0 then return true else return SetError (@Error, default , true) endif endfunc ; ReplaceHTMLEntities() ; ; ; Probably rather slow, but, erm, fairly thorough.. ; ; Note: unless you are using a proper international font, many of the entities ; below will appear as boxes, or empty. Worry not, everything is working fine. ; ; Updated with routine from Dhilip89 ; func ReplaceHTMLEntities($text) Local $Entity[65536] $Entity[34] = "quot" $Entity[38] = "amp" $Entity[39] = "apos" $Entity[60] = "lt" $Entity[62] = "gt" $Entity[160] = "nbsp" $Entity[161] = "iexcl" $Entity[162] = "cent" $Entity[163] = "pound" $Entity[164] = "curren" $Entity[165] = "yen" $Entity[166] = "brvbar" $Entity[167] = "sect" $Entity[168] = "uml" $Entity[169] = "copy" $Entity[170] = "ordf" $Entity[171] = "laquo" $Entity[172] = "not" $Entity[173] = "shy" $Entity[174] = "reg" $Entity[175] = "macr" $Entity[176] = "deg" $Entity[177] = "plusmn" $Entity[178] = "sup2" $Entity[179] = "sup3" $Entity[180] = "acute" $Entity[181] = "micro" $Entity[182] = "para" $Entity[183] = "middot" $Entity[184] = "cedil" $Entity[185] = "sup1" $Entity[186] = "ordm" $Entity[187] = "raquo" $Entity[188] = "frac14" $Entity[189] = "frac12" $Entity[190] = "frac34" $Entity[191] = "iquest" $Entity[192] = "Agrave" $Entity[193] = "Aacute" $Entity[194] = "Acirc" $Entity[195] = "Atilde" $Entity[196] = "Auml" $Entity[197] = "Aring" $Entity[198] = "AElig" $Entity[199] = "Ccedil" $Entity[200] = "Egrave" $Entity[201] = "Eacute" $Entity[202] = "Ecirc" $Entity[203] = "Euml" $Entity[204] = "Igrave" $Entity[205] = "Iacute" $Entity[206] = "Icirc" $Entity[207] = "Iuml" $Entity[208] = "ETH" $Entity[209] = "Ntilde" $Entity[210] = "Ograve" $Entity[211] = "Oacute" $Entity[212] = "Ocirc" $Entity[213] = "Otilde" $Entity[214] = "Ouml" $Entity[215] = "times" $Entity[216] = "Oslash" $Entity[217] = "Ugrave" $Entity[218] = "Uacute" $Entity[219] = "Ucirc" $Entity[220] = "Uuml" $Entity[221] = "Yacute" $Entity[222] = "THORN" $Entity[223] = "szlig" $Entity[224] = "agrave" $Entity[225] = "aacute" $Entity[226] = "acirc" $Entity[227] = "atilde" $Entity[228] = "auml" $Entity[229] = "aring" $Entity[230] = "aelig" $Entity[231] = "ccedil" $Entity[232] = "egrave" $Entity[233] = "eacute" $Entity[234] = "ecirc" $Entity[235] = "euml" $Entity[236] = "igrave" $Entity[237] = "iacute" $Entity[238] = "icirc" $Entity[239] = "iuml" $Entity[240] = "eth" $Entity[241] = "ntilde" $Entity[242] = "ograve" $Entity[243] = "oacute" $Entity[244] = "ocirc" $Entity[245] = "otilde" $Entity[246] = "ouml" $Entity[247] = "divide" $Entity[248] = "oslash" $Entity[249] = "ugrave" $Entity[250] = "uacute" $Entity[251] = "ucirc" $Entity[252] = "uuml" $Entity[253] = "yacute" $Entity[254] = "thorn" $Entity[255] = "yuml" $Entity[338] = "OElig" $Entity[339] = "oelig" $Entity[352] = "Scaron" $Entity[353] = "scaron" $Entity[376] = "Yuml" $Entity[402] = "fnof" $Entity[710] = "circ" $Entity[732] = "tilde" $Entity[913] = "Alpha" $Entity[914] = "Beta" $Entity[915] = "Gamma" $Entity[916] = "Delta" $Entity[917] = "Epsilon" $Entity[918] = "Zeta" $Entity[919] = "Eta" $Entity[920] = "Theta" $Entity[921] = "Iota" $Entity[922] = "Kappa" $Entity[923] = "Lambda" $Entity[924] = "Mu" $Entity[925] = "Nu" $Entity[926] = "Xi" $Entity[927] = "Omicron" $Entity[928] = "Pi" $Entity[929] = "Rho" $Entity[931] = "Sigma" $Entity[932] = "Tau" $Entity[933] = "Upsilon" $Entity[934] = "Phi" $Entity[935] = "Chi" $Entity[936] = "Psi" $Entity[937] = "Omega" $Entity[945] = "alpha" $Entity[946] = "beta" $Entity[947] = "gamma" $Entity[948] = "delta" $Entity[949] = "epsilon" $Entity[950] = "zeta" $Entity[951] = "eta" $Entity[952] = "theta" $Entity[953] = "iota" $Entity[954] = "kappa" $Entity[955] = "lambda" $Entity[956] = "mu" $Entity[957] = "nu" $Entity[958] = "xi" $Entity[959] = "omicron" $Entity[960] = "pi" $Entity[961] = "rho" $Entity[962] = "sigmaf" $Entity[963] = "sigma" $Entity[964] = "tau" $Entity[965] = "upsilon" $Entity[966] = "phi" $Entity[967] = "chi" $Entity[968] = "psi" $Entity[969] = "omega" $Entity[977] = "thetasym" $Entity[978] = "upsih" $Entity[982] = "piv" $Entity[8194] = "ensp" $Entity[8195] = "emsp" $Entity[8201] = "thinsp" $Entity[8204] = "zwnj" $Entity[8205] = "zwj" $Entity[8206] = "lrm" $Entity[8207] = "rlm" $Entity[8211] = "ndash" $Entity[8212] = "mdash" $Entity[8216] = "lsquo" $Entity[8217] = "rsquo" $Entity[8218] = "sbquo" $Entity[8220] = "ldquo" $Entity[8221] = "rdquo" $Entity[8222] = "bdquo" $Entity[8224] = "dagger" $Entity[8225] = "Dagger" $Entity[8226] = "bull" $Entity[8230] = "hellip" $Entity[8240] = "permil" $Entity[8242] = "prime" $Entity[8243] = "Prime" $Entity[8249] = "lsaquo" $Entity[8250] = "rsaquo" $Entity[8254] = "oline" $Entity[8260] = "frasl" $Entity[8364] = "euro" $Entity[8465] = "image" $Entity[8472] = "weierp" $Entity[8476] = "real" $Entity[8482] = "trade" $Entity[8501] = "alefsym" $Entity[8592] = "larr" $Entity[8593] = "uarr" $Entity[8594] = "rarr" $Entity[8595] = "darr" $Entity[8596] = "harr" $Entity[8629] = "crarr" $Entity[8656] = "lArr" $Entity[8657] = "uArr" $Entity[8658] = "rArr" $Entity[8659] = "dArr" $Entity[8660] = "hArr" $Entity[8704] = "forall" $Entity[8706] = "part" $Entity[8707] = "exist" $Entity[8709] = "empty" $Entity[8711] = "nabla" $Entity[8712] = "isin" $Entity[8713] = "notin" $Entity[8715] = "ni" $Entity[8719] = "prod" $Entity[8721] = "sum" $Entity[8722] = "minus" $Entity[8727] = "lowast" $Entity[8730] = "radic" $Entity[8733] = "prop" $Entity[8734] = "infin" $Entity[8736] = "ang" $Entity[8743] = "and" $Entity[8744] = "or" $Entity[8745] = "cap" $Entity[8746] = "cup" $Entity[8747] = "int" $Entity[8756] = "there4" $Entity[8764] = "sim" $Entity[8773] = "cong" $Entity[8776] = "asymp" $Entity[8800] = "ne" $Entity[8801] = "equiv" $Entity[8804] = "le" $Entity[8805] = "ge" $Entity[8834] = "sub" $Entity[8835] = "sup" $Entity[8836] = "nsub" $Entity[8838] = "sube" $Entity[8839] = "supe" $Entity[8853] = "oplus" $Entity[8855] = "otimes" $Entity[8869] = "perp" $Entity[8901] = "sdot" $Entity[8968] = "lceil" $Entity[8969] = "rceil" $Entity[8970] = "lfloor" $Entity[8971] = "rfloor" $Entity[9001] = "lang" $Entity[9002] = "rang" $Entity[9674] = "loz" $Entity[9824] = "spades" $Entity[9827] = "clubs" $Entity[9829] = "hearts" $Entity[9830] = "diams" local $e1 = StringRegExp($text, '&#x(.*?);', 3) local $e2 = StringRegExp($text, '&#(.*?);', 3) local $e3 = StringRegExp($text, '&(.*?);', 3) for $i = 0 To UBound($e1) - 1 step 1 $text = StringReplace($text, '&#x' & $e1[$i] & ';', ChrW(Dec($e1[$i]))) next for $i = 0 To UBound($e2) - 1 step 1 $text = StringReplace($text, '&#' & $e2[$i] & ';', ChrW($e2[$i])) next for $i = 0 To UBound($e3) - 1 step 1 $text = StringReplace($text, '&' & $e3[$i] & ';', ChrW(_ArraySearch($Entity, $e3[$i], 0, 0, 1))) next return $text endfunc func CreateHTMLEntities($string) local $len = StringLen($string) local $ret if not $len then return $string for $i = 1 to $len local $wchar = StringMid($string, $i, 1) $ret &= "&#" & AscW($wchar) & ";" next return $ret endfunc func EnCodeUrl($text) $text = StringReplace($text, " ", "%20") $text = StringReplace($text, "!", "%21") $text = StringReplace($text, '"', "%22") $text = StringReplace($text, "#", "%23") $text = StringReplace($text, "$", "%24") $text = StringReplace($text, "%", "%25") $text = StringReplace($text, "&", "%26") $text = StringReplace($text, "'", "%27") $text = StringReplace($text, "(", "%28") $text = StringReplace($text, ")", "%29") $text = StringReplace($text, "*", "%2A") $text = StringReplace($text, "+", "%2B") $text = StringReplace($text, ",", "%2C") $text = StringReplace($text, "-", "%2D") $text = StringReplace($text, ".", "%2E") $text = StringReplace($text, "/", "%2F") $text = StringReplace($text, "0", "%30") $text = StringReplace($text, "1", "%31") $text = StringReplace($text, "2", "%32") $text = StringReplace($text, "3", "%33") $text = StringReplace($text, "4", "%34") $text = StringReplace($text, "5", "%35") $text = StringReplace($text, "6", "%36") $text = StringReplace($text, "7", "%37") $text = StringReplace($text, "8", "%38") $text = StringReplace($text, "9", "%39") $text = StringReplace($text, ":", "%3A") $text = StringReplace($text, ";", "%3B") $text = StringReplace($text, "<", "%3C") $text = StringReplace($text, "=", "%3D") $text = StringReplace($text, ">", "%3E") $text = StringReplace($text, "?", "%3F") $text = StringReplace($text, "@", "%40") $text = StringReplace($text, "A", "%41") $text = StringReplace($text, "B", "%42") $text = StringReplace($text, "C", "%43") $text = StringReplace($text, "D", "%44") $text = StringReplace($text, "E", "%45") $text = StringReplace($text, "F", "%46") $text = StringReplace($text, "G", "%47") $text = StringReplace($text, "H", "%48") $text = StringReplace($text, "I", "%49") $text = StringReplace($text, "J", "%4A") $text = StringReplace($text, "K", "%4B") $text = StringReplace($text, "L", "%4C") $text = StringReplace($text, "M", "%4D") $text = StringReplace($text, "N", "%4E") $text = StringReplace($text, "O", "%4F") $text = StringReplace($text, "P", "%50") $text = StringReplace($text, "Q", "%51") $text = StringReplace($text, "R", "%52") $text = StringReplace($text, "S", "%53") $text = StringReplace($text, "T", "%54") $text = StringReplace($text, "U", "%55") $text = StringReplace($text, "V", "%56") $text = StringReplace($text, "W", "%57") $text = StringReplace($text, "X", "%58") $text = StringReplace($text, "Y", "%59") $text = StringReplace($text, "Z", "%5A") $text = StringReplace($text, "[", "%5B") $text = StringReplace($text, "\", "%5C") $text = StringReplace($text, "]", "%5D") $text = StringReplace($text, "^", "%5E") $text = StringReplace($text, "_", "%5F") $text = StringReplace($text, "`", "%60") $text = StringReplace($text, "a", "%61") $text = StringReplace($text, "b", "%62") $text = StringReplace($text, "c", "%63") $text = StringReplace($text, "d", "%64") $text = StringReplace($text, "e", "%65") $text = StringReplace($text, "f", "%66") $text = StringReplace($text, "g", "%67") $text = StringReplace($text, "h", "%68") $text = StringReplace($text, "i", "%69") $text = StringReplace($text, "j", "%6A") $text = StringReplace($text, "k", "%6B") $text = StringReplace($text, "l", "%6C") $text = StringReplace($text, "m", "%6D") $text = StringReplace($text, "n", "%6E") $text = StringReplace($text, "o", "%6F") $text = StringReplace($text, "p", "%70") $text = StringReplace($text, "q", "%71") $text = StringReplace($text, "r", "%72") $text = StringReplace($text, "s", "%73") $text = StringReplace($text, "t", "%74") $text = StringReplace($text, "u", "%75") $text = StringReplace($text, "v", "%76") $text = StringReplace($text, "w", "%77") $text = StringReplace($text, "x", "%78") $text = StringReplace($text, "y", "%79") $text = StringReplace($text, "z", "%7A") $text = StringReplace($text, "{", "%7B") $text = StringReplace($text, "|", "%7C") $text = StringReplace($text, "}", "%7D") $text = StringReplace($text, "~", "%7E") $text = StringReplace($text, " ", "%7F") $text = StringReplace($text, "€", "%80") $text = StringReplace($text, " ", "%81") $text = StringReplace($text, "‚", "%82") $text = StringReplace($text, "ƒ", "%83") $text = StringReplace($text, "„", "%84") $text = StringReplace($text, "…", "%85") $text = StringReplace($text, "†", "%86") $text = StringReplace($text, "‡", "%87") $text = StringReplace($text, "ˆ", "%88") $text = StringReplace($text, "‰", "%89") $text = StringReplace($text, "Š", "%8A") $text = StringReplace($text, "‹", "%8B") $text = StringReplace($text, "Œ", "%8C") $text = StringReplace($text, " ", "%8D") $text = StringReplace($text, "Ž", "%8E") $text = StringReplace($text, " ", "%8F") $text = StringReplace($text, " ", "%90") $text = StringReplace($text, "‘", "%91") $text = StringReplace($text, "’", "%92") $text = StringReplace($text, "“", "%93") $text = StringReplace($text, "”", "%94") $text = StringReplace($text, "•", "%95") $text = StringReplace($text, "–", "%96") $text = StringReplace($text, "—", "%97") $text = StringReplace($text, "˜", "%98") $text = StringReplace($text, "™", "%99") $text = StringReplace($text, "š", "%9A") $text = StringReplace($text, "›", "%9B") $text = StringReplace($text, "œ", "%9C") $text = StringReplace($text, " ", "%9D") $text = StringReplace($text, "ž", "%9E") $text = StringReplace($text, "Ÿ", "%9F") $text = StringReplace($text, " ", "%A0") $text = StringReplace($text, "¡", "%A1") $text = StringReplace($text, "¢", "%A2") $text = StringReplace($text, "£", "%A3") $text = StringReplace($text, " ", "%A4") $text = StringReplace($text, "¥", "%A5") $text = StringReplace($text, "|", "%A6") $text = StringReplace($text, "§", "%A7") $text = StringReplace($text, "¨", "%A8") $text = StringReplace($text, "©", "%A9") $text = StringReplace($text, "ª", "%AA") $text = StringReplace($text, "«", "%AB") $text = StringReplace($text, "¬", "%AC") $text = StringReplace($text, "¯", "%AD") $text = StringReplace($text, "®", "%AE") $text = StringReplace($text, "¯", "%AF") $text = StringReplace($text, "°", "%B0") $text = StringReplace($text, "±", "%B1") $text = StringReplace($text, "²", "%B2") $text = StringReplace($text, "³", "%B3") $text = StringReplace($text, "´", "%B4") $text = StringReplace($text, "µ", "%B5") $text = StringReplace($text, "¶", "%B6") $text = StringReplace($text, "·", "%B7") $text = StringReplace($text, "¸", "%B8") $text = StringReplace($text, "¹", "%B9") $text = StringReplace($text, "º", "%BA") $text = StringReplace($text, "»", "%BB") $text = StringReplace($text, "¼", "%BC") $text = StringReplace($text, "½", "%BD") $text = StringReplace($text, "¾", "%BE") $text = StringReplace($text, "¿", "%BF") $text = StringReplace($text, "À", "%C0") $text = StringReplace($text, "Á", "%C1") $text = StringReplace($text, "Â", "%C2") $text = StringReplace($text, "Ã", "%C3") $text = StringReplace($text, "Ä", "%C4") $text = StringReplace($text, "Å", "%C5") $text = StringReplace($text, "Æ", "%C6") $text = StringReplace($text, "Ç", "%C7") $text = StringReplace($text, "È", "%C8") $text = StringReplace($text, "É", "%C9") $text = StringReplace($text, "Ê", "%CA") $text = StringReplace($text, "Ë", "%CB") $text = StringReplace($text, "Ì", "%CC") $text = StringReplace($text, "Í", "%CD") $text = StringReplace($text, "Î", "%CE") $text = StringReplace($text, "Ï", "%CF") $text = StringReplace($text, "Ð", "%D0") $text = StringReplace($text, "Ñ", "%D1") $text = StringReplace($text, "Ò", "%D2") $text = StringReplace($text, "Ó", "%D3") $text = StringReplace($text, "Ô", "%D4") $text = StringReplace($text, "Õ", "%D5") $text = StringReplace($text, "Ö", "%D6") $text = StringReplace($text, " ", "%D7") $text = StringReplace($text, "Ø", "%D8") $text = StringReplace($text, "Ù", "%D9") $text = StringReplace($text, "Ú", "%DA") $text = StringReplace($text, "Û", "%DB") $text = StringReplace($text, "Ü", "%DC") $text = StringReplace($text, "Ý", "%DD") $text = StringReplace($text, "Þ", "%DE") $text = StringReplace($text, "ß", "%DF") $text = StringReplace($text, "à", "%E0") $text = StringReplace($text, "á", "%E1") $text = StringReplace($text, "â", "%E2") $text = StringReplace($text, "ã", "%E3") $text = StringReplace($text, "ä", "%E4") $text = StringReplace($text, "å", "%E5") $text = StringReplace($text, "æ", "%E6") $text = StringReplace($text, "ç", "%E7") $text = StringReplace($text, "è", "%E8") $text = StringReplace($text, "é", "%E9") $text = StringReplace($text, "ê", "%EA") $text = StringReplace($text, "ë", "%EB") $text = StringReplace($text, "ì", "%EC") $text = StringReplace($text, "í", "%ED") $text = StringReplace($text, "î", "%EE") $text = StringReplace($text, "ï", "%EF") $text = StringReplace($text, "ð", "%F0") $text = StringReplace($text, "ñ", "%F1") $text = StringReplace($text, "ò", "%F2") $text = StringReplace($text, "ó", "%F3") $text = StringReplace($text, "ô", "%F4") $text = StringReplace($text, "õ", "%F5") $text = StringReplace($text, "ö", "%F6") $text = StringReplace($text, "÷", "%F7") $text = StringReplace($text, "ø", "%F8") $text = StringReplace($text, "ù", "%F9") $text = StringReplace($text, "ú", "%FA") $text = StringReplace($text, "û", "%FB") $text = StringReplace($text, "ü", "%FC") $text = StringReplace($text, "ý", "%FD") $text = StringReplace($text, "þ", "%FE") $text = StringReplace($text, "ÿ", "%FF") return $text endfunc func DeCodeUrl($text) $text = StringReplace($text, "%20", " ") $text = StringReplace($text, "%21", "!") $text = StringReplace($text, "%22", '"') $text = StringReplace($text, "%23", "#") $text = StringReplace($text, "%24", "$") $text = StringReplace($text, "%25", "%") $text = StringReplace($text, "%26", "&") $text = StringReplace($text, "%27", "'") $text = StringReplace($text, "%28", "(") $text = StringReplace($text, "%29", ")") $text = StringReplace($text, "%2A", "*") $text = StringReplace($text, "%2B", "+") $text = StringReplace($text, "%2C", ",") $text = StringReplace($text, "%2D", "-") $text = StringReplace($text, "%2E", ".") $text = StringReplace($text, "%2F", "/") $text = StringReplace($text, "%30", "0") $text = StringReplace($text, "%31", "1") $text = StringReplace($text, "%32", "2") $text = StringReplace($text, "%33", "3") $text = StringReplace($text, "%34", "4") $text = StringReplace($text, "%35", "5") $text = StringReplace($text, "%36", "6") $text = StringReplace($text, "%37", "7") $text = StringReplace($text, "%38", "8") $text = StringReplace($text, "%39", "9") $text = StringReplace($text, "%3A", ":") $text = StringReplace($text, "%3B", ";") $text = StringReplace($text, "%3C", "<") $text = StringReplace($text, "%3D", "=") $text = StringReplace($text, "%3E", ">") $text = StringReplace($text, "%3F", "?") $text = StringReplace($text, "%40", "@") $text = StringReplace($text, "%41", "A") $text = StringReplace($text, "%42", "B") $text = StringReplace($text, "%43", "C") $text = StringReplace($text, "%44", "D") $text = StringReplace($text, "%45", "E") $text = StringReplace($text, "%46", "F") $text = StringReplace($text, "%47", "G") $text = StringReplace($text, "%48", "H") $text = StringReplace($text, "%49", "I") $text = StringReplace($text, "%4A", "J") $text = StringReplace($text, "%4B", "K") $text = StringReplace($text, "%4C", "L") $text = StringReplace($text, "%4D", "M") $text = StringReplace($text, "%4E", "N") $text = StringReplace($text, "%4F", "O") $text = StringReplace($text, "%50", "P") $text = StringReplace($text, "%51", "Q") $text = StringReplace($text, "%52", "R") $text = StringReplace($text, "%53", "S") $text = StringReplace($text, "%54", "T") $text = StringReplace($text, "%55", "U") $text = StringReplace($text, "%56", "V") $text = StringReplace($text, "%57", "W") $text = StringReplace($text, "%58", "X") $text = StringReplace($text, "%59", "Y") $text = StringReplace($text, "%5A", "Z") $text = StringReplace($text, "%5B", "[") $text = StringReplace($text, "%5C", "\") $text = StringReplace($text, "%5D", "]") $text = StringReplace($text, "%5E", "^") $text = StringReplace($text, "%5F", "_") $text = StringReplace($text, "%60", "`") $text = StringReplace($text, "%61", "a") $text = StringReplace($text, "%62", "b") $text = StringReplace($text, "%63", "c") $text = StringReplace($text, "%64", "d") $text = StringReplace($text, "%65", "e") $text = StringReplace($text, "%66", "f") $text = StringReplace($text, "%67", "g") $text = StringReplace($text, "%68", "h") $text = StringReplace($text, "%69", "i") $text = StringReplace($text, "%6A", "j") $text = StringReplace($text, "%6B", "k") $text = StringReplace($text, "%6C", "l") $text = StringReplace($text, "%6D", "m") $text = StringReplace($text, "%6E", "n") $text = StringReplace($text, "%6F", "o") $text = StringReplace($text, "%70", "p") $text = StringReplace($text, "%71", "q") $text = StringReplace($text, "%72", "r") $text = StringReplace($text, "%73", "s") $text = StringReplace($text, "%74", "t") $text = StringReplace($text, "%75", "u") $text = StringReplace($text, "%76", "v") $text = StringReplace($text, "%77", "w") $text = StringReplace($text, "%78", "x") $text = StringReplace($text, "%79", "y") $text = StringReplace($text, "%7A", "z") $text = StringReplace($text, "%7B", "{") $text = StringReplace($text, "%7C", "|") $text = StringReplace($text, "%7D", "}") $text = StringReplace($text, "%7E", "~") $text = StringReplace($text, "%7F", " ") $text = StringReplace($text, "%80", "€") $text = StringReplace($text, "%81", " ") $text = StringReplace($text, "%82", "‚") $text = StringReplace($text, "%83", "ƒ") $text = StringReplace($text, "%84", "„") $text = StringReplace($text, "%85", "…") $text = StringReplace($text, "%86", "†") $text = StringReplace($text, "%87", "‡") $text = StringReplace($text, "%88", "ˆ") $text = StringReplace($text, "%89", "‰") $text = StringReplace($text, "%8A", "Š") $text = StringReplace($text, "%8B", "‹") $text = StringReplace($text, "%8C", "Œ") $text = StringReplace($text, "%8D", " ") $text = StringReplace($text, "%8E", "Ž") $text = StringReplace($text, "%8F", " ") $text = StringReplace($text, "%90", " ") $text = StringReplace($text, "%91", "‘") $text = StringReplace($text, "%92", "’") $text = StringReplace($text, "%93", "“") $text = StringReplace($text, "%94", "”") $text = StringReplace($text, "%95", "•") $text = StringReplace($text, "%96", "–") $text = StringReplace($text, "%97", "—") $text = StringReplace($text, "%98", "˜") $text = StringReplace($text, "%99", "™") $text = StringReplace($text, "%9A", "š") $text = StringReplace($text, "%9B", "›") $text = StringReplace($text, "%9C", "œ") $text = StringReplace($text, "%9D", " ") $text = StringReplace($text, "%9E", "ž") $text = StringReplace($text, "%9F", "Ÿ") $text = StringReplace($text, "%A0", " ") $text = StringReplace($text, "%A1", "¡") $text = StringReplace($text, "%A2", "¢") $text = StringReplace($text, "%A3", "£") $text = StringReplace($text, "%A4", " ") $text = StringReplace($text, "%A5", "¥") $text = StringReplace($text, "%A6", "|") $text = StringReplace($text, "%A7", "§") $text = StringReplace($text, "%A8", "¨") $text = StringReplace($text, "%A9", "©") $text = StringReplace($text, "%AA", "ª") $text = StringReplace($text, "%AB", "«") $text = StringReplace($text, "%AC", "¬") $text = StringReplace($text, "%AD", "¯") $text = StringReplace($text, "%AE", "®") $text = StringReplace($text, "%AF", "¯") $text = StringReplace($text, "%B0", "°") $text = StringReplace($text, "%B1", "±") $text = StringReplace($text, "%B2", "²") $text = StringReplace($text, "%B3", "³") $text = StringReplace($text, "%B4", "´") $text = StringReplace($text, "%B5", "µ") $text = StringReplace($text, "%B6", "¶") $text = StringReplace($text, "%B7", "·") $text = StringReplace($text, "%B8", "¸") $text = StringReplace($text, "%B9", "¹") $text = StringReplace($text, "%BA", "º") $text = StringReplace($text, "%BB", "»") $text = StringReplace($text, "%BC", "¼") $text = StringReplace($text, "%BD", "½") $text = StringReplace($text, "%BE", "¾") $text = StringReplace($text, "%BF", "¿") $text = StringReplace($text, "%C0", "À") $text = StringReplace($text, "%C1", "Á") $text = StringReplace($text, "%C2", "Â") $text = StringReplace($text, "%C3", "Ã") $text = StringReplace($text, "%C4", "Ä") $text = StringReplace($text, "%C5", "Å") $text = StringReplace($text, "%C6", "Æ") $text = StringReplace($text, "%C7", "Ç") $text = StringReplace($text, "%C8", "È") $text = StringReplace($text, "%C9", "É") $text = StringReplace($text, "%CA", "Ê") $text = StringReplace($text, "%CB", "Ë") $text = StringReplace($text, "%CC", "Ì") $text = StringReplace($text, "%CD", "Í") $text = StringReplace($text, "%CE", "Î") $text = StringReplace($text, "%CF", "Ï") $text = StringReplace($text, "%D0", "Ð") $text = StringReplace($text, "%D1", "Ñ") $text = StringReplace($text, "%D2", "Ò") $text = StringReplace($text, "%D3", "Ó") $text = StringReplace($text, "%D4", "Ô") $text = StringReplace($text, "%D5", "Õ") $text = StringReplace($text, "%D6", "Ö") $text = StringReplace($text, "%D7", " ") $text = StringReplace($text, "%D8", "Ø") $text = StringReplace($text, "%D9", "Ù") $text = StringReplace($text, "%DA", "Ú") $text = StringReplace($text, "%DB", "Û") $text = StringReplace($text, "%DC", "Ü") $text = StringReplace($text, "%DD", "Ý") $text = StringReplace($text, "%DE", "Þ") $text = StringReplace($text, "%DF", "ß") $text = StringReplace($text, "%E0", "à") $text = StringReplace($text, "%E1", "á") $text = StringReplace($text, "%E2", "â") $text = StringReplace($text, "%E3", "ã") $text = StringReplace($text, "%E4", "ä") $text = StringReplace($text, "%E5", "å") $text = StringReplace($text, "%E6", "æ") $text = StringReplace($text, "%E7", "ç") $text = StringReplace($text, "%E8", "è") $text = StringReplace($text, "%E9", "é") $text = StringReplace($text, "%EA", "ê") $text = StringReplace($text, "%EB", "ë") $text = StringReplace($text, "%EC", "ì") $text = StringReplace($text, "%ED", "í") $text = StringReplace($text, "%EE", "î") $text = StringReplace($text, "%EF", "ï") $text = StringReplace($text, "%F0", "ð") $text = StringReplace($text, "%F1", "ñ") $text = StringReplace($text, "%F2", "ò") $text = StringReplace($text, "%F3", "ó") $text = StringReplace($text, "%F4", "ô") $text = StringReplace($text, "%F5", "õ") $text = StringReplace($text, "%F6", "ö") $text = StringReplace($text, "%F7", "÷") $text = StringReplace($text, "%F8", "ø") $text = StringReplace($text, "%F9", "ù") $text = StringReplace($text, "%FA", "ú") $text = StringReplace($text, "%FB", "û") $text = StringReplace($text, "%FC", "ü") $text = StringReplace($text, "%FD", "ý") $text = StringReplace($text, "%FE", "þ") $text = StringReplace($text, "%FF", "ÿ") return $text endfunc ; Strip HTML tags from a string.. ; func StripHTML($web_text, $lf=$LOG_LF) ; strip out the HTML.. $web_text = StringReplace($web_text, " ", " ") $web_text = StringRegExpReplace($web_text, ']*?>', '') $web_text = StringReplace($web_text, $lf & $lf, $lf) return StringStripWS($web_text,3) endfunc ; OrdAbbAppend() ; ; Used to append ordinal abbreviations onto numbers, for ; use in human-readable numeric strings, mainly dates. ; ; Feed it a number, OrdAbbAppend() returns that number, ; plus the appendment, as a string. e.g.. ; ; $foo = OrdAbbAppend(20) ; ; $foo = "20th" ; func OrdAbbAppend($d_str) if $d_str < 1 then SetError(1) return "" endif local $appends[10] $appends[0] = "th" $appends[1] = "st" $appends[2] = "nd" $appends[3] = "rd" $appends[4] = "th" $appends[5] = "th" $appends[6] = "th" $appends[7] = "th" $appends[8] = "th" $appends[9] = "th" if StringMid($d_str, StringLen($d_str)-1, 1) == 1 then $appends[1] = "th" $appends[2] = "th" $appends[3] = "th" endif return $d_str & $appends[StringRight($d_str, 1)] endfunc ; Convert seconds to readable H/M/S time.. ; func SecondsToDHMS($sec=0, $round=true) debug("SecondsToDHMS(sec) =>" & $sec & "<=", @ScriptLineNumber, 9);debug if $round then $sec = StringFormat("%.02f", $sec) if $sec < 0 then return -1 select case $sec < 61 return $sec & " seconds" case $sec < 3601 return StringFormat('%.01dm %.01ds', Mod(($sec / 60), 60), Mod($sec, 60)) case $sec < 86401 return StringFormat('%.01dh %.01dm %.01ds', Mod($sec / 3600, 24), Int(Mod(($sec / 60), 60)), Mod($sec, 60)) case else return StringFormat('%.01dd %.01dh %.01dm %.01ds', Mod($sec / 86400, 7), _ Mod($sec / 3600, 24), Int(Mod(($sec / 60), 60)), Mod($sec, 60)) endselect endfunc ; ; Convert seconds to readable D/H/M/S time.. ; ; ; func SecondsToDHMS($sec=0) ; if $sec < 0 then return -1 ; select ; case $sec < 61 ; return StringFormat("%.02f", $sec) & " seconds" ; case $sec < 3601 ; return StringFormat('%.01dm %.01ds', Mod(($sec / 60), 60), Mod($sec, 60)) ; case $sec < 86401 ; return StringFormat('%.01dh %.01dm %.01ds', Mod($sec / 3600, 24), Int(Mod(($sec / 60), 60)), Mod($sec, 60)) ; case else ; return StringFormat('%.01dd %.01dh %.01dm %.01ds', Mod($sec / 86400, 7), _ ; Mod($sec / 3600, 24), Int(Mod(($sec / 60), 60)), Mod($sec, 60)) ; endselect ; endfunc ; ; UserTimeToUnitTime ; ; This is an emtremely limited function designed for specific back-end tasks. ; If you want to mess with time stuff, use the functions inside . ; ; This converts "user" (Human) time to an integer unit of time. ; Input a string indicating a time, returns that time in some unit. Here's ms.. ; ; input Returned Milliseconds ; ------ --------------------- ; 1000 => 1000 ; 1000ms => 1000 ; 1s => 1000 ; 1m => 60000 ; 1h => 3600000 ; 1d => 86400000 ; ; The second parameter controls the units which will be returned. ; By default it is milliseconds. You can also ask for s, m, h & d. ; ; You can specify "full info" (3rd parameter) which will have UserTimeToUnitTime ; return an array of two values, [0] = the final units, [1] = the user (human) ; unit they arrived in, e.g. "h". ; func UserTimeToUnitTime($user_time, $time_unit="ms", $full_info=false) local $ret_array[2] = [0,"ms"] if IsNumber($user_time) then if $full_info then $ret_array[0] = $user_time return $ret_array else return $user_time endif endif select case StringRight($user_time, 2) = "ms" CRT($user_time, "ms") ; leave number as-is case StringRight($user_time, 1) = "s" CRT($user_time, "s") $user_time *= 1000 case StringRight($user_time, 1) = "m" CRT($user_time, "m") $user_time *= (1000*60) case StringRight($user_time, 1) = "h" CRT($user_time, "h") $user_time *= (1000*60*60) case StringRight($user_time, 1) = "d" CRT($user_time, "d") $user_time *= (1000*60*60*24) endselect switch $time_unit ; case "ms" ; also 1st for quickness ; $user_time = $user_time case "s" $user_time = $user_time/1000 $ret_array[1] = "s" case "m" $user_time = $user_time/1000/60 $ret_array[1] = "m" case "h" $user_time = $user_time/1000/60/60 $ret_array[1] = "h" case "d" $user_time = $user_time/1000/60/60/24 $ret_array[1] = "h" endswitch $ret_array[0] = Number($user_time) if $full_info then return $ret_array else return $user_time endif endfunc ; 24h > Human Time > 24h.. ; ; HourToHumanTime() ; ; Feed it a 24-hour format hour (e.g. "16"). ; Returns a 1-dimensional array with two values.. [4, "pm"] ; ; [0] = hour (integer in 12-hour clock format) ; [1] = am/pm (string) ; func HourToHumanTime($24hour) local $human_hour[2] $human_hour[0] = Number($24hour) ; 02 -> 2 $human_hour[1] = "am" if $24hour > 11 then $human_hour[1] = "pm" if $24hour = 00 then $human_hour[0] = 12 if $24hour > 12 then $human_hour[0] -= 12 $human_hour[0] = int($human_hour[0]) return $human_hour endfunc ; And the reverse.. ; ; Feed it the twelve-hour-clock format hour, and the am/pm string ("am" or "pm") ; Returns an integer (the hour, in 24 hour clock format, padded with a zero, if ; necessary), e.g.. ; ; HumanTimeToHour(3, "am") = 03 ; HumanTimeToHour(3, "pm") = 15 ; ; I use two variables here because a) it's clearer, and b) ; I've been gagging to use the word "puter" in a variable for ages. ; func HumanTimeToHour($12hour, $am_pm) local $puter_hours switch $am_pm case "am" if $12hour = 12 then $puter_hours = 0 else $puter_hours = $12hour endif case "pm" if $12hour = 12 then $puter_hours = 12 else $puter_hours = $12hour + 12 endif endswitch return StringFormat("%02d", $puter_hours) endfunc ; Convert a plain ASCII file to Unicode.. func MakeUnicodeFile($file) local $non_unicode_text = FileRead($file) ; only ASCII will produce the same length string as file the size.. if FileGetSize($file) = StringLen($non_unicode_text) then local $unicode_file = FileOpen($file, 2 + 32) ; erase + UTF16 FileWrite($unicode_file, $non_unicode_text) return true endif ; or else something bad happened.. return false endfunc ; Normalize all line-endings ; to @CRLF, or whatever.. ; this is the fastest, bestest, simplest method.. func UnifyCRLF($some_text, $LF=@CRLF) return StringRegExpReplace($some_text, "\R", $LF) ; return StringRegExpReplace($string, '(*BSR_ANYCRLF)\R', @CRLF) endfunc ; Convert newlines from preferences "\n" to actual Linefeeds, for use in logs, ; console display, etc.. Also works the other way around. ; ; Conversion happens ByRef, so simply do.. ; ; ConvertNewlines($string) ; func ConvertNewlines(ByRef $pref_string, $reverse=false, $LF=$LOG_LF) if $reverse then $pref_string = StringReplace($pref_string, $LF, "\n") else $pref_string = StringReplace($pref_string, "\n", $LF) endif endfunc ; Feed it a number (which is always a MB value), returns value + " MB". If the ; number is > 1024 MB, it is (optionally) converted and returned + " GB", then ; " TB". func FormatMB($mb, $round=0, $array=false) local $return, $unit $mb = Number($mb) select case $mb = 0 $return = 0 case $mb < 1024 $return = Round($mb, $round) $unit = "MB" case $mb >= 1048576 $return = Round($mb / 1048576, $round) $unit = "TB" case $mb >= 1024 $return = Round($mb / 1024, $round) $unit = "GB" endselect if $array then local $ret[2] $ret[0] = $mb $ret[1] = $unit return $ret endif return $return & " " & $unit endfunc func BytesToByteUnit($bytes_value, $unit_required, $round=2) debug("", @ScriptLineNumber, 7);debug debug("BytesToByteUnit(" & $bytes_value & "," & $unit_required & "," & $round & ")", @ScriptLineNumber, 7);debug local $return = $bytes_value switch $unit_required ;case "B" case "KB"; Kilobyte $return = Round($bytes_value/1024, $round) case "MB" ; Megabyte $return = Round($bytes_value/1048576, $round) case "GB" ; Gigabyte $return = Round($bytes_value/1.073742e+009, $round) case "TB" ; Terabyte $return = Round($bytes_value/1.099512e+012, $round) case "PB" ; Petabyte $return = Round($bytes_value/1.1259e+015, $round) case "EB" ; Exabyte $return = Round($bytes_value/1.152922e+018, $round) case "ZB" ; Zettabyte $return = Round($bytes_value/1.180592e+021, $round) case "YB" ; Yottabyte (named after Yoda!) $return = Round($bytes_value/1.208926e+024, $round) endswitch debug("Returning: =>" & $return & "<=", @ScriptLineNumber, 7);debug return $return endfunc ; Create a random String. ; Returns a string of "random" upper and lower case letters to the specified length. ; Only letters are returned, no special characters. func MakeRandomString($length=32, $seed=@Min*@Sec*@MSec) debug("", @ScriptLineNumber, 7);debug debug("MakeRandomString(" & $seed & ")", @ScriptLineNumber, 7);debug SRandom($seed) local $a[$length] local $x = 0 while $a[$length-1] = "" local $tmp = Chr(Random(65, 122, 1)) if StringIsAlpha($tmp) then $a[$x] = Asc($tmp) $x += 1 endif wend $a = StringFromASCIIArray($a) debug("MakeRandomString() returning: =>" & $a & "<=", @ScriptLineNumber, 7);debug return $a endfunc ; local $first_done = false ; if not $params then $params = 12 ; for $i = 1 to Random($random_name_lower_limit, $params, 1) ; if not $first_done then ; $new_name &= Chr(Random(65, 90, 1)) ; $first_done = true ; endif ; $new_name &= Chr(Random(97, 122, 1)) ; next ; Create a random "X-String", which is hexadecimal digits (0-9, A-F) ; Works great, but could obviously be improved! func MakeRandomXString($length=32, $seed=@Min*@Sec*@MSec) SRandom($seed) local $a[$length] local $x = 0 while $a[$length-1] = "" local $tmp = Chr(Random(48, 71, 1)) ; CAPITALS if StringIsXDigit($tmp) then $a[$x] = Asc($tmp) $x += 1 endif wend $a = StringFromASCIIArray($a) debug("MakeRandomXString() returning: =>" & $a & "<=", @ScriptLineNumber, 7);debug return $a endfunc ; From Color-Pickin-Chooser.. ; ; ConvertColorValue() ; ; ConvertColorValue(RGB_color{HEX}, mode{TEXT}, add_prefix{BOOL}, index{INT} (0=return full 6 digits), lowercase{BOOL}) ; ; To get this.. Use any of these.. ; ------------- -------------------------------------------------------- ; RGB Integer: "i", "RGB Integer", "RGB Int" or "int". ; AutoIt RGB "a", "Autoit RGB Hex", "Autoit RGB", "AutoIt Hex", or "AutoIt". ; AutoIt BGR "b", "Autoit BGR Hex", "Autoit BGR", "BGR Hex" or "bgr". ; Delphi Hex "d", "Delphi" or "Delphi Hex". ; Visual C++ BGR "v", "vc", "Visual C++ Hex", "Visual C++ BGR", "Visual C++", "Visual C++ BGR Hex" or "C++". ; RGB Float "RGB Float", "float" or "f". ; HSL "h", "Hue/Sat/Lum", "HSL" or "h/s/l". ; CMYK "k", "cmyk" or "c/m/y/k". ; Web Hex "w", "Web Hex", "Web", or "Hex". func ConvertColorValue($color, $mode = "web", $prefix = false, $index = 0, $lowercase = $off) if StringLeft($color, 1) = "#" Then $color = StringTrimLeft($color, 1) local $pre = "" switch $mode case "i", "RGB Integer", "RGB Int", "int" switch $index case 0 $color = Dec(StringLeft($color, 2)) & "," & Dec(StringMid($color, 3, 2)) & "," & Dec(StringRight($color, 2)) case 1 return Dec(StringLeft($color, 2)) case 2 return Dec(StringMid($color, 3, 2)) case 3 return Dec(StringRight($color, 2)) endswitch case "a", "Autoit RGB Hex", "Autoit RGB", "AutoIt Hex", "AutoIt" $color = "0x" & $color case "b", "Autoit BGR Hex", "Autoit BGR", "BGR Hex", "bgr" $color = "0x" & StringRight($color, 2) & StringMid($color, 3, 2) & StringLeft($color, 2) case "d", "Delphi", "Delphi Hex" $color = "00" & StringRight($color, 2) & StringMid($color, 3, 2) & StringLeft($color, 2) $pre = "$" case "v", "vc", "Visual C++ Hex", "Visual C++ BGR", "Visual C++", "Visual C++ BGR Hex", "C++" $color = "0x00" & StringRight($color, 2) & StringMid($color, 3, 2) & StringLeft($color, 2) case "RGB Float", "float", "f" local $r = Round((1 / 255) * Dec(StringLeft($color, 2)), 2) local $g = Round((1 / 255) * Dec(StringMid($color, 3, 2)), 2) local $b = Round((1 / 255) * Dec(StringRight($color, 2)), 2) $color = StringFormat("%#.2f", $r) & "," & StringFormat("%#.2f", $g) & "," & StringFormat("%#.2f", $b) case "h", "Hue/Sat/Lum", "HSL", "h/s/l" $color = RGBtoHSL($color, ",", 100) case "k", "cmyk", "c/m/y/k" if $prefix = 1 then $color = RGBtoCMYK($color, true) else $color = RGBtoCMYK($color) endif case "w", "Web Hex", "Web", "Hex" $pre = "#" endswitch if not $prefix or $prefix = 4 then $pre = "" if $lowercase = $on then $color = StringLower($color) return $pre & $color endfunc Func RGBtoCMYK($rgb_color, $norm = 0) local $rc_r = ConvertColorValue($rgb_color, "i", 0, 1) / 255 local $rc_g = ConvertColorValue($rgb_color, "i", 0, 2) / 255 local $rc_b = ConvertColorValue($rgb_color, "i", 0, 3) / 255 local $k = MinMin(1 - $rc_r, 1 - $rc_g, 1 - $rc_b) local $c = (1 - $rc_r - $k) / (1 - $k) local $m = (1 - $rc_g - $k) / (1 - $k) local $y = (1 - $rc_b - $k) / (1 - $k) if $norm then return Round($c * 100, 1) & "," & Round($m * 100, 1) & "," & Round($y * 100, 1) & "," & Round($k * 100, 1) else return Round($c, 3) & "," & Round($m, 3) & "," & Round($y, 3) & "," & Round($k, 3) endif endfunc func RGBtoHSL($rgb_color, $idx = "", $simple_array = False, $hsl_scale = 1) local $rh_r = ConvertColorValue($rgb_color, "i", 0, 1) / 255 local $rh_g = ConvertColorValue($rgb_color, "i", 0, 2) / 255 local $rh_b = ConvertColorValue($rgb_color, "i", 0, 3) / 255 local $rh_min = MinMin($rh_r, $rh_g, $rh_b) local $rh_max = MaxMax($rh_r, $rh_g, $rh_b) local $rh_delta = $rh_max - $rh_min if $idx <> 1 then local $rh_lightness = ($rh_min + $rh_max) / 2 if $idx = 3 then return Round($rh_lightness * $hsl_scale, 2) local $rh_saturation = 0 if $rh_lightness > 0 and $rh_lightness < 1 then If $rh_lightness < 0.5 then $rh_saturation = $rh_delta / (2 * $rh_lightness) else $rh_saturation = $rh_delta / (2 - 2 * $rh_lightness) endif endif If $idx = 2 then return Round($rh_saturation * $hsl_scale, 2) endif local $rh_hue = 0 if $rh_delta > 0 then if $rh_max = $rh_r and $rh_max <> $rh_g then $rh_hue += ($rh_g - $rh_b) / $rh_delta endif if $rh_max = $rh_g and $rh_max <> $rh_b then $rh_hue += 2 + ($rh_b - $rh_r) / $rh_delta endif if $rh_max = $rh_b and $rh_max <> $rh_r then $rh_hue += 4 + ($rh_r - $rh_g) / $rh_delta endif $rh_hue *= 60 endif if $rh_hue < 0 then $rh_hue += 360 if $idx = 1 then return Round($rh_hue) local $do_string = true if not $idx then $idx = "," $do_string = false endif local $hsl_arr[3] $hsl_arr[0] = Round($rh_hue) $hsl_arr[1] = Round($rh_saturation * $hsl_scale, 2) $hsl_arr[2] = Round($rh_lightness * $hsl_scale, 2) local $hsl = $hsl_arr[0] & $idx & $hsl_arr[1] & $idx & $hsl_arr[2] if $do_string then return $hsl if $simple_array then return $hsl_arr return StringSplit($hsl, $idx) endfunc ; Send the $string after the Shift, Alt, Ctrl & Win (L or R) keys are released. ; Optionally, give a warning after 1 sec if any of those keys are still down. ; $flag is the same as for Send(). func SendWait($string, $flag=0, $warn="You don't need to hold the modifier keys down for so long!") ; debug("", @ScriptLineNumber, 7);debug ; debug("string(" & $string & "," & $flag & "," & $warn & ")", @ScriptLineNumber, 7);debug $am_sending = true local $HKt = TimerInit() while _IsPressed("10") or _IsPressed("11") or _IsPressed("12") or _IsPressed("5B") or _IsPressed("5C") if $warn <> "" and TimerDiff($HKt) > 1000 then debug("SendWait(HOLDING_KEYS_WARNING)", @ScriptLineNumber, 7);debug if IniRead($ini_path, $my_name, "holding_keys_warning", $OFF) = $OFF then MsgBox($MB_TOPMOST, "Note..", $warn) ; 0x00040000 IniWrite($ini_path, $my_name, "holding_keys_warning", $ON) endif endif Sleep(50) wend Send($string, $flag) $am_sending = false return $string endfunc ; Fancy Custom Input Box.. (accepts drag&drop of files) ; returns: ; Success: The value input by the user. ; @error contains the X coordinate of the window when closed ; @extended contains the X coordinate of the window when closed ; ; If you leave the width at the default (-1), CorzFancyInputBox will ; save and restore its own width settings. Or else specify your own. ; ; Failure: Empty "" value. ; @error contains a non-0 value.. ; ; 1 = The Cancel/Close button was pushed. ; 2 = The Timeout time was reached. ; ; As well as being a drop-in replacement for InputBox, you can optionally supply ; the full path to an ini file and section name to have CorzFancyInputBox save ; the x/y/width specifications for the inputbox, recall them the next time the ; user accesses the same inputbox. ; ; If you are using the defaults ($ini_path/$my_name), you can leave out the ini prefs. ; ; ; NOTE: CorzFancyInputBox() uses the title to create a preference name. If you ; send 100 separate titles for say, 100 buttons, you will create 100 preferences (x3!) ; ; In other words, best to put any control-specific text into the *prompt*. ; func CorzFancyInputBox($title, $prompt, $default_text="", $pass=default, $ib_w=default, $ib_h=default, $ib_x=default, $ib_y=default, _ $timeout=default, $gui_ex=false, $style=default, $inipath=default, $sectionname=default, $sel1=default, $sel2=default) debug("CorzFancyInputBox(title: " & $title & ", prompt: " & $prompt & ", default_text: " & $default_text & ", pass: " & $pass & ", ib_w: " & $ib_w & ", ib_h: " & $ib_h & ", ib_x: " & $ib_x & ", ib_y: " & $ib_y & ", timeout: " & $timeout & ", gui_ex: " & $gui_ex & ", style: " & $style & ", inipath: " & $inipath & ", sectionname: " & $sectionname & ", sel1: " & $sel1 & ", sel2: " & $sel2 & ")...", @ScriptLineNumber, 7);debug local $previous_event_mode = AutoItSetOption("GUIOnEventMode", 0) local $previous_coord_mode = AutoItSetOption("GUICoordMode", 1) local $pref_name = CleanPrefName($title) if not $inipath or $inipath = default then $inipath = $ini_path if not $sectionname or $sectionname = default then $sectionname = $my_name if not $style or $style = default then $style = -1 if not $pass or $pass = default then $pass = "" if $ib_x = Default then $ib_x = -1 if $ib_y = default then $ib_y = -1 if $ib_h = default then $ib_h = 96 if $ib_w = default then $ib_w = @DesktopWidth/2 $ib_x = IniRead($inipath, $sectionname, "inputbox_" & $pref_name & "_x", $ib_x) $ib_y = IniRead($inipath, $sectionname, "inputbox_" & $pref_name & "_y", $ib_y) $ib_w = IniRead($inipath, $sectionname, "inputbox_" & $pref_name & "_width", $ib_w) if not $ib_x then $ib_x = -1 if not $ib_y then $ib_y = -1 if not $ib_h then $ib_h = 96 if not $ib_w then $ib_w = @DesktopWidth/2 debug("$ib_x: " & $ib_x, @ScriptLineNumber, 8);debug debug("$ib_y: " & $ib_y, @ScriptLineNumber, 8);debug debug("$ib_h: " & $ib_h, @ScriptLineNumber, 8);debug debug("$ib_w: " & $ib_w, @ScriptLineNumber, 8);debug if $timeout = default then $timeout = 0 if $sel1 = default then $sel1 = 0 if $sel2 = default then $sel2 = -1 local $line = $prompt if StringInStr($prompt, $MSG_LF) then ; Measure length of first line, up to the linebreak.. $line = StringMid($line, 1, StringInStr($line, $MSG_LF)-1) endif debug("line to length-check: " & $line, @ScriptLineNumber, 8);debug local $line_length = StringLen($line) debug("$line_length: " & $line_length, @ScriptLineNumber, 8);debug local $min_w = $line_length * 7.2 ; MAGIC! debug("$min_w: " & $min_w, @ScriptLineNumber, 8);debug if $ib_w < $min_w then $ib_w = $min_w StringReplace($prompt, $MSG_LF, $MSG_LF) local $line_count = @Extended + 1 debug("$line_count: " & $line_count, @ScriptLineNumber, 8);debug local $return = false local $error = 0 local $inputstyle = $ES_AUTOHSCROLL local $exStyle = BitOr($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST) if $style = -1 then $style = BitOr($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU, $WS_SIZEBOX) if $pass <> 0 then $inputstyle = BitOr($ES_AUTOHSCROLL, $ES_PASSWORD) ; Make the dialog.. local $ib_GUI = GUICreate($title, $ib_w, $ib_h, $ib_x, $ib_y, $style, $exStyle, $gui_ex) local $lab_prompt = GUICtrlCreateLabel($prompt, 10, 5, $ib_w-10, 16*$line_count) GUICtrlSetFont(-1, 10) local $but_OK = GUICtrlCreateButton("OK", $ib_w-45, $ib_h-30, 40, 22, $BS_DEFPUSHBUTTON) GUICtrlSetState(-1, $GUI_ONTOP) GUICtrlSetTip(-1, "Save the setting." & $MSG_LF & _ "When you click this button (and the input is not empty)," & $MSG_LF & _ "the size and position of this dialog will be saved for future use.") local $but_Cancel = GUICtrlCreateButton("Cancel", 5, $ib_h-30, 60, 22) GUICtrlSetState(-1, $GUI_ONTOP) GUICtrlSetTip(-1, "Cancel this dialog." & $MSG_LF & _ "Do not save the input." & $MSG_LF & _ "Do not save dialog's size and position.") local $ib_font = IniRead($inipath, $sectionname, "inputbox_font", "Consolas") local $inp_MyID = GUICtrlCreateInput($default_text, 70, $ib_h-30, $ib_w-125, 22, $inputstyle) GUICtrlSetState(-1, $GUI_FOCUS) GUICtrlSetFont(-1, 10 , 400, "", $ib_font) GUICtrlSetState(-1, $GUI_DROPACCEPTED) GUICtrlSetTip(-1, $prompt) GUICtrlSetResizing($lab_prompt, $GUI_DOCKALL) GUICtrlSetResizing($but_OK, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKRIGHT) GUICtrlSetResizing($but_Cancel, $GUI_DOCKSTATEBAR+$GUI_DOCKLEFT+$GUI_DOCKWIDTH) GUICtrlSetResizing($inp_MyID, $GUI_DOCKSTATEBAR+$GUI_DOCKLEFT+$GUI_DOCKRIGHT) GUISetState(@SW_SHOW, $ib_GUI) _GUICtrlEdit_SetSel($inp_MyID, $sel1, $sel2) WinMove($title, "", default, default, $ib_w, $ib_h) if $timeout <> 0 then local $dialog_begin = TimerInit() local $size_array while true switch GUIGetMsg() case $GUI_EVENT_RESIZED $size_array = WinGetPos($title) if not IsArray($size_array) then continueloop local $my_width = $size_array[2] if $size_array[2] < $min_w then WinMove($title, "", default, default, $min_w, $ib_h) $my_width = $min_w endif if $size_array[3] <> $ib_h then WinMove($title, "", default, default, $my_width, $ib_h) case $GUI_EVENT_CLOSE, $but_Cancel $return = false $error = 1 exitloop case $but_OK $return = StringStripWS(GUICtrlRead($inp_MyID), 3) exitloop endswitch if $timeout <> 0 then if TimerDiff($dialog_begin)/1000 > $timeout then $return = false $error = 2 exitloop endif endif wend ; Return X & Y in @error & @extended.. ? if $return then local $x_coord = -1, $y_coord = -1, $ib_width $size_array = WinGetPos($title) ; 0-1-2-3:x-y-w-h if IsArray($size_array) then $x_coord = $size_array[0] $y_coord = $size_array[1] $ib_width = $size_array[2] endif endif AutoItSetOption("GUIOnEventMode", $previous_event_mode) AutoItSetOption("GUICoordMode", $previous_coord_mode) GUIDelete($ib_GUI) if $return then ; Only write prefs if the user actually changed the position/dimensions from the defaults.. if $x_coord and $x_coord <> -1 then IniWrite($inipath, $sectionname, "inputbox_" & $pref_name & "_x", $x_coord) if $y_coord and $y_coord <> -1 then IniWrite($inipath, $sectionname, "inputbox_" & $pref_name & "_y", $y_coord) if $ib_width and $ib_width <> @DesktopWidth/2 then IniWrite($inipath, $sectionname, "inputbox_" & $pref_name & "_width", $ib_width) endif return $return endif return SetError($error, 0, "") endfunc #cs CorzFancyMsgBox() A replacement for MsgBox, except with a checkbox for the user to never be asked about the issue again. It's basic, but does the job. Returns the number of the button the user clicked (1, 2, 3 or 4). You can set the usual $hwnd and styles (defaults should be fine). It will resize its height to fit the text sent (ish). You can have from one to four buttons, sending the text required for each button, or blank to produce no button. Obviously, if you want only two buttons, you set the value of the first two and leave the last two blank. If you set, for example, the value of the first and last buttons, leaving 2 and 3 blank, you will get four buttons, two of which will be blank! You can also set which is the default button (1, 2, 3 or 4). CorzFancyMsgBox() will store the X & Y position of the dialog for future instances. Each dialog gets its own settings (the pref name being derived from the title of the message box). You can supply an ini path and section name to store the prefs, otherwise CorzFancyMsgBox() will use the app default ini and main app [name] section. If the user checks the "Always perform the chosen action" box, the user's choice is saved to the ini file and in future CorzFancyMsgBox() will simply return the pre-saved value. You can also set an icon (full path, unless it's in your PATH) and icon index (note: most icons inside shell32.dll use -negative IDs).. Handy shell32.dll icons.. ID Icon ----- ------------- 24 question mark -211 question mark 3D -28/28 stop (appliance) -220 stop (no entry) -237 warning triangle -278 information (i) old 2D (default icon) -317 cog (completely square, no transparency required!) -239 Recycle CorzFancyMsgBox() returns: The number of the button the user clicked (1, 2, 3 or 4). If the user clicked a button, @error and @extended are set to the final X and Y positions of the dialog, respectively. FYI. If the user cancels out of the dialog, @error will be set to 1 and the function will return 0 as the value. Examples: CorzFancyMsgBox("This is a notice", "You never have to see this notice again") $debug = CorzFancyMsgBox("Really Overwrite Files?", "Many triggers and tasks have been found to already exist in KeyBind.ini. Overwrite?" , 60, false, -1, $ini_path, "Test", "Yes", "No", "", "", 2, "shell32.dll", -237) debug("$debug: =>" & $debug & "<=", @ScriptLineNumber, 7);debug #ce func CorzFancyMsgBox($title, $text, $timeout=0, $gui_ex=false, $style=-1, $inipath=$ini_path, _ $sectionname=$my_name, $butt1_txt="OK", $butt2_txt="", $butt3_txt="", $butt4_txt="", _ $default_butt=1, $icon_path="shell32.dll", $icon_id=-278) debug("", @ScriptLineNumber, 7);debug debug("CorzFancyMsgBox(" & $title & "," & $text & "," & $gui_ex & "," & $style & "," & $inipath & "," & $sectionname & "," & $butt1_txt & "," & $butt2_txt & "," & $butt3_txt & "," & $butt4_txt & "," & $default_butt & "," & $icon_path & "," & $icon_id & ")", @ScriptLineNumber, 7);debug local $pref_name = CleanPrefName($title) ; There may be a predetermined response.. local $dont_bug_me = IniRead($inipath, $sectionname, $pref_name & "_dont_bug_me", 0) debug("$dont_bug_me: =>" & $dont_bug_me & "<=", @ScriptLineNumber, 7);debug if $dont_bug_me <> 0 then return $dont_bug_me ; the number of the saved response if $timeout = default then $timeout = 0 if $gui_ex = default then $gui_ex = false if $style = default then $style = -1 if $inipath = default then $inipath = $ini_path if $butt1_txt = default then $butt1_txt = "OK" if not $butt1_txt then $butt1_txt = "OK" if $sectionname = default then $sectionname = $my_name local $dt_pushed local $dt_warn_count = 0 local $error, $extended local $last_event_mode = AutoItSetOption("GUIOnEventMode", 0) local $last_coord_mode = AutoItSetOption("GUICoordMode", 0) ; relative to last control ; work out some sizes and positions.. if $style = -1 then $style = BitOr($WS_CAPTION, $WS_SYSMENU, $WS_SIZEBOX) local $exStyle = BitOr($WS_EX_TOPMOST, $GUI_WS_EX_PARENTDRAG) local $dt_min_w = 400 local $dt_min_h = 130 local $dt_w local $dt_h = $dt_min_h ; Not very clever. Works well within our limited range. (under 1000 characters) local $text_len = StringLen($text) debug("$text_len: =>" & $text_len & "<=", @ScriptLineNumber, 7);debug local $size_array local $addin_height = 0 while $addin_height < $text_len $dt_h += 22 ; add these pixels to the GUI height $addin_height += 50 ; for every extra this many characters text length (slightly magic!) $dt_min_h += 22 wend local $butt_width local $dt_x = IniRead($inipath, $sectionname, "msgbox_" & $pref_name & "_x", -1) local $dt_y = IniRead($inipath, $sectionname, "msgbox_" & $pref_name & "_y", -1) $dt_w = IniRead($inipath, $sectionname, "msgbox_" & $pref_name & "_width", $dt_min_w) ; create the GUI.. ; local $dt_GUI = GUICreate($title, $dt_w, $dt_h, $dt_x, $dt_y, $style, $exStyle, $gui_ex) GUISetFont(-1, 10, 400, 0, "Segoe UI", 5) GUISetBkColor(0xFFFFFF) ; icon_path local $icon_width = 0 if $icon_path then $icon_width = 36 ; CheckBox:: ; Don't bug me again about this!! ; GUISetCoord(10, $dt_h-66) local $check_dont_bug = GUICtrlCreateCheckBox("Always perform the chosen action.", 0, 0, 220, default, _ Bitor($WS_TABSTOP, $BS_AUTOCHECKBOX), BitOr($WS_EX_TOPMOST, $WS_EX_TRANSPARENT, $GUI_WS_EX_PARENTDRAG)) GUICtrlSetFont(-1, 8.5, 400, 0, "Segoe UI", 5) GUICtrlSetBkColor(-1, 0xFFFFFF) GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM+$GUI_DOCKSIZE+$GUI_DOCKLEFT) ; the "text" label.. ; GUISetCoord(15+$icon_width, 6) GUICtrlCreatelabel($text, 0, 0, $dt_w-30-$icon_width, $dt_h-53, _ BitOr($SS_NOTIFY, $SS_LEFT), $GUI_WS_EX_PARENTDRAG) GUICtrlSetBkColor(-1, 0xFFFFFF) ; GUICtrlSetBkColor(-1, 0xFF0000) GUICtrlSetResizing(-1, $GUI_DOCKBORDERS) GUICtrlSetFont(-1, 10, 400, 0, "Segoe UI", 5) GUICtrlSetTip(-1, " You can click and drag the entire window around quickly from here ") ; icon "shell32.dll" ; if $icon_path then GUISetCoord(10, 10) GUICtrlCreateIcon("", "", 0, -2, 32, 32, $SS_ICON, $WS_EX_TRANSPARENT) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) GUICtrlSetTip(-1, " this is an image ") GUICtrlSetState(-1,$GUI_DISABLE) GUICtrlSetImage(-1, $icon_path, $icon_id) GUICtrlSetResizing(-1, $GUI_DOCKSIZE+$GUI_DOCKLEFT+$GUI_DOCKTOP) endif ; The Stripe ; (F0F0F0).. ; GUISetCoord(50,$dt_h-43) ; $label_stripe = GUICtrlCreatelabel("", 0, 0, $dt_w, $dt_h, 0, $GUI_WS_EX_PARENTDRAG) GUICtrlCreatelabel(" ", 0, 0, $dt_w-100, 2, 0, $GUI_WS_EX_PARENTDRAG) GUICtrlSetBkColor(-1, 0xF0F0F0) GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM+$GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKHEIGHT) ; Make The Buttons.. ; local $buttons = 1 if $butt2_txt then $buttons = 2 if $butt3_txt then $buttons = 3 if $butt4_txt then $buttons = 4 local $buttons_array[$buttons+1][2] = [[$buttons]] local $buttonstyle = BitOr($BS_CENTER, $BS_FLAT, $BS_VCENTER, $BS_NOTIFY, $WS_TABSTOP) local $total_width = 0, $gap = 7 local $button_top = $dt_h-33 local $i = 1 ; [0] => Button ID, [1] => text of button while $i <= $buttons $buttons_array[$i][1] = Eval("butt" & $i & "_txt") ; screw the manual! It works! $i += 1 wend ; create buttons, as required.. for $i = $buttons_array[0][0] to 1 step -1 $butt_width = (StringLen($buttons_array[$i][1])*8)+20 GUISetCoord($dt_w-$total_width-$butt_width-$gap, $button_top) $buttons_array[$i][0] = GUICtrlCreateButton($buttons_array[$i][1], 0, 0, $butt_width, 25, $buttonstyle) GUICtrlSetFont(-1, 9, 400, 0, "Segoe UI", 5) GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM+$GUI_DOCKSIZE+$GUI_DOCKRIGHT) $total_width += $butt_width+$gap if $i = $default_butt then ControlFocus($dt_GUI, "", $buttons_array[$i][0]) next ; Another Dragable Area.. ; GUISetCoord(0,$button_top-8) GUICtrlCreateLabel("", 0, 0, $dt_w-$total_width-2, 50, 0, $GUI_WS_EX_PARENTDRAG) GUICtrlSetTip(-1, " Yes, you can click and drag the entire window around quickly from here, too ") GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM+$GUI_DOCKSIZE+$GUI_DOCKLEFT+$GUI_DOCKRIGHT) ; Show the dialog.. ; GUISetState(@SW_SHOW, $dt_GUI) WinMove($dt_GUI, "", default, default, $dt_w, $dt_h) local $msg while true $dt_pushed = 0 $msg = GUIGetMsg() for $i = 1 to $buttons_array[0][0] if $msg = $buttons_array[$i][0] then $dt_pushed = $i exitloop endif next if $dt_pushed then exitloop else select case $msg = $GUI_EVENT_CLOSE exitloop case $msg = $GUI_EVENT_RESIZED $size_array = WinGetPos($dt_GUI) if not IsArray($size_array) then return false if $size_array[2] < $dt_min_w then WinMove($dt_GUI, "", default, default, $dt_min_w, $size_array[3]) if $size_array[3] < $dt_min_h then WinMove($dt_GUI, "", default, default, $size_array[2], $dt_min_h) case $msg = $check_dont_bug if GUICtrlread($check_dont_bug) = $ON then $dt_warn_count += 1 local $message = "From now on you will no longer be notified and " & $my_name & _ " will just get on with doing whatever YOU CHOOSE NEXT..." if $dt_warn_count > 1 then $message = "You have been warned!" if $dt_warn_count > 3 then $message = "Oh! Just DECIDE will you!" MsgBox($MB_ICONWARNING+$MB_SYSTEMMODAL, "This is PERMANENT!!", $message) endif endselect endif Sleep(50) wend ; User clicked a button (didn't cancel out) ; if $dt_pushed = 0 then $error = 1 ; user cancelled out else debug("CorzFancyMsgBox() User Clicked Button: " & $dt_pushed, @ScriptLineNumber, 7);debug debug("CorzFancyMsgBox() User Chooses Option: " & $buttons_array[$dt_pushed][1], @ScriptLineNumber, 7);debug ; There may already be a response for this dialog.. ; Re-use $dont_bug_me. $dont_bug_me = GUICtrlRead($check_dont_bug) if $dont_bug_me = $ON then IniWrite($inipath, $sectionname, $pref_name & "_dont_bug_me", $dt_pushed) else ; If you are never seeing this dialog again you don't need this lot.. $size_array = WinGetPos($dt_GUI) ; 0-1-2-3:x-y-w-h if IsArray($size_array) then IniWrite($inipath, $sectionname, "msgbox_" & $pref_name & "_x", $size_array[0]) IniWrite($inipath, $sectionname, "msgbox_" & $pref_name & "_y", $size_array[1]) IniWrite($inipath, $sectionname, "msgbox_" & $pref_name & "_width", $size_array[2]) $error = $size_array[0] $extended = $size_array[1] endif endif endif AutoItSetOption("GUIOnEventMode", $last_event_mode) AutoItSetOption("GUICoordMode", $last_coord_mode) GUIDelete($dt_GUI) return SetError($error, $extended, $dt_pushed) endfunc ; Event-Mode version of above function.. ; func CorzFancyMsgBoxEM($title, $text, $timeout=0, $gui_ex=false, $style=-1, $inipath=$ini_path, _ $sectionname=$my_name, $butt1_txt="OK", $butt2_txt="", $butt3_txt="", $butt4_txt="", _ $default_butt=1, $icon_path="shell32.dll", $icon_id=-278) debug("", @ScriptLineNumber, 7);debug debug("CorzFancyMsgBoxEM(" & $title & "," & $text & "," & $gui_ex & "," & $style & "," & $inipath & "," & $sectionname & "," & $butt1_txt & "," & $butt2_txt & "," & $butt3_txt & "," & $butt4_txt & "," & $default_butt & "," & $icon_path & "," & $icon_id & ")", @ScriptLineNumber, 7);debug local $pref_name = CleanPrefName($title) ; There may be a predetermined response.. local $dont_bug_me = IniRead($inipath, $sectionname, $pref_name & "_dont_bug_me", 0) debug("$dont_bug_me: =>" & $dont_bug_me & "<=", @ScriptLineNumber, 7);debug if $dont_bug_me <> 0 then return $dont_bug_me ; the number of the saved response if $timeout = default then $timeout = 0 if $gui_ex = default then $gui_ex = false if $style = default then $style = -1 if $inipath = default then $inipath = $ini_path if $butt1_txt = default then $butt1_txt = "OK" if not $butt1_txt then $butt1_txt = "OK" if $sectionname = default then $sectionname = $my_name global $dt_open = true global $dt_pushed = 0 global $dt_warn_count = 0 local $error, $extended local $last_event_mode = AutoItSetOption("GUIOnEventMode", 1) local $last_coord_mode = AutoItSetOption("GUICoordMode", 0) ; relative to last control ; work out some sizes and positions.. if $style = -1 then $style = BitOr($WS_CAPTION, $WS_SYSMENU, $WS_SIZEBOX) local $exStyle = BitOr($WS_EX_TOPMOST, $GUI_WS_EX_PARENTDRAG) global $dt_min_w = 400 global $dt_min_h = 130 local $dt_w local $dt_h = $dt_min_h ; Not very clever. Works well within our limited range. (under 1000 characters) local $text_len = StringLen($text) debug("$text_len: =>" & $text_len & "<=", @ScriptLineNumber, 7);debug local $addin_height = 0 while $addin_height < $text_len $dt_h += 22 ; add these pixels to the GUI height $addin_height += 50 ; for every extra this many characters text length (slightly magic!) $dt_min_h += 22 wend local $butt_width local $dt_x = IniRead($inipath, $sectionname, "msgbox_" & $pref_name & "_x", -1) local $dt_y = IniRead($inipath, $sectionname, "msgbox_" & $pref_name & "_y", -1) $dt_w = IniRead($inipath, $sectionname, "msgbox_" & $pref_name & "_width", $dt_min_w) ; create the GUI.. ; global $dt_GUI = GUICreate($title, $dt_w, $dt_h, $dt_x, $dt_y, $style, $exStyle, $gui_ex) GUISetFont(-1, 10, 400, 0, "Segoe UI", 5) GUISetBkColor(0xFFFFFF) GUISetOnEvent($GUI_EVENT_CLOSE, "cfmbCloseDialog", $dt_GUI) GUISetOnEvent($GUI_EVENT_RESIZED, "cfmbResize", $dt_GUI) ; icon_path local $icon_width = 0 if $icon_path then $icon_width = 36 ; CheckBox:: ; Don't bug me again about this!! ; GUISetCoord(10, $dt_h-66) global $check_dont_bug = GUICtrlCreateCheckBox("Always perform the chosen action.", 0, 0, 220, default, _ Bitor($WS_TABSTOP, $BS_AUTOCHECKBOX), BitOr($WS_EX_TOPMOST, $WS_EX_TRANSPARENT, $GUI_WS_EX_PARENTDRAG)) GUICtrlSetFont(-1, 8.5, 400, 0, "Segoe UI", 5) GUICtrlSetBkColor(-1, 0xFFFFFF) GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM+$GUI_DOCKSIZE+$GUI_DOCKLEFT) GUICtrlSetOnEvent(-1, "cfmbWarnPermanent") ; the "text" label.. ; GUISetCoord(15+$icon_width, 6) GUICtrlCreatelabel($text, 0, 0, $dt_w-30-$icon_width, $dt_h-53, _ BitOr($SS_NOTIFY, $SS_LEFT), $GUI_WS_EX_PARENTDRAG) GUICtrlSetBkColor(-1, 0xFFFFFF) ; GUICtrlSetBkColor(-1, 0xFF0000) GUICtrlSetResizing(-1, $GUI_DOCKBORDERS) GUICtrlSetFont(-1, 10, 400, 0, "Segoe UI", 5) GUICtrlSetTip(-1, " You can click and drag the entire window around quickly from here ") ; icon "shell32.dll" ; if $icon_path then GUISetCoord(10, 10) GUICtrlCreateIcon("", "", 0, -2, 32, 32, $SS_ICON, $WS_EX_TRANSPARENT) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) GUICtrlSetTip(-1, " this is an image ") GUICtrlSetState(-1,$GUI_DISABLE) GUICtrlSetImage(-1, $icon_path, $icon_id) GUICtrlSetResizing(-1, $GUI_DOCKSIZE+$GUI_DOCKLEFT+$GUI_DOCKTOP) endif ; The Stripe ; (F0F0F0).. ; GUISetCoord(50,$dt_h-43) ; $label_stripe = GUICtrlCreatelabel("", 0, 0, $dt_w, $dt_h, 0, $GUI_WS_EX_PARENTDRAG) GUICtrlCreatelabel(" ", 0, 0, $dt_w-100, 2, 0, $GUI_WS_EX_PARENTDRAG) GUICtrlSetBkColor(-1, 0xF0F0F0) GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM+$GUI_DOCKLEFT+$GUI_DOCKRIGHT+$GUI_DOCKHEIGHT) ; Make The Buttons.. ; local $buttons = 1 if $butt2_txt then $buttons = 2 if $butt3_txt then $buttons = 3 if $butt4_txt then $buttons = 4 global $buttons_array[$buttons+1][2] = [[$buttons]] local $buttonstyle = BitOr($BS_CENTER, $BS_FLAT, $BS_VCENTER, $BS_NOTIFY, $WS_TABSTOP) local $total_width = 0, $gap = 7 local $button_top = $dt_h-33 local $i = 1 ; [0] => Button ID, [1] => text of button while $i <= $buttons $buttons_array[$i][1] = Eval("butt" & $i & "_txt") ; screw the manual! It works! $i += 1 wend ; create buttons, as required.. for $i = $buttons_array[0][0] to 1 step -1 $butt_width = (StringLen($buttons_array[$i][1])*8)+20 GUISetCoord($dt_w-$total_width-$butt_width-$gap, $button_top) $buttons_array[$i][0] = GUICtrlCreateButton($buttons_array[$i][1], 0, 0, $butt_width, 25, $buttonstyle) GUICtrlSetFont(-1, 9, 400, 0, "Segoe UI", 5) GUICtrlSetOnEvent(-1, "cfmbPushButton") GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM+$GUI_DOCKSIZE+$GUI_DOCKRIGHT) ;GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) $total_width += $butt_width+$gap if $i = $default_butt then ControlFocus($dt_GUI, "", $buttons_array[$i][0]) next ; Another Dragable Area.. ; GUISetCoord(0,$button_top-8) GUICtrlCreateLabel("", 0, 0, $dt_w-$total_width-2, 50, 0, $GUI_WS_EX_PARENTDRAG) GUICtrlSetTip(-1, " Yes, you can click and drag the entire window around quickly from here, too ") GUICtrlSetResizing(-1, $GUI_DOCKBOTTOM+$GUI_DOCKSIZE+$GUI_DOCKLEFT+$GUI_DOCKRIGHT) ; Show the dialog.. ; GUISetState(@SW_SHOW, $dt_GUI) WinMove($dt_GUI, "", default, default, $dt_w, $dt_h) while $dt_open Sleep(25) wend ; User clicked a button (didn't cancel out) ; if $dt_pushed = 0 then $error = 1 ; user cancelled out else debug("CorzFancyMsgBox() User Clicked Button:: " & $dt_pushed, @ScriptLineNumber, 7);debug debug("CorzFancyMsgBox() User Chooses Option:: " & $buttons_array[$dt_pushed][1], @ScriptLineNumber, 7);debug ; There may already be a response for this dialog.. ; Re-use $dont_bug_me. $dont_bug_me = GUICtrlRead($check_dont_bug) if $dont_bug_me = $ON then IniWrite($inipath, $sectionname, $pref_name & "_dont_bug_me", $dt_pushed) else ; If you are never seeing this dialog again you don't need this lot.. local $size_array = WinGetPos($dt_GUI) ; 0-1-2-3:x-y-w-h if IsArray($size_array) then IniWrite($inipath, $sectionname, "msgbox_" & $pref_name & "_x", $size_array[0]) IniWrite($inipath, $sectionname, "msgbox_" & $pref_name & "_y", $size_array[1]) IniWrite($inipath, $sectionname, "msgbox_" & $pref_name & "_width", $size_array[2]) $error = $size_array[0] $extended = $size_array[1] endif endif endif AutoItSetOption("GUIOnEventMode", $last_event_mode) AutoItSetOption("GUICoordMode", $last_coord_mode) GUIDelete($dt_GUI) return SetError($error, $extended, $dt_pushed) endfunc func cfmbResize() local $size_array = WinGetPos($dt_GUI) if not IsArray($size_array) then return false if $size_array[2] < $dt_min_w then WinMove($dt_GUI, "", default, default, $dt_min_w, $size_array[3]) if $size_array[3] < $dt_min_h then WinMove($dt_GUI, "", default, default, $size_array[2], $dt_min_h) endfunc func cfmbPushButton() debug("", @ScriptLineNumber, 7);debug debug("cfmbPushButton(" & @GUI_CtrlId & ")", @ScriptLineNumber, 7);debug for $i = 1 to $buttons_array[0][0] if @GUI_CtrlId = $buttons_array[$i][0] then $dt_pushed = $i cfmbCloseDialog() endif next endfunc func cfmbWarnPermanent() if GUICtrlread($check_dont_bug) = $OFF then return $dt_warn_count += 1 local $message = "From now on you will no longer be notified and " & $my_name & _ " will just get on with doing whatever YOU CHOOSE NEXT..." if $dt_warn_count > 1 then $message = "You have been warned!" if $dt_warn_count > 3 then $message = "Oh! Just DECIDE will you!" MsgBox($MB_ICONWARNING+$MB_SYSTEMMODAL, "This is PERMANENT!!", $message) endfunc func cfmbCloseDialog() $dt_open = false endfunc ; Automatic Version Checking.. ; See corz_essentials.au3 for more info ; requires.. ; #include ; #include ; #include ; #include func VersionCheckOnline($v_name, $vck_url, $dl_url, $my_ini, $my_section, $this_version, $GUI=default) debug("VersionCheckOnline(v)" & $this_version, @ScriptLineNumber, 6);debug if not @Compiled then return local $version_checking = IniRead($my_ini, $my_section, "version_checking", "") if $version_checking == 0 then return false if $version_checking = -1 or $version_checking = "" then ; -1 at install time local $do_checkver = CorzFancyInputBox("Automatic Version Checking?", $v_name & _ " can check online for a new version of itself." & $MSG_LF & _ "Enter the number of days between checks." & $MSG_LF & _ "(enter 0 to disable version checking.)", "" , " M" , _ 400, 130 , (@DesktopWidth/2)-200, (@DesktopHeight/2)-50, 0, $GUI) if $do_checkver = "" then return false ; cancelled out of inputbox ; They enter "fuck off!", we write "0" IniWrite($my_ini, $my_section, "version_checking", Number($do_checkver)) if $do_checkver = 0 then return false endif if $version_checking > 365 then $version_checking = 365 if $version_checking > 0 or StringLeft($version_checking, 1) = "a" then local $version_checked = IniRead($my_ini, $my_section, "version_checked", "2000/01/01 00:00:00") if StringLeft($version_checking, 1) <> "a" then local $days_passed = _DateDiff("D", $version_checked, _NowCalc()) if $days_passed < $version_checking then return false endif endif local $daystr = "every day" if $version_checking > 1 then $daystr = "every " & $version_checking & " days" if StringLeft($version_checking, 1) = "a" then $daystr = "always" ProgressOn("Version Check (" & $daystr & ")" , "Checking for new version..") ProgressSet(25) $vck_url &= "&frequency=" & $version_checking & "¤t=" & $this_version local $published_version = BackGroundDownload($vck_url, 5000, 25) local $errmsg, $ext_error = @extended if @error <> 0 or not $published_version then ProgressOff() switch $ext_error case 1 $errmsg = $MSG_LF & "It looks like " & $my_domain & " is down." case 2 $errmsg = $MSG_LF & "Connexion timed-out." case 3 $errmsg = $MSG_LF & "Check your firewall." endswitch debug("Version Check FAILED." & $errmsg, @ScriptLineNumber, 1);debug MsgBox(16, "Version Check FAILED!", "Could not determine version online." & $errmsg) return false endif ProgressSet(50) IniWrite($my_ini, $my_section, "version_checked", _NowCalc()) ProgressSet(75) local $vcomp = _VersionCompare($this_version, $published_version) switch $vcomp case 0, 1 ; both equal (or $this_version is greater!!!) ProgressSet(100) ProgressOff() return false case -1 ProgressSet(100) local $version_response = MsgBox(4+48+262144, "New Version Available", _ "A newer version of " & $v_name & " is available." & $MSG_LF _ & "Would you like to visit the download page?") ProgressOff() switch $version_response case 6 ; yes - go to download page ShellExecute($dl_url) endswitch return $published_version endswitch endfunc ; Download a file from $dl_URL in the background, wait for $timeout milliseconds. ; This is designed to be used with VersionCheckOnline(), but could be used for any background download. ; Returns the raw file data. ; Abort, set @error to non-0 and return false if file not received. ; Type of fail is in @extended (1=server down, 2=timeout, 3=firewall blocked) ; ; NOTE: this function updates a progress dialog (set current position with $start). Optional. func BackGroundDownload($dl_URL, $timeout=default, $start=default, $save_file=default) if $timeout = default then $timeout = 3000 if $start = default then $start = 0 if $save_file = default then $save_file = false Local $c_time, $TmpFile $TmpFile = _WinAPI_GetTempFileName(@TempDir) if $save_file then $TmpFile = $save_file else $TmpFile = _WinAPI_GetTempFileName(@TempDir) endif local $DL = InetGet($dl_URL, $TmpFile, ($INET_FORCERELOAD + $INET_FORCEBYPASS), $INET_DOWNLOADBACKGROUND) ; We could use a sleep step for calculating time, but using small steps (eg. 25) would throw the total out of whack local $BG_time = TimerInit() local $dmsg do Sleep(10) $c_time = Round(TimerDiff($BG_time)) if Mod($c_time, 100) < 11 then ; 1 larger than sleep time (above). if $c_time > 999 then ProgressSet($start+(($c_time*3)/1000), "", "Checking: timeout in " & ($timeout-$c_time) & " ms") endif endif if $c_time >= $timeout then InetClose($DL) $dmsg = "Failed. Connexion Timeout." ProgressSet(0, "", $dmsg) debug($dmsg, @ScriptLineNumber, 1);debug return SetError(1, 2, $dmsg) ; 2 = timeout endif until InetGetInfo($DL, $INET_DOWNLOADCOMPLETE) local $success = InetGetInfo($DL, $INET_DOWNLOADSUCCESS) InetClose($DL) if not $success then ; Test server.. if Ping($my_domain, 500) < 10 then $dmsg = "Failed. Suspect Firewall." ProgressSet(0, "", $dmsg) debug($dmsg, @ScriptLineNumber, 1);debug return SetError(1, 3, $dmsg) ; 3 = check firewall else $dmsg = "Failed. Suspect Server Error." debug($dmsg, @ScriptLineNumber, 1);debug ProgressSet(0, "", $dmsg) return SetError(1, 1, $dmsg) ; 1 = server error / 404 endif endif local $dl_data = FileRead($TmpFile) ProgressSet(0, "", "Success!") if not $save_file then FileDelete($TmpFile) return $dl_data endif endfunc ; Feed it a path, if it is a full, valid path it is returned as-is. ; If it's a relative path, it is added to the datadir path and that full path is returned. func SetRelPathToDataDir($some_path) if $some_path and StringLeft($some_path, 2) <> '\\' and StringMid($some_path, 2, 1) <> ':' then CLT($some_path) $some_path = $data_dir & "\" & $some_path CRT($some_path) endif return $some_path endfunc ; Fire up the user's default screensaver.. ; func StartScreenSaver() global $user32_dll = DllOpen("user32.dll") local Const $WM_SYSCOMMAND = 0x112 local Const $SC_SCREENSAVE = 0xF140 local $gui = GUICreate("",10,10,-100,-100) local $guiHandle = WinGetHandle($gui) DllCall($user32_dll, "long", "SendMessageA", "long", $guiHandle, "long", $WM_SYSCOMMAND, "long", $SC_SCREENSAVE, "long", 0x0) DllClose($user32_dll) GUIDelete($gui) endfunc ; Lock the WorkStation. ; Simple, effective.. ; func LockWorkStation() ShellExecute("rundll32.exe", 'user32.dll,LockWorkStation') ; NOTE: CaSe is Crucial, here. if @Error then return SetError(@Error, @Extended, false) return true endfunc ; Author: xrxca (autoit at forums dot xrx dot ca) + wee bits by me ; func _GetMonitors() $monitors_list[0][0] = 0 ; Added so that the global array is reset if this is called multiple times local $handle = DllCallbackRegister("_MonitorEnumProc", "int", "hwnd;hwnd;ptr;lparam") DllCall("user32.dll", "int", "EnumDisplayMonitors", "hwnd", 0, "ptr", 0, "ptr", DllCallbackGetPtr($handle), "lparam", 0) DllCallbackFree($handle) local $i = 0 for $i = 1 To $monitors_list[0][0] if $monitors_list[$i][1] < $monitors_list[0][1] then $monitors_list[0][1] = $monitors_list[$i][1] if $monitors_list[$i][2] < $monitors_list[0][2] then $monitors_list[0][2] = $monitors_list[$i][2] if $monitors_list[$i][3] > $monitors_list[0][3] then $monitors_list[0][3] = $monitors_list[$i][3] if $monitors_list[$i][4] > $monitors_list[0][4] then $monitors_list[0][4] = $monitors_list[$i][4] next return $monitors_list endfunc ;==>_GetMonitors func _MonitorEnumProc($hMonitor, $hDC, $lRect, $lParam) #forceref $lParam, $hDC local $Rect = DllStructCreate("int left;int top;int right;int bottom", $lRect) $monitors_list[0][0] += 1 redim $monitors_list[$monitors_list[0][0] + 1][5] $monitors_list[$monitors_list[0][0]][0] = $hMonitor $monitors_list[$monitors_list[0][0]][1] = DllStructGetData($Rect, "left") $monitors_list[$monitors_list[0][0]][2] = DllStructGetData($Rect, "top") $monitors_list[$monitors_list[0][0]][3] = DllStructGetData($Rect, "right") $monitors_list[$monitors_list[0][0]][4] = DllStructGetData($Rect, "bottom") return 1 ; Return 1 to continue enumeration endfunc ; By ascend4nt (encapsulated by cor) ; Returns the handle of the owner window directly under the mouse.. func GetWindowUnderMouse($iX,$iY) local $stInt64,$aRet,$stPoint=DllStructCreate("long;long") DllStructSetData($stPoint,1,$iX) DllStructSetData($stPoint,2,$iY) $stInt64=DllStructCreate("int64",DllStructGetPtr($stPoint)) $aRet=DllCall("user32.dll","hwnd","WindowFromPoint","int64",DllStructGetData($stInt64,1)) if @Error then return SetError(2,@Error,0) if $aRet[0]=0 Then return SetError(3,0,0) ; The above can return 'sub' windows, or control handles, so we get the owner window.. local $aResult = DllCall("user32.dll", "hwnd", "GetAncestor", "hwnd", $aRet[0], "uint", 2) if @Error then return SetError(@Error, @Extended, 0) return $aResult[0] endfunc ; check wether a number is within a set range.. func NumberInRange($number, $min, $max) return ($number >= $min and $number <= $max); endfunc ; Speak some text out loud.. ; ; Rate is -10 to 10 or thereabouts. ; Volume 0 - 100, maybe. ; Voice is a substring of one of your available system voices (e.g. "Hazel"). ; func Speak($text, $vol=50, $rate=0, $voice="", $wait=false) debug("", @ScriptLineNumber, 7);debug debug("Speak(" & $text & "," & $vol & "," & $rate & "," & $wait & ")", @ScriptLineNumber, 7);debug ; Use a global variable so speech call is asynchronous. If you start a ; new speech command, it will cut-off the old one and begin immediately. global $o_speech = ObjCreate("SAPI.SpVoice") if not IsObj($o_speech) then return false local $speak_flag if $wait then $speak_flag = 10 ; no asynch else $speak_flag = 11 ;8 = XML 1 = SVSFlagsAsync 2: purge (seems to do this, anyway) endif debug("Speak() --> DeTokenizeString -->" & $text & "<=", @ScriptLineNumber, 7);debug $text = DeTokenizeString($text) if FileExists($text) then $speak_flag += 4 ; will read file contents when given valid file path endif ; choose a voice.. local $choose_voice = $o_speech.GetVoices().Item(0) if $voice then for $i = 0 to $o_speech.GetVoices().Count() - 1 local $MS_voice = $o_speech.GetVoices().Item($i) if StringInStr($MS_voice.GetAttribute("Name"), $voice) then $choose_voice = $MS_voice exitloop endif next endif ; speak the text.. with $o_speech .Voice = $choose_voice .Rate = $rate .Volume = $vol .Speak($text, $speak_flag); with XML + purge before speak endwith return true endfunc ; Returns an array of available system voices.. ; NOTE: Unless you hack your registry, you will probably only have a small ; selection of voices to play with. See KeyBind docs for how to expand this. func GetSpeechVoices() local $o_speech = ObjCreate("SAPI.SpVoice") if not IsObj($o_speech) then return -1 local $this_voice local $voice_array[1] for $i = 0 to $o_speech.GetVoices().Count() - 1 $this_voice = $o_speech.GetVoices().Item($i) ArrayAdd($voice_array, $this_voice.GetAttribute("Name")) next return $voice_array endfunc ; ; Get the command-line arguments. ; Returns an array with two values.. ; ; $ret_array[0] => switches ; $ret_array[1] => filename (if supplied) ; ; Do: ; ; local $cmd_array = $CmdLine ; local $cmdline = GetCommandLine($CmdLineRaw, $cmd_array) ; global $switches = $cmdline[0] ; global $inputfile = $cmdline[1] ; ; Note, when running inside your IDE (not @Compiled) you may not get the same ; results as you will when @Compiled, depending on your IDE. Test the compiled ; version! ; func GetCommandLine($command_line, $cmd_array) debug("", @ScriptLineNumber, 7);debug debug("GetCommandLine(" & $command_line & ")", @ScriptLineNumber, 7);debug debug_PrintArray($cmd_array, $LOG_LF & "cel.au3 :: (" & @ScriptLineNumber & ") " & " $cmd_array: ");debug $command_line = StringStripWS($command_line, 3) local $ret_array[2] if $cmd_array[0] then for $i = 1 to $cmd_array[0] $cmd_array[$i] = StringStripWS($cmd_array[$i], 3) next ; file path supplied.. if StringRight($command_line, 1) <> ")" then $ret_array[1] = StringStripWS($cmd_array[$cmd_array[0]], 3) for $i = 1 to $cmd_array[0] if StringStripWS($cmd_array[$i], 3) <> $ret_array[1] then _ $ret_array[0] &= StringStripWS($cmd_array[$i], 3) & " " next else $ret_array[1] = "" for $i = 1 to $cmd_array[0] $ret_array[0] &= StringStripWS($cmd_array[$i], 3) & " " next endif endif CRT($ret_array[0], " ") return $ret_array endfunc ; UrlToText() ; ; basic HTML > text translation, for spoken web pages ; slow, and not terribly clever.. ; ; feed it a URL or path to a local html file, returns the plain text, for speaking ; all formatting is removed, and "." dots are also added to break up big sections. ; ; you can send start and end points for the text stream; simply tag the words/phrases ; onto the end of the URL (or local file location) using an asterisk, e.g.. ; ; $myText = UrlToText('http://news.bbc.co.uk/*Last Updated*CONTACT US') ; ; which would get you the latest headlines from the BBC, ready for feeding to Sam, or Mike ; or Mary or whoever. If you omit the end point, e.g.. ; ; $myText = UrlToText('http://www.answers.com/topic/gal-pagos-tortoise-2*Synonyms') ; ; all the text from the start point to the end of the page will be returned. If you provide ; no start and end points, the text of the whole page is returned. Something to play with. ; func UrlToText($url) debug("", @ScriptLineNumber, 7);debug debug("UrlToText(" & $url & ")", @ScriptLineNumber, 7);debug local $start = "" local $end = "" local $handle = "" if StringInStr($url, "*", 0, -1) then local $url_parts = StringSplit($url, "*") $url = $url_parts[1] if uBound($url_parts) > 2 then $start = $url_parts[2] if uBound($url_parts) > 3 then $end = $url_parts[3] endif if StringLeft($url, 4) = "http" then InetGet($url, @TempDir & "\UrlToText.tmp", 1) ; if no file or emp $handle = FileOpen(@TempDir & "\UrlToText.tmp", 0) else $handle = FileOpen($url, 0) endif local $web_text = FileRead($handle) if StringInStr($web_text, "<") then ; we'll break shit up for speaking.. $web_text = StringRegExpReplace($web_text, '', '. ') ; strip out the HTML.. $web_text = StringRegExpReplace($web_text, '\s', ' ') $web_text = StringRegExpReplace($web_text, '<(?i)head(.*?)', '') ; best done individually.. $web_text = StringRegExpReplace($web_text, '<(?i)script(.*?)', '') $web_text = StringRegExpReplace($web_text, '<(?i)style(.*?)', '') $web_text = StringRegExpReplace($web_text, ']*?>', '') $web_text = ReplaceHTMLEntities($web_text) endif ; speak from.. if $start then $web_text = StringTrimLeft($web_text, StringInStr($web_text, $start)-1) endif ; speak to.. local $strlen = StringLen($web_text) local $end_pos = StringInStr($web_text, $end) if $end_pos = 0 then $end_pos = $strlen if $end then $web_text = StringTrimRight($web_text, $strlen-$end_pos+1) endif FileClose($handle) FileDelete(@TempDir & "\UrlToText.tmp") return StringStripWS($web_text, 4) endfunc ; DoLog() ; Logs stuff.. ; ; The optional second parameter tells DoLog to append, or not. ; $dl_append will most likely receive the output from a checkbox.. ; 1 (append) or 4 [or anything else] (create new log) ; ; To stop and close the log, send "out" as your log string ; the optional third parameter '$log_extra' goes at top of log, ; and, if required, you must send it along with your "out" command, eg.. ; ; DoLog("out", 0, "command-line: " & $my_arguments & $LOG_LF & $LOG_LF) ; ; ; and now the function itself.. func DoLog($dl_string, $dl_append=4, $log_extra="") debug("Log extra: " & $log_extra, @ScriptLineNumber, 10 );debug if $dl_string = "out" then if $log_string then if $dl_append = $ON then $dl_append = $FO_APPEND + $FO_CREATEPATH else $dl_append = $FO_OVERWRITE + $FO_CREATEPATH endif local $my_log_file = FileOpen($log_location, $dl_append) FileWriteLine($my_log_file, $my_name & _ " log: " & DateTimeString() & ".. " & $LOG_LF & _ "--------------------------------------------------------------------------------" & $LOG_LF) if not $log_extra then FileWriteLine($my_log_file, "command-line: " & $CmdLineRaw & $LOG_LF & $LOG_LF) endif FileWriteLine($my_log_file, $log_extra) FileWriteLine($my_log_file, $log_string & $LOG_LF) FileClose($my_log_file) $log_string = "" endif else $log_string &= UnifyCRLF($dl_string) & $LOG_LF endif return $dl_string endfunc ;; Debugging Functions.. ; debug() ; ; Provides quick debug report in your console/log.. ; ; If your text editor can do it (probably), this is a great ; way to get debug output without halting the script execution.. ; ; Newbies: you set your global $debug_level and bugs of that level ; and below are logged. Stuff you always want to see will have a low ; level, and stuff you rarely want to see (it's large, etc.) will ; have a higher level. ; ; Debug levels go from 1 to 10, though typically in my apps there is ; also level 11, where gobs of generally unnecessary output is ; produced. An occasionally useful nod to Spinal Tap, I suppose. ; ; NOTE: if you call debug() in a compiled script you will get ; the debug() output debug_dump()ed to a log, instead. ; ; The Au3Stripper Parameter "/rsln" ensures these line numbers are ; preserved in the compiled script, so debug output is fairly useful. ; A typical debug line might look like this: ; ; (1103/2899) : ==> $do_output: enabled ; ; The numbers in braces refer to (original script line / stripped ; script line). The one on the left is probably the most useful. ; func debug($d_string, $ln=false, $level=1, $max_size=$max_debug_log_size) if $level > $debug_level then return false ; This is unlikely to catch actual arrays under normal circumstances (there is a string prepended to input!).. if IsArray($d_string) then return debug_PrintArray($d_string, "cel.au3 :: NOT A STRING!", $ln, $level, 0, $max_size);debug if @Compiled then return debug_dump($d_string, $ln, $level, true, $max_size) local $pre = "" ; We add the line numbers so that: ; a) We know where shit happens, and.. ; b) if your text editor supports it, we can click those lines in the console output ; and go directly to that line in the script. If your text editor/IDE does not support ; this feature, upgrade your editor. The time you are wasting ... ; Notepad++ if $ln and $ln <> -1 then $pre = "(" & $ln & ") " & @Tab ; ; Editplus.. ; if $ln then $pre = ".\" & @ScriptName & "(" & $ln & "): ==> " ; etc.. ; if $ln then $pre = """" & @ScriptFullPath & """(" & $ln & "): ==> " if $pre then $pre &= "[ " & _NowCalcDate() & " @ " & _NowTime() & "::" & @Msec & " ][l:" & $level & "]" & @Tab ConsoleWrite($pre & $d_string & $LOG_LF) endfunc ; debug_dump() ; ; Like debug (), but to a file.. func debug_dump($d_string, $ln=false, $level=1, $append=true, $max_size=$max_debug_log_size) if $level > $debug_level then return false if IsArray($d_string) then return debug_dumpArray($d_string, "$ARRAY:", $append, $level, $max_size) local $pre, $code = 129 ; + UTF-8 if $append = false then $code = 130 if $ln and $ln <> -1 then $pre = "(" & $ln & ") : ==> " CheckLogSize($max_size) local $fileh = FileOpen($dump_file, $code) FileWriteLine($fileh, $pre & $d_string & $LOG_LF) FileClose ($fileh) endfunc ; LogError() ; ; It should be "errer", really. ; Log an (usually, exit) error to a file ; func debug_LogError($error_string) FileWriteLine(@ScriptDir & "\error.log", "") FileWriteLine(@ScriptDir & "\error.log", _ "--------------------------------------------------------------------------------") FileWriteLine(@ScriptDir & "\error.log", @Year & "/" & @Mon & "/" & @MDay _ & " " & @Hour & ":" & @Min & ":" & @Sec ) FileWriteLine(@ScriptDir & "\error.log", "") FileWriteLine(@ScriptDir & "\error.log", "command-line: " & $CmdLineRaw) FileWriteLine(@ScriptDir & "\error.log", "") FileWriteLine(@ScriptDir & "\error.log", $error_string) endfunc ; debug_PrintArray() ; debug_PrintArray() ; ; Debug output of an array, in the console ; (your text editor/IDE can probably display this for you, if you so desire).. func debug_PrintArray(byref $array, $tring="array", $ln="", $level=1, $limit=0, $max_size=$max_debug_log_size, $forcedump=false, $string=false) if $level > $debug_level then return false local $pre $pre = "(" & $ln & ") " & @Tab if $pre then $pre &= "[ " & _NowCalcDate() & " @ " & _NowTime() & "::" & @Msec & " ][l:" & $level & "]" & @Tab if not IsArray($array) then return ConsoleWrite($LOG_LF & $pre & $tring & ": NOT an array!" & _ $LOG_LF & $pre & "it's a string: " & "->" & $array & "<-" & $LOG_LF & $LOG_LF) ; 2+dimensional array sent.. if UBound($array, 0) > 1 then return debug_Print2DArray($array, $tring, $ln, $level, $limit, $max_size, $forcedump, $string) local $pa_string = "" local $count = 0 for $element in $array $pa_string &= '[' & $count & '] : ' & $element & $LOG_LF $count += 1 if $count = $limit then exitloop next if $string then return $LOG_LF & $pre & $tring & ": " & $LOG_LF & $pa_string & $LOG_LF if @Compiled or $forcedump then debug_dump($LOG_LF & $pre & $tring & ": " & $LOG_LF & $pa_string & $LOG_LF, $ln, $level, true, $max_size) else ConsoleWrite($LOG_LF & $pre & $tring & ": " & $LOG_LF & $pa_string & $LOG_LF) endif endfunc ; Like debug_PrintArray, but will handle arrays with more than two columns.. ; ; For if you know what you should have, and want to see it. ; Only works for the kind of arrays returned by IniReadSection() and similar ; functions, or ones you created yourself, needs $array[0][0] to be meaningful.. func debug_Print2DArray(byref $array, $tring="array", $ln="", $level=1, $limit=0, $max_size=$max_debug_log_size, $forcedump=false, $string=false) ; $limit for compatability only if @Compiled and ($level > $debug_level) then return 0 local $pre if $ln then $pre = "(" & $ln & ") " & @Tab if not IsArray($array) then return debug($pre & $tring & ": NOT an array!" & $LOG_LF & _ $pre & "it's a string: " & "->" & $array & "<-" & $LOG_LF, @ScriptLineNumber, 5);debug ; 1-dimensional array sent.. if UBound($array, 0) < 2 then return debug_PrintArray($array, $tring, $ln, $level, $limit, $ln) if $pre then $pre &= "[ " & _NowCalcDate() & " @ " & _NowTime() & "::" & @Msec & " ][l:" & $level & "]" & @Tab $limit += 1 local $cols = UBound($array, 2) local $pa_string = "" for $i = 0 to UBound($array, 1)-1 $pa_string &= '[' & $i & '] [0] = ' & $array[$i][0] & ' ' for $j = 1 to $cols-1 $pa_string &= ' [' & $j & '] = ' & $array[$i][$j] & ' ' next $pa_string &= $LOG_LF next if $string then return $LOG_LF & $pre & $tring & ": " & $LOG_LF & $pa_string & $LOG_LF if @Compiled or $forcedump then debug_dump($LOG_LF & $pre & $tring & ": " & $LOG_LF & $pa_string & $LOG_LF, $ln, $level, true, $max_size) else ConsoleWrite($LOG_LF & $pre & $tring & ": " & $LOG_LF & $pa_string & $LOG_LF) endif endfunc ; debug_dumpArray() ; Debug output of an array, to a file.. func debug_dumpArray(byref $array, $title="array", $append=true, $level=1, $max_size=$max_debug_log_size) if not IsArray($array) then return 0 if $level > $debug_level then return false if UBound($array, 0) > 1 then return debug_Print2DArray($array, $title, "", $level, 0, $max_size) CheckLogSize($max_size) local $code = 129 ; + UTF-8 if $append = false then $code = 130 local $fileh = FileOpen($dump_file, $code) local $da_string = $title & $LOG_LF local $count = 0 for $element in $array $da_string &= '[' & $count & '] : ' & $element & $LOG_LF $count += 1 next FileWrite($fileh, $da_string) FileClose($fileh) endfunc ; If the log reaches a preset size, backup and start again.. func CheckLogSize($max_size=$max_debug_log_size) if $max_size <> 0 then if FileGetSize($dump_file) > ($max_size * 1048576) then ; Bytes > MB = * 1048576 (1024*1024) BackupFile($dump_file) endif endif endfunc ; Provides a time-stamped backup of a file.. func BackupFile($file) local $backup = GetParent($file) & "\[" & FileDateStamp() & "]_" & RemoveExtension(Basename($file)) & "." & GetExtension($file) local $ret = FileMove($file, $backup) Run(@ComSpec & " /c " & 'compact.exe /C "' & $dump_file & '"', "", @SW_HIDE) return $ret endfunc ; _IsPressed (is a key pressed?) ; Author(s): ezzetabi and Jon / Valik func ce_IsPressed($Key) local $kp = DllCall('user32.dll', "int", "GetAsyncKeyState", "int", '0x' & $Key) if not @error and BitAND($kp[0], 0x8000) = 0x8000 then return 1 return 0 endfunc ; Is some window visible? func WinVisible($GUI) return BitAnd(WinGetState($GUI), 2) endfunc ; Just for fun, reverses a StringSplit - handy if you have split a string to ; manipulate and now want it back as a string.. ; Pass it an AutioIt array, as returned by StringSplit ; ; This also makes a great part 1 of a 1-2 WriteArrayToFromFile type function. ; (see above for exactly that) ; func ArrayJoin($array, $join_str=$LOG_LF) debug_PrintArray($array, "cel.au3 :: ArrayJoin():", @ScriptLineNumber, 8);debug debug("$join_str: " & $join_str, @ScriptLineNumber, 8);debug local $ret_str for $i = 1 to $array[0] if $array[$i] <> "" then $ret_str &= $array[$i] & $join_str endif next CRT($ret_str, $join_str) debug("$ret_str: " & $ret_str, @ScriptLineNumber, 8);debug return $ret_str endfunc ; Return total available free memory.. func GetFreeMem() local $mem_stats = MemGetStats() local $free = $mem_stats[2] * 1024 ; convert to bytes return $free endfunc func GetFreeMemHuman() local $mem_stats = MemGetStats() local $free = $mem_stats[2] / 1024 ; convert to MB return FormatMB($free, 2) endfunc ; close some running process.. func CloseProcess($process_name) SetError(0) local $closed = ProcessClose($process_name) if @Error then $closed = ProcessWaitClose($process_name) if @Error then $closed = Run(@ComSpec & " /c " & 'taskkill /F /T /IM ' & $process_name, "", @SW_HIDE) debug("Closed " & $process_name & ": " & $closed, @ScriptLineNumber, 7);debug return $closed endfunc ; Cute little System Info Box.. ; Designed to be included as an About Box Easter Egg. ; func SysInfoBox() local $last_event_mode = AutoItSetOption("GUIOnEventMode", 0) local $last_coord_mode = AutoItSetOption("GUICoordMode", 0) local $si_x = IniRead($ini_path, $my_name, "si_x", -1) local $si_y = IniRead($ini_path, $my_name, "si_y", -1) local $si_w = IniRead($ini_path, $my_name, "si_w", 800) local $si_h = IniRead($ini_path, $my_name, "si_h", 388) if $si_w < 400 Then $si_w = 400 local $label_width = 140 local $info_width = $si_w - $label_width - 20 ; local $path_adds = "" local $gui_sysinfo = GUICreate("System Information", $si_w, $si_h, $si_x, $si_y, _ BitOR($WS_CLIPSIBLINGS, $WS_CAPTION, $WS_SYSMENU, $WS_SIZEBOX), $WS_EX_TOPMOST) GUISetIcon(@AutoItExe, 0, $gui_sysinfo) GUISetCoord($si_w-33, 10) local $label_env = GUICtrlCreateLabel("ENV", 0, 0, 30, 20) GUICtrlSetResizing(-1, $GUI_DOCKMENUBAR+$GUI_DOCKWIDTH+$GUI_DOCKRIGHT) GUICtrlSetTip(-1, " Click here to see this system's Environment Variables (aka. 'ENV VAR'). ") GUISetCoord(10, -10) local $computername = GUICtrlCreateLabel("Computer Name:", 0, 20, $label_width) GUICtrlCreateLabel("Memory:", $label_width + 220, 0, 60) GUISetCoord(10, 10) GUICtrlCreateLabel("Current UserName:", 0, 20, $label_width) GUICtrlCreateLabel("Operating System:", 0, 20, $label_width) GUICtrlCreateLabel("System %" & "PATH%:", 0, 20, $label_width) ; In case AutoItSetOption("ExpandEnvStrings", 1) local $ip = GUICtrlCreateLabel("Local IP Address:", 0, 20, $label_width) local $combo_info_drives = GUICtrlCreateCombo("", 0, 22, 100, 200) local $my_drives = DriveGetDrive("FIXED") for $i = 1 to $my_drives[0] GUICtrlSetData($combo_info_drives, $my_drives[$i]) next ControlCommand($gui_sysinfo, "", $combo_info_drives, "SelectString", @HomeDrive) local $startupdir = GUICtrlCreateLabel("Startup Directory:", 0, 28, $label_width) GUICtrlCreateLabel("Windows Directory:", 0, 20, $label_width) GUICtrlCreateLabel("System Folder:", 0, 20, $label_width) GUICtrlCreateLabel("Desktop Directory:", 0, 20, $label_width) GUICtrlCreateLabel("'My Documents' Directory:", 0, 20, $label_width) GUICtrlCreateLabel("Program Files Directory:", 0, 20, $label_width) GUICtrlCreateLabel("Start Menu Directory:", 0, 20, $label_width) GUICtrlCreateLabel("Temporary File Directory:", 0, 20, $label_width) GUICtrlCreateLabel("Desktop:", 0, 20, $label_width) GUICtrlCreateLabel("Date [Y-M-D]:", 0, 20, $label_width) GUICtrlCreateLabel("Time [H:M:S]:", 0, 20, $label_width) local $myini = GUICtrlCreateLabel("My ini:", 0, 20, $label_width) GUISetCoord($label_width + 10, -12) local $current_drive = GUICtrlRead($combo_info_drives) local $inp_computername = GUICtrlCreateInput(@ComputerName, 0, 20, 200, 20) local $input_freemem = GUICtrlCreateInput(GetFreeMemHuman(), $label_width * 2, 0, 120, 20) for $i = $computername to $input_freemem GUICtrlSetResizing($i, $GUI_DOCKALL) GUICtrlSetTip($i, " Click the labels to select all the input text. " & $msg_lf & " NOTE: Some update dynamically and will quickly deselect themselves! ") next GUISetCoord($label_width + 10, 10) local $input_username = GUICtrlCreateInput(@UserName, 0, 20, $info_width, 20) local $vbit = "x86" if @AutoItX64 = 1 then $vbit = "x64" local $os_string = StringReplace(@OSVersion, "_", " ") & " (" & $vbit & ") " & @OSServicePack & " [" & @OSType & "][cpu:" & StringLower(@CPUArch) & "]" GUICtrlCreateInput($os_string, 0, 20, $info_width, 20) GUICtrlCreateInput(EnvGet("PATH"), 0, 20, $info_width, 20) GUICtrlCreateInput(@IPAddress1, 0, 20, $info_width, 20) local $input_drive_label = GUICtrlCreateInput(DriveGetLabel($current_drive & "\"), 0, 23, 150, 20) local $input_totalspace = GUICtrlCreateInput(FormatMB(DriveSpaceTotal($current_drive & "\"), 2), 155, 0, 100, 20) local $input_freespace = GUICtrlCreateInput(FormatMB(DriveSpaceFree($current_drive & "\"), 2) & " Free", 105, 0, 150, 20) GUISetCoord($label_width + 10, 138) GUICtrlCreateInput(@StartupDir, 0, 0, $info_width, 20) GUICtrlCreateInput(@WindowsDir, 0, 20, $info_width, 20) GUICtrlCreateInput(@SystemDir, 0, 20, $info_width, 20) GUICtrlCreateInput(@DesktopDir, 0, 20, $info_width, 20) GUICtrlCreateInput(@MyDocumentsDir, 0, 20, $info_width, 20) GUICtrlCreateInput(@ProgramFilesDir, 0, 20, $info_width, 20) GUICtrlCreateInput(@StartMenuDir, 0, 20, $info_width, 20) GUICtrlCreateInput(@TempDir, 0, 20, $info_width, 20) GUICtrlCreateInput(@DesktopWidth & "px" & " x " & @DesktopHeight & "px " & _ @DesktopDepth & "bit [" & @DesktopRefresh & "Hz]", 0, 20, $info_width, 20) local $input_date = GUICtrlCreateInput(@YEAR & "-" & @MON & "-" & @MDAY, 0, 20, $info_width, 20) local $input_time = GUICtrlCreateInput(@HOUR & ":" & @MIN & ":" & @SEC, 0, 20, $info_width, 20) local $input_ini = GUICtrlCreateInput($ini_path, 0, 20, $info_width, 20) for $i = $input_username To $input_ini GUICtrlSetResizing($i, $GUI_DOCKALL+$GUI_DOCKRIGHT) next for $i = $inp_computername To $input_ini GUICtrlSetFont($i, 8.5, 400, 0, "Consolas", 5) next for $i = $input_drive_label To $input_freespace GUICtrlSetResizing($i, $GUI_DOCKALL) next GUISetState() local $last_sec = @Sec local $link = false while true if @Sec<> $last_sec then GUICtrlSetData($input_time, @HOUR & ":" & @MIN & ":" & @SEC) if @SEC < 2 and @HOUR = 0 and @MIN = 0 then GUICtrlSetData($input_date, @YEAR & "-" & @MON & "-" & @MDAY) endif $current_drive = GUICtrlRead($combo_info_drives) GUICtrlSetData($input_drive_label, DriveGetLabel($current_drive & "\")) local $capacity = DriveSpaceTotal($current_drive & "\") local $free_space = DriveSpaceFree($current_drive & "\") GUICtrlSetData($input_totalspace, FormatMB($capacity, 2)) GUICtrlSetData($input_freespace, FormatMB($free_space, 2) & " Free") if $free_space < ($capacity / 10) then GUICtrlSetBkColor($input_freespace, 0xff0000) else GUICtrlSetBkColor($input_freespace, default) endif GUICtrlSetData($input_freemem, GetFreeMemHuman() & " Free") $last_sec = @Sec endif local $msg = GUIGetMsg() switch $msg case $label_env GUISetState(@SW_DISABLE, $gui_sysinfo) DisplayEnvVars() GUISetState(@SW_ENABLE, $gui_sysinfo) case $gui_event_close exitloop case $combo_info_drives $current_drive = GUICtrlRead($combo_info_drives) GUICtrlSetData($input_drive_label, DriveGetLabel($current_drive & "\")) GUICtrlSetData($input_totalspace, FormatMB(DriveSpaceTotal($current_drive & "\"), 2)) GUICtrlSetData($input_freespace, FormatMB(DriveSpaceFree($current_drive & "\"), 2) & " Free") case $computername to $ip GUICtrlSetState($msg + 19, $gui_focus) case $startupdir to $myini GUICtrlSetState($msg + 21, $gui_focus) endswitch ; Visual indication of clickable link.. local $mouse = GUIGetCursorInfo($gui_sysinfo) if $mouse[4] <> $link then if $mouse[4] = $label_env and $link = false then $link = $mouse[4] GUICtrlSetColor($label_env, 0x008DFF) GUISetCursor(0, 1, $gui_sysinfo) else GUICtrlSetColor($label_env, default) GUISetCursor() $link = false endif endif Sleep(100) wend local $size_array = WinGetPos($gui_sysinfo) if IsArray($size_array) then if $si_x <> $size_array[0] and $size_array[0] >= 0 and $size_array[0] < (@DesktopWidth - 25) then IniWrite($ini_path, $my_name, "si_x", $size_array[0]) if $si_y <> $size_array[1] and $size_array[1] >= 0 and $size_array[1] < (@DesktopHeight - 25) then IniWrite($ini_path, $my_name, "si_y", $size_array[1]) $size_array = WinGetClientSize($gui_sysinfo) if IsArray($size_array) then if $size_array[0] <> $si_w and $size_array[0] >= 100 then IniWrite($ini_path, $my_name, "si_w", $size_array[0]) if $size_array[1] <> $si_h and $size_array[1] >= 100 then IniWrite($ini_path, $my_name, "si_h", $size_array[1]) endif endif GUIDelete($gui_sysinfo) AutoItSetOption("GUIOnEventMode", $last_event_mode) AutoItSetOption("GUICoordMode", $last_coord_mode) endfunc ; GUI readout of the System Environment Variables.. ; func DisplayEnvVars() local $PID = Run(@ComSpec & " /c set", @SystemDir, @SW_HIDE, $STDOUT_CHILD) local $env_vars while true $env_vars &= StdoutRead($PID) if @Error then exitloop wend $env_vars = StringStripWS($env_vars, 3) DisplayText($env_vars, "Environment Variables", 700, 600) endfunc ; Simple GUI to display some text for the user. ; ; Perhaps a readme, or license agreement. ; With an option to copy the text to the ClipBoard. ; func DisplayText($text, $title="For Reading..", $width=650, $height=$width, $inipath=$ini_path, $sectionname=$my_name) local $last_event_mode = AutoItSetOption("GUIOnEventMode", 0) local $last_coord_mode = AutoItSetOption("GUICoordMode", 0) ; local $height = $width local $GUI_styles = BitOR($WS_CLIPSIBLINGS, $WS_CAPTION, $WS_SYSMENU, $WS_SIZEBOX) local $edit_styles = BitOr($ES_WANTRETURN, $WS_VSCROLL, $WS_HSCROLL, $ES_AUTOHSCROLL, $ES_MULTILINE, $WS_TABSTOP) local $prefname = "display_txt_" & CleanPrefName($title) local $dt_x = IniRead($inipath, $sectionname, $prefname & "_x", -1) local $dt_y = IniRead($inipath, $sectionname, $prefname & "_y", -1) local $GUI_txt_display = GUICreate($title, $width, $height, $dt_x, $dt_y, $GUI_styles, $WS_EX_TOPMOST) local $edit_env = GUICtrlCreateEdit($text, 5, 5, $width-10, $height-40, $edit_styles) local $butt_copy = GUICtrlCreateButton("Copy To ClipBoard", $width-155, $height-35, 105, 25) local $butt_done = GUICtrlCreateButton("OK", 110, 0, 35, 25) GUICtrlSetResizing($edit_env, $GUI_DOCKBORDERS) GUICtrlSetResizing($butt_copy, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKRIGHT) GUICtrlSetResizing($butt_done, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKRIGHT) ControlFocus($GUI_txt_display, "", $edit_env) Send("{Right}") GUISetState(@SW_SHOW, $GUI_txt_display) while true switch GUIGetMsg() case $butt_done, $gui_event_close exitloop case $butt_copy ClipPut($text) DisplayTooltipMessage("Data Successfully Copied to the ClipBoard", 3000, "Success!", true) endswitch Sleep(25) wend local $size_array = WinGetPos($GUI_txt_display) if IsArray($size_array) then IniWrite($inipath, $sectionname, $prefname & "_x", $size_array[0]) IniWrite($inipath, $sectionname, $prefname & "_y", $size_array[1]) endif GUIDelete($GUI_txt_display) AutoItSetOption("GUIOnEventMode", $last_event_mode) AutoItSetOption("GUICoordMode", $last_coord_mode) return true endfunc