global $my_version = "2.0.0.0" #cs ffe - an ffmpeg front-end, from corz.org. http://www.google.com/search?q=ffmpeg *** BEFORE COMPILING *** Please see the compile options at the foot of this program. You may want to change the locations of the copied binaries, for starters. About: ffe is a simple yet powerful Windows® front-end for ffmpeg, designed for rapid testing of its various multimedia conversion parameters, enabling you to save lots of slightly different versions of a file very, very quickly; in other words, "find the best settings". ffmpeg, by Fabrice Bellard, et al., is a quite incredible multimedia converter, capable of converting a vast number of input and output media formats, and depending on which binary you use, supports either a HUGE number of control parameters, or a REALLY HUGE number of control parameters. ffe uniquely uses MATOF technology to automatically update output filenames to match your encoding parameters; you can tweak-and-go without worrying about obliterating your previous tests. While converting, the console output from ffmpeg can be viewed live inside ffe, and when complete, the entire process log is available for viewing/searching. ffe supports batch operation, automatic concatenation, infinite and infinitely customizable presets and customizable parameter buttons, pre- and post-job shell commands, dynamic @tokens, Media Info Reporting, Windows Batch Script Output, floating drop-window, command-line control and a host of other handy features and functions. Enjoy! More info here: http://corz.org/windows/software/ffe/ To use: Drop ffe.exe next to ffmpeg.exe (the ffmpeg binary). Run ffe.exe That's it. See inside ffe.ini and the current itstory for LOTS of notes and tricks.. http://corz.org/engine?section=beta/windows/ffe&source=version.nfo _IniReadSection ;bugs.. No known bugs. 2do.. All done! 2do maybe.. * Watch Mode (use Windows API directly for this) >> Automatically encode to current preset ("go") all files dropped in X folder. Add done files to a $known_files array and/or moving originals when done moving is better or else clear array after X days, to prevent long-term memory issues for instances running for months, processing millions of files done, 2document.. Aaargh.. Everything! notes.. The program architecture; to use the term loosely; is fairly linear. As these things (GUIs) go, one or two functions becomes three, and so on. On the bright side, it should be pretty clear how to hack in new stuff. if you are compiling this yourself, you need to use "AutoIt Wrapper" to add the extra icons. You will also need to use AT LEAST version 1.9.3 of AutoIt Wrapper for the paths to work correctly. You can download it here.. http://www.autoitscript.com/autoit3/scite/downloads.shtml version info here.. http://corz.org/machine/source/beta/windows/ffe/version.nfo #ce #include #include #include #include #include #include #include #include #include #include #include #include #include #include ; Fun with animated GIF drop windows.. ; ; Of course this is sheer madness, a moving drop target!! lol ; ; BUT, if you want a dancing girl or throbbing arrow or whatever, on your ; desktop go right ahead. Enjoy your insanity! ; ; Of course you will need trancexx's lovely GIFAnimation.au3 script available. ; It will be around the site/distro somewhere. ; #include "GIFAnimation.au3" global $hGIF global $enable_animated_gif = true ; this gets set on image load, to use GIF routines for gifs.. global $gif_method = false ; ; While this started out as a bit of fun, I have since discovered a few animated ; gifs that work really well, with gentle visual indicators. I've spruced up the ; gif code a bit, too. I'll probably leave it in for the release. ; we put these functions directly into ffe.au3 now (it's easier for everyone). ;#include "Include/corz_essentials.au3" ; forked years ago. see foot of this file global const $LOG_LF = @CRLF ; for logs/saved text files global const $MSG_LF = @LF ; for dialog boxes ; 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 global const $MF_BYPOSITION = 0x00000400 global const $MF_SEPARATOR = 0x00000800 global const $MF_CHECKED = 0x00000008 Global Const $MF_UNCHECKED = 0x0 global const $MF_POPUP = 0x00000010 global const $exit_preset = "FFE-EXIT-SETTINGS" ; depending on your version of AutoIt, you might need to un/comment this next line.. ;const $WM_SYSCOMMAND = 0x0112 AutoItSetOption("GUIOnEventMode", 1) AutoItSetOption("TrayMenuMode", 11) AutoItSetOption("TrayOnEventMode", 1) AutoItSetOption("GUICoordMode", 1) ; NEVER AGAIN!!! (getting there now, see MakeGUI()) AutoItSetOption("GUIEventOptions", 1) ; init vars.. global $me_app, $my_name = "ffe" global $my_title = " ffe.. ffmpeg front-end" global $ini_path = $my_name & ".ini" global $abort_batch = false global $got_helps = "" global $ffmpeg = 0; the ffmpeg proccess global $my_domain = "corz.org" global $my_url = "http://" & $my_domain & "/windows/software/ffe/" global $versioncheck_url = "http://" & $my_domain & "/inc/versions.php?app=ffe" global $download_url = "http://" & $my_domain & "/windows/software/ffe/#section-Download" global const $NAME_BUTTONS = "custom buttons" global const $NAME_SETTINGS = "main settings" global const $NAME_PRESETS = "presets" ; this may get switched on.. global $do_debug = $OFF ;if $do_debug = $ON then debug("foo =>" & $foo & "<=" , @ScriptLineNumber);debug ;if $do_debug = $ON then PrintArray($array, "$array", 0, @ScriptLineNumber);debug ; enables you to see icons and such without compiling. ; alter the second $me_app to match the place where you keep ffe.exe.. if @Compiled then $me_app = @ScriptFullPath $do_debug = $OFF else $do_debug = $ON ; enter the path to your own local binary.. $me_app = "C:\Program Files\corz\ffe\ffe.exe" endif global $data_parent = @AppDataDir & "\corz\" & $my_name ; memory is cheap! ;) global $inputfile, $old_inputfile, $extra_args, $v_codec, $a_codec, $resize_preset, $args, $msgs, $count_ints global $installed_ini, $matof_string, $old_matof, $no_video, $no_audio, $launch_preset, $user_inputfile, $user_outputfile global $find_count = 0, $switches, $go, $do_gen=false, $do_quit=false, $do_shutdown=false, $log_string, $am_custom_buttons_disable global $arTransItems[10], $arCPUItems[6], $ReportTypesMenuItems[7], $DropCommandMenuItems[3], $CustomButtonMenuItems[502] global $tray_abort_batch, $tray_toggle_drop_window, $tray_toggle_start_minimized, $tray_toggle_delayed_start, $tray_toggle_fluid_image_menu, $tray_toggle_auto_copy_images, $tray_choose_image_folder global $ctxt_toggle_fluid_image_menu, $ctxt_toggle_auto_copy_images, $ctxt_choose_image_folder, $tray_toggle_retain_recent_files global $ffeGUI, $GUI_DropWindow, $GUI_DropWindowResizer, $output_dir, $inp_inputfile, $lab_inputfile, $inp_outputfile, $ini_outputfile global $inp_input_params, $combo_presets, $butt_add_file_arg_to_input_params, $check_do_drop_window, $check_do_matof global $radio_preset_replace, $check_store_filepaths, $combo_v_codec, $combo_v_bitrate, $combo_frames_per_second global $inp_crop_top, $inp_crop_right, $inp_crop_bottom, $inp_crop_left, $inp_x_size, $inp_y_size, $check_concatenate global $check_run_pre_job_commands, $check_run_post_job_commands, $check_overwrite global $combo_preset_resizes, $check_resize_first, $combo_a_codec, $combo_a_bitrate, $combo_target_type global $inp_extra_args, $butt_quicktest, $butt_mediareport, $lab_help_info, $edit_in_args, $edit_console_output global $butt_find, $butt_copy2clip, $butt_clearout, $butt_doit, $label_abort, $previous_pos, $do_countdown_timer global $am_always_on_top, $am_console_wordwrap, $am_trans, $am_reptypes, $am_image_buttons, $am_do_tooltips, $am_sort_presets_list, $am_cpu, $am_drop_command global $am_retain_exit_settings, $am_use_mediainfo, $am_log_each_job, $am_log_append, $am_job_log_append global $check_quit_when_done, $check_shutdown_when_done, $am_about, $clean_outputfile_ext, $outputfile global $am_custom_buttons_columns, $custom_buttons_array, $custom_buttons[502] ;arbitary number - will change global $paused, $generate_script = false, $shifted = false, $timeout=false, $portable = false, $delay_start_at = false global $current_preset = $my_name, $title_msg_string global $dropwin_visible, $dropwin_trans_real, $lab_main_drop, $image_handle, $half_trans, $drop_win_state global $hover, $hovering, $switching, $blocking global $monitors_list[1][5] $monitors_list[0][0] = 0 global $img_index = 1 global $drop_images[1][3] ; trayID and item text global $made_files[1] global $recent_files[1] global $min_width = 875 global $min_height = 442 global $height_magic = 24 ; Magic! global $maximized = $OFF, $minimized = $OFF global $start_minimized global $nTPChecked = 0 global $nCPUChecked = 0 global $DropCommands[3] = ["None", "Go", "Report"] global $ReportTypes[7] = ["default", "compact", "csv", "flat", "ini", "json", "xml"] global $arCPU[6] = ["Idle/Low", "Below Normal", "Normal", "Above Normal", "High", "Realtime (Use with caution!)"] ; "known" files we have probed already.. global $oMyError = ObjEvent("AutoIt.Error", "AAError") ; Initialize a COM error handler global $known_files ; Associative arrays in AutoIt? Hells yeah! AAInit($known_files) global $concat_list = @TempDir & "\ffe-concat-list.txt" global $grid_x = 465 global $grid_y = 145 global $buttons_y_shunt, $button_spacing ; ToolTips.. global $tip_icon, $tip_icon_index, $tip_style ; ini prefs.. global $presets, $x, $y, $width, $height, $video_codecs, $audio_codecs, $file_types, $video_bitrates, $audio_bitrates, $frames_per_second, $target_types global $preset_resizes, $always_on_top, $user_trans, $console_wordwrap, $log_location, $job_log_location, $log_append, $job_log_append, $replace_mode, $store_filepaths global $image_buttons, $magic_butt_icon_index, $dropwin_butt_icon_index, $folder_icon_index, $time_icon_index ; ; should not change, but /could/, so they're up here. global $matof_separator, $log_each_job, $cpu_priority, $short_test_frames, $fallback_folder, $console_output_font global $console_output_font_size, $custom_buttons_columns, $custom_buttons_font_size, $CBMChecked, $custom_buttons_width, $custom_buttons_height, $do_output, $do_tooltips, $tooltip_time, $drop_command global $retain_exit_settings, $sort_presets_list, $ffmpeg_binary, $plugins_path, $help_texts, $help_butts, $not_presets, $retain_recent_files global $GDI_dll, $allowed_image_types, $do_drop_window, $drop_win_image, $drop_win_transparency, $drop_win_image_folder, $fluid_image_menu, $auto_copy_images global $pre_job_commands_file, $post_job_commands_file, $batch_commands_timeout, $run_commands_with_shell, $post_file_command, $check_run_post_file_command, $run_as_dos ; ffprobe/mediainfo reporting.. global $ffprobe_loc, $report_format, $report_directory, $report_extension, $report_switches, $nRTChecked, $store_probe_type, $un_escape_output global $use_mediainfo, $mediainfo_location, $mediainfo_switches, $nDCChecked ; preset-level ffe settings.. ; if we set "defaults" here, we can use GetPrefs() to reload at any time using existing values as fall-backs global $resize_first = $OFF global $do_matof = $ON ; ffe job buttons. global $run_pre_job_commands = $UNSET global $run_post_job_commands = $UNSET global $run_post_file_command = $UNSET global $overwrite = $UNSET global $concatenate = $UNSET global $quit_when_done = $UNSET global $shutdown_when_done = $UNSET ; read-only settings.. global $default_extension = "mkv" global $kill_ffmpeg_on_exit = $ON Global Const $iMargin = 4 ; Set max and min Resize_GUI sizes ; command-line parameters.. $CmdLineRaw = StringStripWS($CmdLineRaw, 3) if $CmdLine[0] then for $i = 1 to $CmdLine[0] $CmdLine[$i] = StringStripWS($CmdLine[$i], 3) next ; file path supplied.. if StringRight($CmdLineRaw, 1) <> ")" then $inputfile = StringStripWS($CmdLine[$CmdLine[0]], 3) for $i = 1 to $CmdLine[0] if StringStripWS($CmdLine[$i], 3) <> $inputfile then $switches &= " " & StringStripWS($CmdLine[$i], 3) next else $inputfile = "" for $i = 1 to $CmdLine[0] $switches &= " " & StringStripWS($CmdLine[$i], 3) next endif endif ConsoleWrite(".\" & @ScriptName & "(" & @ScriptLineNumber & "): ==> " & "cli switches: " & $switches & $LOG_LF) ConsoleWrite(".\" & @ScriptName & "(" & @ScriptLineNumber & "): ==> " & "specified inputfile: " & $inputfile & $LOG_LF) ; process special switches.. ; $go = true means we run the job immediately if $switches then $switches = StringStripWS($switches, 3) if StringLeft($switches, 2) = "go" then $launch_preset = StringTrimRight(StringMid($switches, 4, -1), 1) $go = true elseif StringLeft($switches, 8) = "generate" then $launch_preset = StringTrimRight(StringMid($switches, 10, -1), 1) $go = true $do_gen = true $do_quit = true elseif StringLeft($switches, 4) = "load" then $launch_preset = StringTrimRight(StringMid($switches, 6, -1), 1) $go = false elseif StringLeft($switches, 3) = "run" then $launch_preset = StringTrimRight(StringMid($switches, 5, -1), 1) $go = true $do_quit = true elseif StringLeft($switches, 8) = "shutdown" then $launch_preset = StringTrimRight(StringMid($switches, 10, -1), 1) $go = true $do_shutdown = true endif endif ConsoleWrite(".\" & @ScriptName & "(" & @ScriptLineNumber & "): ==> " & "launch preset: " & $launch_preset & $LOG_LF) ; one-time special portable install switch.. if $inputfile = "portable" then $installed_ini = FileInstall(".\stuff\ffe.ini", @ScriptDir & "\" & $ini_path) ; no overwrite flag, so will fail if ffe.ini already exists. $inputfile = "" endif ; portable mode.. if FileExists($ini_path) then $portable = true $data_parent = @ScriptDir $ini_path = $data_parent & "\" & $ini_path else ; regular AppData usage.. if not FileExists($data_parent) then DirCreate($data_parent) $ini_path = $data_parent & "\" & $ini_path $installed_ini = FileInstall(".\stuff\ffe.ini", $ini_path) endif ; update ini to latest version.. if not $installed_ini then UpdateIniFile() ; STILL NO INI FILE! if not FileExists($ini_path) then ConsoleWrite(".\" & @ScriptName & "(" & @ScriptLineNumber & "): problem with ini ==> " & $ini_path & $LOG_LF) MsgBox(0, "No ffe.ini found!", "ffe.ini was not found and cound not be created." & $MSG_LF & "ffe will now exit... ", 10) exit -99 endif ; we grab /one/ pref here.. global $allow_multiple = IniReadCheckBoxValue($ini_path, $my_name, "allow_multiple", $OFF) ; if already running and multiple instances disallowed, pass the inputfile path to the already running instance.. if $allow_multiple = $OFF then ce_Singleton($my_name, 1) if @error = 183 then WinActivate($my_title) if $inputfile then ControlSetText($my_title, "", "[CLASS:Edit; INSTANCE:1]", $inputfile, 1) exit 5 endif endif ; OK! GetPrefs() MakeTray() SetHotKeys() MakeGUI() SetOnTop() MakeAppMenu() ; load either the default settings [ffe] or some specified preset.. LoadPreset($launch_preset, true) ; 2nd param set here only, for "INIT". ; Do it now? if $launch_preset and $go and $inputfile then DoIt() else if $retain_exit_settings = $ON and InArray($presets, $exit_preset) and not ce_IsPressed(10) then LoadPreset($exit_preset, true) IniDelete($ini_path, $exit_preset) ConsoleAdd("previous settings restored") endif endif ; idle loop.. global $now_time, $on_top_counter while true if $delay_start_at then DoIt() CheckMouse() ; this is set if mouse is hovering over one of our controls.. $hover = @extended ; mouseover transparency change.. if $dropwin_visible then $now_time = TimerDiff ($on_top_counter) if Mod($now_time, 10000) < 100 then SetDropWinOnTop() ; every 10s or so ; mouse-over Drop Window - provide feedback.. if $hover and not $hovering then if $gif_method then _WinAPI_SetLayeredWindowAttributes($GUI_DropWindow, 0x345, $half_trans) else SetTransparentBitmap($GUI_DropWindow, $image_handle, $half_trans) endif ; this flag indicates the mouse is inside the DropWindow ; if we didn't set & check for this, we'd be updating the transparency every 1/100th second. ; Using the two varables we get two states: switch-in & switch-out $hovering = true ; mouse leaves Drop Window.. elseif $hovering and not $hover then if $gif_method then _WinAPI_SetLayeredWindowAttributes($GUI_DropWindow, 0x345, $dropwin_trans_real) else SetTransparentBitmap($GUI_DropWindow, $image_handle, $dropwin_trans_real) endif $hovering = false endif endif ; Close the Drop Window any time (with HideDropWindow()) and THIS opens it again, so long as $do_drop_window = $ON if $do_drop_window = $ON and not $dropwin_visible then ShowDropWindow() Sleep(100) wend ; fin! ; okay, here goes. ; run the job.. func DoIt() ConsoleWrite(".\" & @ScriptName & "(" & @ScriptLineNumber & "): ==> " & "DoIt() processing: inputfile / outputfile: " & $inputfile & " / " & $outputfile & $LOG_LF) if ce_IsPressed(10) or $do_gen then $generate_script = true if $inputfile = "" then if not BrowseForInputFile() then return DoIt() return endif if not $outputfile and not IsWild($inputfile) and $do_output = $ON then if not BrowseForOutputFile() then return DoIt() return endif $user_inputfile = $inputfile $user_outputfile = $outputfile UnSetHotKeys() ClearOutput() DisableActiveInputs() HideOutputButts() ; store this so we can show the dropwin again at the end, if enabled.. $drop_win_state = $do_drop_window if $dropwin_visible then CloseDropWindow() ; Delayed Start + Countdown Timer.. if $delay_start_at then ConsoleAdd("delayed start activated") local $d_diff, $h_diff, $m_diff, $t_str, $pl, $ad, $tdiff local $diff = _DateDiff("s", _NowCalc(), $delay_start_at) while $diff > 0 ; all this for a countdown timer! if $do_countdown_timer = $ON then $t_str = "" ; Days.. $d_diff = _DateDiff("D", _NowCalc(), $delay_start_at) $pl = "" if $d_diff > 1 then $pl = "s" if $d_diff then $t_str = $d_diff & " day" & $pl ; Hours.. $h_diff = _DateDiff("h", _NowCalc(), $delay_start_at) $pl = "" $ad = "" $tdiff = $h_diff-($d_diff*24) if $tdiff > 1 then $pl = "s" if $t_str then $ad = ", " if $tdiff then $t_str &= $ad & $tdiff & " hour" & $pl $tdiff = "" ; Minutes.. $m_diff = _DateDiff("n", _NowCalc(), $delay_start_at) $pl = "" $ad = "" $tdiff = $m_diff-($h_diff*60) if $tdiff > 1 then $pl = "s" if $t_str then $ad = ", " if $tdiff then $t_str &= $ad & $tdiff & " minute" & $pl $tdiff = "" ; Seconds.. $diff = _DateDiff("s", _NowCalc(), $delay_start_at) $tdiff = $diff-($m_diff*60) $pl = "" if $tdiff > 1 then $pl = "s" if $tdiff then if $t_str then $t_str &= " and " $t_str &= $tdiff & " second" & $pl endif WinSetTitle($ffeGUI, "", $my_title & " delayed start in " & $t_str) endif if not $delay_start_at then return ReturnNow("delayed start aborted", -7) Sleep(1000) wend WinSetTitle($ffeGUI, "", $my_title) endif local $job_log, $msg, $generated, $run_command if FileExists($concat_list) then FileDelete($concat_list) ; Pre-Job Commands.. if $run_pre_job_commands = $ON then LoadPreCommands() ;always nice to grab this fresh, in case of recent edits.. RunCommandsFile($pre_job_commands_file, $job_log, $generated, "Pre") Sleep(1000) endif ; $run_files is always an array.. for single files, we create an array with a single element.. local $run_files[2] = [1, $inputfile] ; BATCH RUN.. if IsWild($inputfile) then ; it's a batch, e.g. "I:\Rip\ffe\*.mkv" local $run_parent = GetParent($inputfile) ; "I:\Rip\ffe" local $inputfile_extension = GetExtension($inputfile) ; "mkv" local $full_filename = "" ; user entered wildcards: send the entire filename with wildcards to ReadDir() if IsWild(Basename($inputfile)) then $full_filename = Basename($inputfile) ; gather names of all matching files in the directory.. if StringInStr($inputfile, "://") then ; ftp/http return ReturnNow("error: cannot process wilcards in URLS.", -3) else $run_files = ReadDir($run_parent, $inputfile_extension, $full_filename) endif if IsArray($run_files) and $run_files[0] > 0 then ; enable "Abort Batch" menu option. ; put back base path.. for $ra = 1 to $run_files[0] local $this_fn = $run_parent & "\" & $run_files[$ra] if IsDir($this_fn) then $run_files[$ra] = "" else $run_files[$ra] = $this_fn endif next else return ReturnNow($LOG_LF & "error creating batch. sorry.", -1) endif endif local $batch = $OFF $abort_batch = false if $run_files[0] > 1 then $batch = $ON TrayItemSetState($tray_abort_batch, $TRAY_ENABLE) endif ; reset "made files" for this job.. redim $made_files[1] for $runs = 1 to $run_files[0] if not $run_files[$runs] then continueloop ; in case of empties from bad dir items $inputfile = $run_files[$runs] DoArgsCreate($batch) ; the only place this is set - right inside a batch.. we call the function directly, too. if $inputfile = $outputfile then if $go then ; this should never happen, but just in case.. $outputfile = RemoveExtension($outputfile) & MakeRandomAlphaNumericString(8) & "." & GetExtension($outputfile) else MsgBox(0, "file name clash!", "You will need to choose a different output filename.. ", 0, $ffeGUI) if (BrowseForOutputFile() = 0) then return ReturnNow($LOG_LF & "error starting job: file name clash.", -2) endif DoIt() return endif endif ; Already made this file - add random suffix to file name.. if InArray($made_files, $outputfile) then local $old_of = $outputfile $outputfile = RemoveExtension($outputfile) & MakeRandomAlphaNumericString(8) & "." & GetExtension($outputfile) ; update args with new file name.. $args = StringReplace($args, $old_of, $outputfile) endif ; $outputfile is now SET! if $concatenate = $ON and $batch = $ON then FileWriteLine($concat_list, "file '" & $outputfile & "'") endif GUICtrlSetState($label_abort, $GUI_SHOW) $title_msg_string = $my_title & " [press 'F4' to abort]" if IsWild(GUICtrlRead($inp_inputfile)) then $title_msg_string = $my_title & " [press pause/break to abort batch]" WinSetTitle($ffeGUI, "", $title_msg_string) ; we will need to pass the !q" to ffmpeg manually.. HotKeySet("{F4}", "HK_FFmpegAbort") ; this also aborts a regular job.. HotKeySet("{PAUSE}", "HK_RunningAbortBatch") HotKeySet("{SCROLLLOCK}", "HK_ProcessPauseSuspend") ; RUN the amazing ffmpeg.. $paused = false $msg = $LOG_LF & "starting ffe job on " & @YEAR & "-" & @MON & "-" & @MDAY & " @ " & @hour & ":" & @min & ":" & @sec & "." & @msec & $LOG_LF & "command-line: " & $args & $LOG_LF & $LOG_LF DoLog($msg) $job_log &= $msg ; This is REQUIRED to get plugins to work.. EnvSet("FREI0R_PATH", $plugins_path) ; Windows batch script output.. if $generate_script then $generated &= $args & $LOG_LF else ConsoleWrite(".\" & @ScriptName & "(" & @ScriptLineNumber & "): ==> " & "Run() ffmpeg with args: " & $args & $LOG_LF) $ffmpeg = Run($args, @ScriptDir, @SW_HIDE, BitOr($STDERR_CHILD, $STDIN_CHILD)) ProcessSetPriority($ffmpeg, $cpu_priority) local $timestamp = TimerInit() local $console_out while true Sleep(25) ; Capture Output.. $console_out = StderrRead($ffmpeg) if @error then exitloop if $abort_batch then StdinWrite($ffmpeg, "q") Sleep(250) ProcessClose($ffmpeg) exitloop 2 endif if not @extended then continueloop if StringInStr($console_out, "already exists. Overwrite ? [y/N]") then WinActivate($ffeGUI) WinSetTitle($ffeGUI, "", $my_title & " [Overwrite existing file? (hit 'y' or 'n')]") HotKeySet("y", "HK_FFmpegResponseYes") HotKeySet("n", "HK_FFmpegResponseNo") endif $console_out = StringStripWS($console_out, 3) $job_log &= DoLog(SetConsoleOutput($console_out)) & $LOG_LF ; only $job_log gets the extra $LOG_LF wend StdioClose($ffmpeg) $msg = $LOG_LF & "Completed in " & SecondsToDHMS(TimerDiff($timestamp)/1000) & " (" & Round(TimerDiff($timestamp) / 1000, 2) & " seconds)" & $LOG_LF & _ "--------------------------------------------------------------------------------" & $LOG_LF & $LOG_LF & $LOG_LF DoLog($msg) $job_log &= $msg $job_log &= DoLog(SetConsoleOutput($console_out)) & $LOG_LF ; only $job_log gets the extra $LOG_LF endif ; We keep a tally of all files created during the job. ; if ffmpeg wants to output some file with the same name, we will add a random suffix to the name. ; This is designed to catch a situation where the user has used a *.* wildcard and there are associated ; files in the same dir as the videos, e.g. "movie.srt". The user sets up a batch job and wakes the ; next morning to find 10 *tiny* movie files which won't play. Nope, it's never happened to me. Seriously. if FileExists($outputfile) then ArrayAdd($made_files, $outputfile) ; add file to recent files and re-build the tray.. ArrayAdd($recent_files, $outputfile, true, true) ; we also use this data to create a "Recent Files" list in the Tray menu.. MakeTray() ; Run the Post-File Command.. (you almost could do this in one line, but where's the fun in that?) ; Also, tricks like > redirection would be out. if $run_post_file_command = $ON then $timeout = false if $batch_commands_timeout then AdLibRegister("RunCommandsTimeout", $batch_commands_timeout*1000*60) $run_command = DeTokenize(String($post_file_command)) local $pipe_to=false, $pipe_data="" ; recognise user redirection in post-fiele command.. if StringInStr($run_command, ">") then local $run_arr = StringSplit($run_command, ">") if IsArray($run_arr) and $run_arr[0] = 2 then $run_command = $run_arr[1] $pipe_to = StringStripWS(StringReplace($run_arr[2], '"', ""), 3) $job_log &= DoLog(ConsoleAdd("detected '>' redirection in command. outputting STDIO to file: " & $pipe_to)) & $LOG_LF endif endif $msg = "running post-file command: " & $run_command $job_log &= DoLog(ConsoleAdd($msg)) & $LOG_LF local $err local $command_run = Run($run_command, "", @SW_HIDE, $STDOUT_CHILD) while true $err = false $console_out = StdOutRead($command_run) $err = @error $console_out = StringStripWS($console_out, 3) if $console_out then if $pipe_to then $pipe_data &= $console_out $job_log &= DoLog(ConsoleAdd($console_out)) & $LOG_LF endif if $err or $timeout then exitloop Sleep(25) wend StdioClose($command_run) ; write out user ">" redirection.. if $pipe_to then FileWrite($pipe_to, $pipe_data) AdLibUnRegister("RunCommandsTimeout") endif endif next ; ConCATenate Output files.. if $concatenate = $ON and $batch = $ON then local $write_loc = $ffmpeg_binary local $write_cat = $concat_list if $generate_script then $write_loc = '"' & $ffmpeg_binary & '"' $write_cat = "ffe-concat-list.txt" endif local $ow_args if $overwrite = $ON then $ow_args &= " -y " $run_command = $write_loc & " -f concat -i """ & $write_cat & """ " & $ow_args & "-c copy " & $output_dir & "\joined." & $clean_outputfile_ext if $generate_script then $generated &= $run_command & $LOG_LF else $msg = "Concatenating files.." $job_log &= DoLog(ConsoleAdd($msg)) & $LOG_LF $ffmpeg = Run($run_command, @ScriptDir, @SW_HIDE, BitOr($STDERR_CHILD, $STDIN_CHILD, $STDOUT_CHILD)) ; re-use process handle so ffmpeg hotkeys still work in concat job while true Sleep(25) $err = false $console_out = StderrRead($ffmpeg) $err = @error if not @extended then continueloop if $abort_batch then Sleep(250) exitloop endif $console_out = StringStripWS($console_out, 3) $job_log &= DoLog(SetConsoleOutput($console_out)) & $LOG_LF if $err then exitloop wend StdioClose($ffmpeg) endif endif ; Post-Job Commands.. if $run_post_job_commands = $ON then LoadPostCommands() RunCommandsFile($post_job_commands_file, $job_log, $generated, "Post") Sleep(1000) endif DoLog("out", $log_append, $LOG_LF & $LOG_LF) TrayItemSetState($tray_abort_batch, $TRAY_DISABLE) HotKeySet("{PAUSE}") HotKeySet("{SCROLLLOCK}") HotKeySet("{F4}") HotKeySet("y") HotKeySet("n") WinSetTitle($ffeGUI, "", $my_title) GUICtrlSetState($label_abort, $GUI_HIDE) SetConsoleOutput($job_log) ShowOutputButts() if $log_each_job = $ON and not $generate_script then SaveOutput($job_log) if $generate_script then local $save_bat if $do_gen then $save_bat = @WorkingDir & "\ffe.bat" else local $save_bat_dir = IniRead($ini_path, $my_name, "save_bat_dir", @MyDocumentsDir) DialogOpen() $save_bat = FileSaveDialog("Save/Append Batch Script", $save_bat_dir, "All (*.*)|Batch files (*.bat)|Command files (*.cmd)", $FD_PATHMUSTEXIST, "ffe.bat", $ffeGUI) DialogClose() if FileExists(GetParent($save_bat)) then IniWrite($ini_path, $my_name, "save_bat_dir", GetParent($save_bat)) endif if not @error then local $job_batch_file = FileOpen($save_bat, $FO_APPEND+$FO_UTF8_NOBOM) FileWrite($job_batch_file, $generated) FileClose($job_batch_file) ConsoleAdd($LOG_LF & "saved batch script to: " & $save_bat) endif FileMove($concat_list, GetParent($save_bat) & "\ffe-concat-list.txt", $FC_OVERWRITE) endif ; Shutdown PC.. if $do_shutdown or $shutdown_when_done = $ON then local $shutdown_response if not $do_shutdown then DialogOpen() $shutdown_response = MsgBox(1, "ffe will now shutdown your computer..", _ "As instructed, ffe will now shutdown your computer. " & $MSG_LF & $MSG_LF & _ "To abort the shutdown process, click [Cancel] within the next 60 seconds." & $MSG_LF & $MSG_LF & _ "Click [OK] to shutdown immediately.", 60, $ffeGUI) DialogClose() else $shutdown_response = 1 endif if $shutdown_response = 1 or $shutdown_response = -1 then Shutdown(BitOr($SD_SHUTDOWN, $SD_POWERDOWN)) DoQuit() endif ; QUIT.. elseif $do_quit or $quit_when_done = $ON then local $quit_response if not $do_quit then DialogOpen() $quit_response = MsgBox(1, "ffe will now quit..", _ "As instructed, ffe will now quit. " & $MSG_LF & $MSG_LF & _ "To abort, click [Cancel] within the next 10 seconds.", 10, $ffeGUI) DialogClose() else $quit_response = 1 endif if $quit_response = 1 or $quit_response = -1 then DoQuit() endif endif $do_drop_window = $drop_win_state EnableActiveInputs() UpdateInput() SetHotKeys() GUICtrlSetState($edit_console_output, $GUI_FOCUS) if $delay_start_at then TrayItemSetState($tray_toggle_delayed_start, $OFF) $delay_start_at = false ConsoleAdd("Delayed Job Complete (like you can see this!)") endif endfunc ; get ini values.. func GetPrefs($current_section=$my_name) ; specify section (for later use) ; the available sections (presets+) $presets = IniReadSectionNames($ini_path) $x = Int(IniRead($ini_path, $my_name, "x", -1)) $y = Int(IniRead($ini_path, $my_name, "y", -1)) $width = Int(IniRead($ini_path, $my_name, "width", 935)) if $width < $min_width then $width = $min_width $height = Int(IniRead($ini_path, $my_name, "height", 590)) if $height < $min_height then $height = $min_height $minimized = IniReadCheckBoxValue($ini_path, $my_name, "minimized", $OFF) $maximized = IniReadCheckBoxValue($ini_path, $my_name, "maximized", $OFF) $start_minimized = IniReadCheckBoxValue($ini_path, $my_name, "start_minimized", $OFF) if $start_minimized = $ON then $minimized = $ON if $minimized = $ON and $maximized = $ON then $maximized = SwitchBool($maximized) $always_on_top = IniReadCheckBoxValue($ini_path, $my_name, "always_on_top", $OFF) $user_trans = IniRead($ini_path, $my_name, "transparency", 0) $do_output = IniReadCheckBoxValue($ini_path, $my_name, "do_output", $ON) ; Master ToolTips Switch.. $do_tooltips = IniReadCheckBoxValue($ini_path, $my_name, "do_tooltips", $ON) $tooltip_time = IniRead($ini_path, $my_name, "tooltip_time", 10000) ; ToolTip Icon: local $tip_icon_res = IniRead($ini_path, $my_name, "tip_icon_res", $me_app) if not $tip_icon_res then $tip_icon_res = $me_app $tip_icon_index = IniRead($ini_path, $my_name, "tip_icon_index", 0) if not $tip_icon_index then $tip_icon_index = 0 $tip_icon = $me_app & "," & $tip_icon_index ; System ToolTip Icon override.. local $system_tip_icon = IniRead($ini_path, $my_name, "system_tip_icon", "") if $system_tip_icon and $system_tip_icon >= 0 and $system_tip_icon < 7 then $tip_icon = $system_tip_icon ; ToolTip Style.. $tip_style = IniRead($ini_path, $my_name, "tip_style", 1) $sort_presets_list = IniReadCheckBoxValue($ini_path, $my_name, "sort_presets_list", $ON) ; use images on (some) buttons? $image_buttons = IniReadCheckBoxValue($ini_path, $my_name, "image_buttons", $ON) $replace_mode = IniReadCheckBoxValue($ini_path, $my_name, "replace_mode", $ON) $store_filepaths = IniReadCheckBoxValue($ini_path, $my_name, "store_filepaths", $OFF, true) ; tristate - unset to grey control $console_wordwrap = IniReadCheckBoxValue($ini_path, $my_name, "console_wordwrap", $OFF) $drop_command = IniRead($ini_path, $my_name, "drop_command", "") $retain_exit_settings = IniReadCheckBoxValue($ini_path, $my_name, "retain_exit_settings", $ON) $do_countdown_timer = IniReadCheckBoxValue($ini_path, $my_name, "do_countdown_timer", $ON) ; The nifty custom buttons.. $custom_buttons_columns = IniRead($ini_path, $my_name, "custom_buttons_columns", "auto") if $custom_buttons_columns = "auto" then $CBMChecked = 501 else if $custom_buttons_columns and $custom_buttons_columns < 0 then $custom_buttons_columns = 0 $CBMChecked = $custom_buttons_columns endif $custom_buttons_width = int(IniRead($ini_path, $my_name, "custom_buttons_width", 75)) if $custom_buttons_width and ($custom_buttons_width < 8 or $custom_buttons_width > 150) then $custom_buttons_width = 75 $custom_buttons_height = int(IniRead($ini_path, $my_name, "custom_buttons_height", 27)) $buttons_y_shunt = int(IniRead($ini_path, $my_name, "buttons_y_shunt", 11)) $button_spacing = int(IniRead($ini_path, $my_name, "button_spacing", 3)) $custom_buttons_font_size = Round(IniRead($ini_path, $my_name, "custom_buttons_font_size", 9), 2) LoadCustomButtonData() ; Logging.. $log_append = IniReadCheckBoxValue($ini_path, $my_name, "log_append", $OFF) $job_log_append = IniReadCheckBoxValue($ini_path, $my_name, "job_log_append", $OFF) $log_each_job = IniReadCheckBoxValue($ini_path, $my_name, "log_each_job", $ON) ; Log location.. GetLogLocation() $job_log_location = DeTokenize(IniRead($ini_path, $my_name, "job_log_location", "@datadir\logs")) ; ffmpeg binary location.. $i = DeTokenize(IniRead($ini_path, $my_name, "ffmpeg_binary", "")) if FileExists($i) then $ffmpeg_binary = $i else SetFFMpegBinaryLocation() endif ; ffprobe/mediainfo.. GetReportingValues() ; ffprobe plugins.. $plugins_path = DeTokenize(IniRead($ini_path, $my_name, "plugins_path", "")) if (not $plugins_path) and FileExists($ffmpeg_binary) then $plugins_path = GetParent($ffmpeg_binary) & "\plugins" IniWrite($ini_path, $my_name, "plugins_path", TokenizeString($plugins_path)) endif ; custom help.. $help_texts = IniRead($ini_path, $my_name, "help_texts", "Main|help.nfo|-h,Formats|help-formats.nfo|-formats,Filters|help-filters.nfo|-filters,Codecs|help-codecs.nfo|-codecs,Full|help-full.nfo|-h full") if StringInStr($help_texts, "|") then $help_texts = StringSplit($help_texts, ",") global $help_butts[$help_texts[0]+1] = [$help_texts[0]] else $help_texts = "" endif $not_presets = IniRead($ini_path, $my_name, "not_presets", $my_name & "," & $NAME_BUTTONS & "," & $exit_preset) if not $not_presets then $not_presets = $my_name & "," & $NAME_BUTTONS & "," & $exit_preset $not_presets = StringSplit($not_presets, ",") ; button image indexes.. $magic_butt_icon_index = IniRead($ini_path, $my_name, "magic_butt_icon_index", -6) $dropwin_butt_icon_index = IniRead($ini_path, $my_name, "dropwin_butt_icon_index", -13) $folder_icon_index = IniRead($ini_path, $my_name, "folder_icon_index", -5) $time_icon_index = IniRead($ini_path, $my_name, "time_icon_index", -11) $matof_separator = IniRead($ini_path, $my_name, "matof_separator", " ") ; cuz above " " don't work, for some reason :/ .. if $matof_separator = "" then $matof_separator = " " ; CPU priority.. $cpu_priority = int(IniRead($ini_path, $my_name, "cpu_priority", 2)) if $cpu_priority < 0 or $cpu_priority > 5 then $cpu_priority = 2 $nCPUChecked = $cpu_priority $video_codecs = IniRead($ini_path, $current_section, "video_codecs", "||copy|a64multi|a64multi5|alias_pix|amv|apng|asv1|asv2|avrp|avui|ayuv|bmp|libxavs|cinepak|cljr|libschroedinger|dnxhd|dpx|dvvideo|ffv1|ffvhuff|flashsv|flashsv2|flv|gif|h261|h263|h263p|libx264|libx264rgb|libx265|huffyuv|jpeg2000|libopenjpeg|jpegls|ljpeg|mjpeg|mpeg1video|mpeg2video|mpeg4|libxvid|msmpeg4v2|msmpeg4|msvideo1|pam|pbm|pcx|pgm|pgmyuv|png|ppm|prores|prores_aw|prores_ks|qtrle|r10k|r210|rawvideo|roqvideo|rv10|rv20|sgi|snow|sunrast|svq1|targa|libtheora|tiff|utvideo|v210|v308|v408|v410|libvpx|libvpx-vp9|libwebp|wmv1|wmv2|xbm|xface|xwd|y41p|yuv4|- disable video -") $audio_codecs = IniRead($ini_path, $current_section, "audio_codecs", "||copy|aac|libvo_aacenc|ac3|ac3_fixed|adpcm_adx|g722|g726|adpcm_ima_qt|adpcm_ima_wav|adpcm_ms|adpcm_swf|adpcm_yamaha|alac|libopencore_amrnb|libvo_amrwbenc|comfortnoise|dca|eac3|flac|g723_1|libgsm|libgsm_ms|libilbc|mp2|mp2fixed|libtwolame|libmp3lame|nellymoser|libopus|pcm_alaw|pcm_f32be|pcm_f32le|pcm_f64be|pcm_f64le|pcm_mulaw|pcm_s16be|pcm_s16be_planar|pcm_s16le|pcm_s16le_planar|pcm_s24be|pcm_s24daud|pcm_s24le|pcm_s24le_planar|pcm_s32be|pcm_s32le|pcm_s32le_planar|pcm_s8|pcm_s8_planar|pcm_u16be|pcm_u16le|pcm_u24be|pcm_u24le|pcm_u32be|pcm_u32le|pcm_u8|real_144|roq_dpcm|s302m|sonic|sonicls|libspeex|tta|vorbis|libvorbis|wavpack|libwavpack|wmav1|wmav2|- disable audio -") $file_types = IniRead($ini_path, $current_section, "file_types", "All (*.*)|Audio Files (*.mp3;*.wav;*.ogg;*.mp2;*.wma;*.asf;*.asx;*.ape;*.shn;*.mpc;*.flac;*.tta;*.m4a;*.aif;*.aac)|Movie files (*.avi;*.mpg;*.mpeg;*.mov;*.mkv;*.ogm;*.ogv;*.mp4;*.asf;*.wmv;*.rm;*.flv;*.vob;*.webm;*.rmvb;*.nsv;*.mpe;*.3gp)") $video_bitrates = IniRead($ini_path, $current_section, "video_bitrates", "||360k|512k|640k|768k|1000k|1200k|1600k|1800k|2000k|4000k|8000K|16000K|32000K|64000K") $audio_bitrates = IniRead($ini_path, $current_section, "audio_bitrates", "||32k|48k|56k|64k|80k|96k|112k|128k|160k|192k|256k|320k|480k") $frames_per_second = IniRead($ini_path, $current_section, "frames_per_second", "||12|15|20|23.976|24|25|29.97|30|50|60") $target_types = IniRead($ini_path, $current_section, "target_types", "||pal-vcd|dvd|ntsc-svcd|vcd|svcd|dv|dv50") $preset_resizes = IniRead($ini_path, $current_section, "preset_resizes", "||sqcif|qcif|cif|4cif|qqvga|qvga|vga|svga|xga|uxga|qxga|sxga|qsxga|hsxga|wvga|wxga|wsxga|wuxga|woxga|wqsxga|wquxga|whsxga|whuxga|cga|ega|hd480|hd720|hd1080") $console_output_font = IniRead($ini_path, $current_section, "console_output_font", "Lucida Console") $console_output_font_size = IniRead($ini_path, $current_section, "console_output_font_size", 9) $short_test_frames = IniRead($ini_path, $current_section, "short_test_frames", 1000) ; we will read this again, as-needed, as dynamic @tokens may change, also we can use this as a fall-back, in case no fallback_folder is specified insside the preset $fallback_folder = DeTokenize(IniRead($ini_path, $current_section, "fallback_folder", "@parent")) ; preset-level settings.. $resize_first = IniReadCheckBoxValue($ini_path, $current_section, "resize_first", $resize_first) $do_matof = IniReadCheckBoxValue($ini_path, $current_section, "do_matof", $do_matof) ; ffe job buttons.. $run_pre_job_commands = IniReadCheckBoxValue($ini_path, $current_section, "run_pre_job_commands", $run_pre_job_commands, true) $run_post_job_commands = IniReadCheckBoxValue($ini_path, $current_section, "run_post_job_commands", $run_post_job_commands, true) $run_post_file_command = IniReadCheckBoxValue($ini_path, $current_section, "run_post_file_command", $run_post_file_command, true) $post_file_command = IniRead($ini_path, $current_section, "post_file_command", "") $overwrite = IniReadCheckBoxValue($ini_path, $current_section, "overwrite", $overwrite, true) $concatenate = IniReadCheckBoxValue($ini_path, $current_section, "concatenate", $concatenate, true) $quit_when_done = IniReadCheckBoxValue($ini_path, $current_section, "quit_when_done", $quit_when_done, true) $shutdown_when_done = IniReadCheckBoxValue($ini_path, $current_section, "shutdown_when_done", $shutdown_when_done, true) ; read-only preset-level settings.. $default_extension = IniRead($ini_path, $current_section, "default_extension", $default_extension) $kill_ffmpeg_on_exit = IniReadCheckBoxValue($ini_path, $current_section, "kill_ffmpeg_on_exit", $kill_ffmpeg_on_exit) ; funky drop target.. $do_drop_window = IniReadCheckBoxValue($ini_path, $my_name, "do_drop_window", $ON) GetDropWinImage() GetDropWinImageFolder() $drop_win_transparency = IniRead($ini_path, $current_section, "drop_win_transparency", 0) GetRealTrans() $allowed_image_types = IniRead($ini_path, $current_section, "allowed_image_types", "bmp,png,ico,emf,wmf") if $allowed_image_types = "*" then $allowed_image_types = "bmp,png,ico,emf,wmf,jpg,jpeg,gif,tif,tiff" $allowed_image_types = "," & $allowed_image_types & "," $fluid_image_menu = IniReadCheckBoxValue($ini_path, $my_name, "fluid_image_menu", $OFF) $auto_copy_images = IniReadCheckBoxValue($ini_path, $my_name, "auto_copy_images", $ON) $GDI_dll = IniRead($ini_path, $my_name, "GDI_dll", "gdiplus.dll") endfunc ; The main ffe GUI/Window.. func MakeGUI() ; handy measurements.. local $tip, $ttt, $column_two = 590 if ($width / 2) > $column_two then $column_two = ($width / 2) ; Biting the bullet.. AutoItSetOption("GUICoordMode", 0) ; create the GUI.. $ffeGUI = GUICreate($my_title, $width, $height, $x, $y, BitOr($WS_SIZEBOX, $WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_CAPTION, $WS_POPUP), $WS_EX_ACCEPTFILES) GUISetIcon($me_app, 0) ; setup some GUI events.. GUISetOnEvent($GUI_EVENT_CLOSE, "User_DoQuit") GUISetOnEvent($GUI_EVENT_RESIZED, "ResizeSaveXYPrefs") GUISetOnEvent($GUI_EVENT_MINIMIZE, "ToggleWindow") GUISetOnEvent($GUI_EVENT_MAXIMIZE, "ToggleMaximizeWindow") GUISetOnEvent($GUI_EVENT_RESTORE, "ToggleMaximizeWindow") GUISetOnEvent($GUI_EVENT_PRIMARYUP, "PrimaryUpCheckSize") GUISetOnEvent($GUI_EVENT_DROPPED, "GetDroppedItem") ; Catch focus passing to $inp_outputfile GUIRegisterMsg($WM_COMMAND, "CheckFocus") ; input file input.. GUISetCoord(10, 12) $lab_inputfile = GUICtrlCreateLabel("input:", 0, 0, 36) $ttt = "Input File(s)" $tip = "Enter the full path to the input file (or just drag it in). " GUICtrlSetTipOptional(-1, $tip & $MSG_LF & "Click here to view the source file directory. ", $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) GUICtrlSetOnEvent(-1, "OpenSourceDir") $inp_inputfile = GUICtrlCreateInput($inputfile, 40, 0, $width-110, 18) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetOnEvent(-1, "UpdateInput") GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) GUICtrlSetState(-1, $GUI_DROPACCEPTED) ; Drag-And-Drop Window Activation.. if $image_buttons = $ON then $check_do_drop_window = GUICtrlCreateCheckbox("", $width-103, -1, 20, 20, BitOr($BS_AUTOCHECKBOX, $BS_PUSHLIKE, $BS_ICON)) if @compiled then GUICtrlSetImage(-1,$me_app, $dropwin_butt_icon_index, 0) else GUICtrlSetImage(-1, ".\icons\target.ico", -1, 0) endif else $check_do_drop_window = GUICtrlCreateCheckbox("ꙩ", $width-103, 0, 20, 20, BitOr($BS_AUTOCHECKBOX, $BS_PUSHLIKE)) endif GUICtrlSetTipOptional(-1, "Opens a shaped (with the right image), transparent window you can use to drop files into. " & $MSG_LF & _ "It behaves just like your regular input file input, files are queued up or processed with your" & $MSG_LF & _ "current 'Drag-And-Drop Command'. Also use it to set the location of your ffmpeg binary.", "Floating Drop Window (F9)") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) GUICtrlSetOnEvent(-1, "ClickToggleDropWindow") GUICtrlSetState(-1, $do_drop_window) if $image_buttons = $ON then GUICtrlCreateButton("...", 24, 0, 20, 20, BitOr($WS_TABSTOP,$BS_FLAT,$BS_ICON)) if @compiled then GUICtrlSetImage(-1,$me_app, $folder_icon_index, 0) else GUICtrlSetImage(-1, ".\icons\document-outline.ico", -1, 0) endif else GUICtrlCreateButton("...", $width-79, 0, 20, 20, BitOr($WS_TABSTOP,$BS_FLAT)) endif GUICtrlSetTipOptional(-1, "Browse to locate the input file.", $ttt) GUICtrlSetOnEvent(-1, "BrowseForInputFile") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) ; output file input!.. GUISetCoord(10, 39) $ttt = "Output File(s)" GUICtrlCreateLabel("output: ", 0, 0, 36) $tip = "Enter the full path to the output file (or drag in a file or folder)." GUICtrlSetTipOptional(-1, $tip & $MSG_LF & _ "NOTE: you can click this label to disable output altogether," & $MSG_LF & _ "e.g. for creating image sequences (enter your output directly" & $MSG_LF & _ "into the extra agruments input)." & $MSG_LF & $MSG_LF & _ "NOTE; You Must Put The Output File(s) LAST", $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) GUICtrlSetOnEvent(-1, "ToggleOutput") ; the actual input area for file output *phew*.. $inp_outputfile = GUICtrlCreateInput($outputfile, 40, 0, $width-110, 18) GUICtrlSetTipOptional(-1, $tip & $MSG_LF & "NOTE: As soon as you click inside here, MATOF is disabled. ", $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) GUICtrlSetState(-1, $GUI_DROPACCEPTED) ; magic auto-transforming output filename [MATOF!] .. if $image_buttons = $ON then $check_do_matof = GUICtrlCreateCheckbox("", $width-103, -1, 20, 20, BitOr($BS_AUTOCHECKBOX, $BS_PUSHLIKE, $BS_ICON)) if @compiled then GUICtrlSetImage(-1,$me_app, $magic_butt_icon_index, 0) else GUICtrlSetImage(-1, ".\icons\magic-wand.ico", -1, 0) endif else $check_do_matof = GUICtrlCreateCheckbox("!!!", $width-103, 0, 20, 20, BitOr($BS_AUTOCHECKBOX, $BS_PUSHLIKE)) endif GUICtrlSetTipOptional(-1, "Magic Auto-Transforming Output Filename (MATOF!) (Ctrl+M)" & $MSG_LF & $MSG_LF & _ "Check this to have the output file automatically transformed when " & $MSG_LF & _ "you change stuff below (handy for doing lots of quick tests). "& $MSG_LF & $MSG_LF & _ "NOTE: When you are running a batch, you cannot disable this. ", "MATOF!") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) GUICtrlSetState(-1, $do_matof) GUICtrlSetOnEvent(-1, "ClickToggleMatofStatus") ; browse for output file.. if $image_buttons = $ON then GUICtrlCreateButton("...", 24, 0, 20, 20, BitOr($WS_TABSTOP,$BS_FLAT,$BS_ICON)) if @compiled then GUICtrlSetImage(-1,$me_app, $folder_icon_index, 0) else GUICtrlSetImage(-1, ".\icons\document-outline.ico", -1, 0) endif else GUICtrlCreateButton("...", 24, 0, 20, 20, BitOr($WS_TABSTOP,$BS_FLAT)) endif GUICtrlSetTipOptional(-1, "Browse to specify the output file. ", $ttt) GUICtrlSetOnEvent(-1, "BrowseForOutputFile") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) ; ffe job buttons.. ; tip not seen for groups.. bummer :/ Hmm.. what if ; hey this is clever (even cleverer for combos - see below) GUISetCoord(10, 62) GUICtrlCreateLabel("", 0, 0, $column_two-18, 14, 0, 0) ; GUICtrlSetBkColor(-1, $COLOR_RED) GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) GUICtrlSetTipOptional(-1, "These options are always inherited, or not, from the chosen preset. They can be Enabled, Disabled, or Unset." & $MSG_LF & _ "Unless an option is specifically set (on/off) in a preset, the old setting will be in effect.", "ffe job controls") GUISetCoord(10, 62) GUICtrlCreateGroup("ffe job.. ", 0, 0, $column_two-18, 35) ; tip not seen.. bummer :/ GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) $ttt = "Pre-Job Commands" $check_run_pre_job_commands = GUICtrlCreateCheckbox(" pre-job-commands ", 6, 13, 105, 18, BitOr($BS_AUTO3STATE,$BS_RIGHTBUTTON)) GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) GUICtrlSetTipOptional(-1, "Before the job runs, run your specified pre-job commands batch file? ", $ttt) GUICtrlSetOnEvent(-1, "ClickSetPreJobCommands") GUICtrlSetState(-1, $run_pre_job_commands) local $menu_check_run_pre_job_commands = GUICtrlCreateContextMenu($check_run_pre_job_commands) GUICtrlCreateMenuItem("Specify New Pre-Job Commands File..", $menu_check_run_pre_job_commands) GUICtrlSetOnEvent(-1, "SpecifyPreJobCommandsFile") $ttt = "Post-File Commands" $check_run_post_file_command = GUICtrlCreateCheckbox(" post-file-command ", 112, 0, 110, 18, BitOr($BS_AUTO3STATE,$BS_RIGHTBUTTON)) GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) GUICtrlSetTipOptional(-1, "After each file is processed, run your specified post-file command. " & $MSG_LF & "Right-click the control for edit options.", $ttt) GUICtrlSetOnEvent(-1, "ClickSetPostFileCommand") GUICtrlSetState(-1, $run_post_file_command) local $menu_check_run_post_file_command = GUICtrlCreateContextMenu($check_run_post_file_command) GUICtrlCreateMenuItem("Edit The Post-File Command..", $menu_check_run_post_file_command) GUICtrlSetOnEvent(-1, "SpecifyPostFileCommand") $ttt = "Post-Job Commands" $check_run_post_job_commands = GUICtrlCreateCheckbox(" post-job-commands ", 117, 0, 110, 18, BitOr($BS_AUTO3STATE,$BS_RIGHTBUTTON)) GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) GUICtrlSetTipOptional(-1, "After the job runs, run your specified post-job commands batch file? ", $ttt) GUICtrlSetOnEvent(-1, "ClickSetPostJobCommands") GUICtrlSetState(-1, $run_post_job_commands) local $menu_check_run_post_job_commands = GUICtrlCreateContextMenu($check_run_post_job_commands) GUICtrlCreateMenuItem("Specify New Post-Job Commands File..", $menu_check_run_post_job_commands) GUICtrlSetOnEvent(-1, "SpecifyPostJobCommandsFile") $ttt = "Overwrite" $check_overwrite = GUICtrlCreateCheckbox(" overwrite ", 115, 0, 62, 20, BitOr($BS_AUTO3STATE,$BS_RIGHTBUTTON)) GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) GUICtrlSetTipOptional(-1, "Should ffe tell ffmpeg to overwrite existing files? ", $ttt) GUICtrlSetOnEvent(-1, "ClickSetOverwrite") GUICtrlSetState(-1, $overwrite) $check_concatenate = GUICtrlCreateCheckbox(" join ", 70, 0, 34, 20, BitOr($BS_AUTO3STATE,$BS_RIGHTBUTTON)) GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) GUICtrlSetTipOptional(-1, "During batch operations, should ffe tell ffmpeg to join the output files together? ", $ttt) GUICtrlSetOnEvent(-1, "ClickSetConcatenateFiles") GUICtrlSetState(-1, $concatenate) $ttt = "Quit When Done" $check_quit_when_done = GUICtrlCreateCheckbox(" quit ", 40, 0, 36, 20, BitOr($BS_AUTO3STATE,$BS_RIGHTBUTTON)) GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) GUICtrlSetTipOptional(-1, "Should ffe quit when the job is complete? ", $ttt) GUICtrlSetOnEvent(-1, "ClickSetQuitWhenDone") GUICtrlSetState(-1, $quit_when_done) $ttt = "Shutdown PC When Done" $check_shutdown_when_done = GUICtrlCreateCheckbox(" shutdown ", 40, 0, 64, 20, BitOr($BS_AUTO3STATE,$BS_RIGHTBUTTON)) GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) GUICtrlSetTipOptional(-1, "Should ffe shutdown your computer when the job is complete? ", $ttt) GUICtrlSetOnEvent(-1, "ClickSetShutdownWhenDone") GUICtrlSetState(-1, $shutdown_when_done) ShutDownOverrideQuit() ; input override parameter option things.. GUISetCoord(10, 97) $ttt = "Input Parameter Override" GUICtrlCreateGroup("input parameter override.. ", 0, 0, $column_two-18, 39) GUICtrlSetResizing(-1, $GUI_DOCKALL) $tip = "If you need to specify special parameters for the input file, do that here. " & $MSG_LF & _ "This is the place where you would find an SRT file, for example." & $MSG_LF & $MSG_LF & _ "NOTE: these parameters will usually override output parameters, forcing " & $MSG_LF & _ "whatever you specify, here." & $MSG_LF & $MSG_LF & _ "DON'T FORGET to put '-i' in front of, and ""quotes"" around any file " & $MSG_LF & _ "paths you put/drop here!" & $MSG_LF & $MSG_LF & _ "AND, that THIS section goes BEFORE the INPUT (above) in the " & $MSG_LF & _ "arguments (so -map FIRST!) " & $MSG_LF & $MSG_LF & _ "NOTE: This input accepts @tokens." GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $inp_input_params = GUICtrlCreateInput("", 5, 15, $column_two-76, 20) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) GUICtrlSetState(-1, $GUI_DROPACCEPTED) GUICtrlSetFont(-1, $console_output_font_size, 400, 0, $console_output_font, 5) $ttt = "Quick Add-A-File Button" $butt_add_file_arg_to_input_params = GUICtrlCreateButton("+", $column_two-72, 0, 20, 20, BitOr($WS_TABSTOP,$BS_FLAT,$BS_CENTER,$BS_VCENTER)) GUICtrlSetTipOptional(-1, "Clicking here adds '-i """"' to the input override and places the caret inbetween the two quotes. " & $MSG_LF & _ "Then you can drag a file directly into the input parameter override input and it's ready-to-go. " & $MSG_LF & $MSG_LF & _ "Note: The addition is always at the end, so you can easily perform this action multiple times.", $ttt) GUICtrlSetOnEvent(-1, "AddInputOverrideFileArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $ttt = "Delete" GUICtrlCreateButton(" x", 24, 0, 20, 20, BitOr($WS_TABSTOP,$BS_FLAT,$BS_CENTER,$BS_VCENTER)) GUICtrlSetTipOptional(-1, "Click here to wipe the current input override parameters. ", $ttt) GUICtrlSetOnEvent(-1, "DelInputOverrideFileArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) ; presets.. ; (aka. parameter favourites) $tip = "Select a preset from the list. The selected preset can either add to" & $MSG_LF & _ "or replace the current settings NOTE: once selected, you can use " & $MSG_LF & _ "your arrow keys to navigate this combo control. " & $MSG_LF & _ "(right-click the combo's chevron for a context menu) " GUISetCoord($column_two, 62) GUICtrlCreateLabel("", 0, 0, $column_two-12, 20, 0, 0) GUICtrlSetTipOptional(-1, $tip, $NAME_PRESETS) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) ; GUICtrlSetBkColor(-1, $COLOR_RED) GUISetCoord($column_two, 62) GUICtrlCreateLabel("", 0, 0, 10, 42, 0, 0) GUICtrlSetTipOptional(-1, $tip, $NAME_PRESETS) GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) ; GUICtrlSetBkColor(-1, $COLOR_RED) GUISetCoord($column_two, 103) GUICtrlCreateLabel("", 0, 0, $column_two-12, 8, 0, 0) GUICtrlSetTipOptional(-1, $tip, $NAME_PRESETS) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) ; GUICtrlSetBkColor(-1, $COLOR_RED) ; enable the background color commands and you will see; I am not fucking around here. $ttt = $NAME_PRESETS GUISetCoord($column_two, 62) GUICtrlCreateGroup(StringLower($NAME_PRESETS) & ".. ", 0, 0, ($width-$column_two)-10, 74) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) local $combo_styles = BitOr($CBS_DROPDOWN, $CBS_AUTOHSCROLL, $WS_VSCROLL) if $sort_presets_list = $ON then $combo_styles = BitOr($CBS_SORT, $CBS_DROPDOWN, $CBS_AUTOHSCROLL, $WS_VSCROLL) $combo_presets = GUICtrlCreateCombo("", 10, 20, ($width-$column_two)-120, default, $combo_styles) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetOnEvent(-1, "ComboLoadPreset") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) GUICtrlSetState(-1, $GUI_DROPACCEPTED+$GUI_ONTOP) UpdatePresetsCombo() local $ctxt_combo = GUICtrlCreateContextMenu($combo_presets) GUICtrlCreateMenuItem("Rename Preset", $ctxt_combo) GUICtrlSetOnEvent(-1, "MenuRenamePreset") GUICtrlCreateMenuItem("Refresh List", $ctxt_combo) GUICtrlSetOnEvent(-1, "MenuRefreshPresetsList") GUICtrlCreateMenuItem("", $ctxt_combo) GUICtrlCreateMenuItem("Export Data", $ctxt_combo) GUICtrlSetOnEvent(-1, "MenuExportData") GUICtrlCreateMenuItem("Import Data", $ctxt_combo) GUICtrlSetOnEvent(-1, "ComboMenuImportData") GUICtrlCreateMenuItem("", $ctxt_combo) GUICtrlCreateMenuItem("Wipe All Preset Backups", $ctxt_combo) GUICtrlSetOnEvent(-1, "WipeBackups") $ttt = "Save A Preset" GUICtrlCreateButton("save", ($width-$column_two)-115, 0, 42, 22, BitOr($WS_TABSTOP,$BS_FLAT), $WS_EX_TOPMOST) GUICtrlSetTipOptional(-1, "Save these settings as a preset (aka. 'favourite settings') " & $MSG_LF & _ "NOTE: when overwriting an existing preset, hold down " & $MSG_LF & _ "the key to skip the warning. ", $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) GUICtrlSetOnEvent(-1, "ButtSavePreset") $ttt = "Wipe A Preset" GUICtrlCreateButton("wipe", 46 , 0, 42, 22, BitOr($WS_TABSTOP,$BS_FLAT), $WS_EX_TOPMOST) GUICtrlSetTipOptional(-1, "Remove this preset from the list. ", $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) GUICtrlSetOnEvent(-1, "WipePreset") ; add/replace parameters options.. GUICtrlCreateLabel(StringLower($NAME_PRESETS) & "..", 70-($width-$column_two), 31, default, 18, BitOr($WS_TABSTOP,$BS_FLAT), $WS_EX_TOPMOST) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $ttt = "Replace Settings" $radio_preset_replace = GUICtrlCreateRadio("replace", 47, -2, default, 18, -1) GUICtrlSetTipOptional(-1, "The selected preset will replace all the current settings with settings from the new preset. " & $MSG_LF & _ "If your current preset specifies ' -scodec copy', and you load a preset specifying " & $MSG_LF & _ "'-metadata:s:s:0 language=eng', the extra parameters input would now contain both.", $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) GUICtrlSetOnEvent(-1, "TogglePresetMode") GUICtrlSetState(-1, $replace_mode) $ttt = "Add To Settings" GUICtrlCreateRadio("add to", 60, 0, default, 18, -1) GUICtrlSetTipOptional(-1, "The selected preset will ADD to all the current settings. " & $MSG_LF & "This applies to all the visible settings that can be" & $MSG_LF & " 'added to'; i.e. not toggles and job settings.", $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) GUICtrlSetOnEvent(-1, "TogglePresetMode") if $replace_mode = $OFF then GUICtrlSetState(-1, $ON) GUICtrlCreateLabel("..my settings.", 54, 2, default, 18, -1, $WS_EX_TOPMOST) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) ; store the input/output file paths inside the preset? $ttt = "Save/Restore File Paths" $check_store_filepaths = GUICtrlCreateCheckbox("with file paths", ($width-$column_two)-276, -1, default, 18, -1, $WS_EX_TOPMOST) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) GUICtrlSetOnEvent(-1, "ToggleStorePaths") GUICtrlSetTipOptional(-1, "Store the full path of the input and output files inside the preset " & $MSG_LF & _ "and (usually) restore those file paths along with the preset. ", $ttt) if $store_filepaths <> $GUI_INDETERMINATE then GUICtrlSetState(-1, $store_filepaths) else GUICtrlSetState(-1, $GUI_DISABLE) GUICtrlSetTipOptional(-1, "This feature is disabled inside ffe.ini.", $ttt) ; won't show - it's diabled! endif ;2do - more of this - consider hiding completely ; output options.. local $out_top = 66 local $out_left = 10 GUISetCoord(10, 137) GUICtrlCreateGroup(" output parameter override.. ", 0, 0, $width-20, 150) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) ; video codec.. $ttt = "Video Codec" $tip = "Override the output video codec here. " & $MSG_LF & "Select a preset codec from the list, " & $MSG_LF & "or enter one manually. " GUICtrlCreateLabel("video codec: ", 6, 18) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $combo_v_codec = GUICtrlCreateCombo($v_codec, -1, 16, 128, default, BitOr($CBS_SORT, $CBS_DROPDOWN, $CBS_AUTOHSCROLL, $WS_VSCROLL)) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) GUICtrlSetData(-1, $video_codecs) ;2do.. ; we are working our way slowly through the GUI, removing this nonsense! AutoItSetOption("GUICoordMode", 1) ;2do.. Need to re-organize from here, into groups, not rows! ; video bitrate.. $ttt = "Video Bitrate" $tip = "Override the output video bitrate(bits/s). " & $MSG_LF & "Select a preset, or enter manually. " GUICtrlCreateLabel("bitrate: ", $out_left+142, $out_top+90) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $combo_v_bitrate = GUICtrlCreateCombo("", $out_left+142, $out_top+106, 42, default) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) GUICtrlSetData(-1, $video_bitrates) ; video fps.. $ttt = "Video FPS" $tip = "Override the output video fps (frames per second). " & $MSG_LF & "Select a preset bitrate from the list, or enter one " & $MSG_LF & "manually. " GUICtrlCreateLabel("fps: ", $out_left+194, $out_top+90) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $combo_frames_per_second = GUICtrlCreateCombo("", $out_left+194, $out_top+106, 42, default) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) GUICtrlSetData(-1, $frames_per_second) ; cropping.. ; crop x .. $ttt = "Cropping" $tip = "Crop the video.." GUICtrlCreateLabel("crop the video.. ", $out_left+241, $out_top+90) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $inp_crop_top = GUICtrlCreateInput("", $out_left+275, $out_top+106, 33, 20, $ES_NUMBER) GUICtrlSetTipOptional(-1, "Crop the TOP of the video.", $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $inp_crop_right = GUICtrlCreateInput("", $out_left+309, $out_top+127, 33, 20, $ES_NUMBER) GUICtrlSetTipOptional(-1, "Crop the RIGHT side of the video.", $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $inp_crop_bottom = GUICtrlCreateInput("", $out_left+275, $out_top+148, 33, 20, $ES_NUMBER) GUICtrlSetTipOptional(-1, "Crop the BOTTOM of the video.", $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $inp_crop_left = GUICtrlCreateInput("", $out_left+242, $out_top+127, 33, 20, $ES_NUMBER) GUICtrlSetTipOptional(-1, "Crop the LEFT side of the video.", $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) ; video resizing.. $ttt = "Resizing" ; x .. $tip = "Rescale the video width. " GUICtrlCreateLabel("resize x: ", $out_left+350, $out_top+90) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $inp_x_size = GUICtrlCreateInput("", $out_left+350, $out_top+106, 33, 20, $ES_NUMBER) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) ; the "x" in 640x480! GUICtrlCreateLabel("x", $out_left+389, $out_top+108) GUICtrlSetResizing(-1, $GUI_DOCKALL) $ttt = "Rescaling" ; y .. $tip = "Rescale the video height. " GUICtrlCreateLabel("resize y: ", $out_left+400, $out_top+90) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $inp_y_size = GUICtrlCreateInput("", $out_left+400, $out_top+106, 33, 20, $ES_NUMBER) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) ; preset sizes.. $ttt = "Preset Sizes" $tip = ".. or you can select a named preset size from the list (if you know what they mean!) " & $MSG_LF & "Note: this will override the manual settings (above) " GUICtrlCreateLabel("preset sizes: ", $out_left+350, $out_top+132) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $combo_preset_resizes = GUICtrlCreateCombo($resize_preset, $out_left+350, $out_top+148, 64, default) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) GUICtrlSetData(-1, $preset_resizes) ; resize-crop order.. $ttt = "Resize-Crop Order" $check_resize_first = GUICtrlCreateCheckbox("resize first", $out_left+260, $out_top+169) GUICtrlSetTipOptional(-1, "Check this to resize the video BEFORE the cropping operation (it depends on how your logic goes).." & $MSG_LF & _ "The order of things affects the dimensions. You might crop THEN resize, or the reverse... ", $ttt) GUICtrlSetonEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) GUICtrlSetState($check_resize_first, $resize_first) ; audio codec.. $ttt = "Audio Codec" $tip = "Override the output audio codec here " & $MSG_LF & "Select a preset codec from the list, or " & $MSG_LF & "enter one manually. " GUICtrlCreateLabel("audio codec: ", $out_left+6, $out_top+132) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $combo_a_codec = GUICtrlCreateCombo($a_codec, $out_left+5, $out_top+148, 128, default, BitOr($CBS_SORT, $CBS_DROPDOWN, $CBS_AUTOHSCROLL, $WS_VSCROLL)) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) GUICtrlSetData(-1, $audio_codecs) ; audio bitrate $ttt = "Audio Bitrate" $tip = "Override the output audio bitrate (Hz). " & $MSG_LF & "Select a preset bitrate from the list, or " & $MSG_LF & "enter one manually. " GUICtrlCreateLabel("bitrate: ", $out_left+142, $out_top+132) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $combo_a_bitrate = GUICtrlCreateCombo("", $out_left+142, $out_top+148, 42, default) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) GUICtrlSetData(-1, $audio_bitrates) ; quick targets.. $ttt = "Quick Targets" $tip = "Allow ffmpeg to automatically set all the options for THIS file type. " & $MSG_LF & _ "You can also override individual parameters manually, so long as " & $MSG_LF & "they are compatible with the target file type. " GUICtrlCreateLabel("quick config types: ", $out_left+5, $out_top+174) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $combo_target_type = GUICtrlCreateCombo("", $out_left+6, $out_top+190, 128, default) GUICtrlSetData(-1, $target_types) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) ; extra raw parameters.. $ttt = "Extra Raw Parameters" $tip ="Feel free to add any other command-line parameters you might need right here. " & $MSG_LF & _ "The possibilities are almost infinite! Check the manual! " & $MSG_LF & $MSG_LF & _ "NOTE: This input accepts @tokens." GUICtrlCreateLabel("extra parameters.. ", $out_left+142, $out_top+174) GUICtrlSetTipOptional(-1, $tip, $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $inp_extra_args = GUICtrlCreateInput("", $out_left+141, $out_top+190, $width-168, 21) GUICtrlSetTipOptional(-1, $tip & $MSG_LF, $ttt) GUICtrlSetOnEvent(-1, "AutoCreateArgs") GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKRIGHT, $GUI_DOCKSIZE)) GUICtrlSetState(-1, $GUI_DROPACCEPTED) GUICtrlSetFont(-1, $console_output_font_size, 400, 0, $console_output_font, 5) ; reset all parameters.. $ttt = "Reset ALL Parameters" GUICtrlCreateButton("reset", $out_left+$width-65, $out_top+84, 40, 20, BitOr($WS_TABSTOP,$BS_FLAT)) GUICtrlSetTipOptional(-1, "Click this button to reset all the parameters", $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKRIGHT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) GUICtrlSetOnEvent(-1, "ClickButtWipeSettings") ; "Short Test" button.. $ttt = "Add Quick Test Parameters" $butt_quicktest = GUICtrlCreateButton("short test", $out_left+$width-85, $out_top+105, 60, 22, BitOr($WS_TABSTOP,$BS_FLAT)) GUICtrlSetTipOptional(-1, "Adds some parameters to process only the first " & $short_test_frames & " frames of video. " & $MSG_LF & _ "Feel free to edit this number! (hold SHIFT key while you click to do this first). ", $ttt) GUICtrlSetonEvent(-1, "AddShortTestParam") GUICtrlSetResizing(-1, BitOr($GUI_DOCKRIGHT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) local $ctxt_short_test = GUICtrlCreateContextMenu($butt_quicktest) GUICtrlCreateMenuItem("Edit Short Test Frames", $ctxt_short_test) GUICtrlSetOnEvent(-1, "UserEditShortTestParams") ; "Report" button.. $ttt = "Create A Media Report" $butt_mediareport = GUICtrlCreateButton("media report", $out_left+$width-105, $out_top+128, 80, 22, BitOr($WS_TABSTOP,$BS_FLAT)) GUICtrlSetTipOptional(-1, "Use ffprobe or MediaInfo to generate a media report for your input file " & $MSG_LF & "The report will appear in your console output area ", $ttt) GUICtrlSetonEvent(-1, "GenerateReport") GUICtrlSetResizing(-1, BitOr($GUI_DOCKRIGHT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) ; The Super-Nifty Custom Buttons.. CreateButtonGrid($custom_buttons_array, $grid_x, $grid_y) ; HELP! if IsArray($help_texts) then ; BIG info text for help buttons.. $lab_help_info = GUICtrlCreatelabel("", $width-115, $out_top+150, 104, 20) GUICtrlSetFont(-1, 12, 800, 0, "", 5) GUICtrlSetResizing(-1, BitOr($GUI_DOCKRIGHT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) for $h = 1 to $help_texts[0] local $help_data = StringSplit($help_texts[$h], "|") local $help_x = 134-($h*20) - (20 * (5-$help_texts[0])) $help_butts[$h] = GUICtrlCreateButton("?", $width-$help_x, $out_top+170, 18, 18, BitOr($WS_TABSTOP,$BS_FLAT)) $ttt = $help_data[1] GUICtrlSetTipOptional(-1, "Click this button to view the " & StringUpper($help_data[1]) & " help file in the console output window (below). " & $MSG_LF & _ "Shift-click to instead open the help file in your default ." & GetExtension($help_data[2]) & " file viewer ", $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKRIGHT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) GUICtrlSetOnEvent(-1, "HelpMeNow") next endif ; command-line input.. $ttt = "Dynamic Command-Line Display" GUICtrlCreateLabel("command-line input: ", 10, $out_top+228, $width-20, 20) GUICtrlSetResizing(-1, BitOr( $GUI_DOCKRIGHT, $GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) $edit_in_args = GUICtrlCreateEdit("", 10, $out_top+244, $width-20, 64, BitOr($ES_MULTILINE, $ES_READONLY)) GUICtrlSetTipOptional(-1, "This is the actual command-line that will be used. ", $ttt) GUICtrlSetResizing(-1, BitOr( $GUI_DOCKRIGHT, $GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) ; command-line output.. $ttt = "Console Output" $edit_console_output = GUICtrlCreateEdit("", 10, $out_top+314, $width-20, $height-($out_top+358), GetEditStyles()) GUICtrlSetTipOptional(-1, "You can see the output from ffmpeg here, including any errors, messages, and so on.. " & $MSG_LF & _ "Normal text editing functions apply, e.g. use Ctrl+A to select ALL text.", $ttt) GUICtrlSetResizing(-1, BitOr( $GUI_DOCKRIGHT, $GUI_DOCKTOP, $GUI_DOCKBOTTOM, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) GUICtrlSetLimit(-1, 2147483647) GUICtrlSetFont(-1, $console_output_font_size, 400, 0, $console_output_font, 5) GUICtrlSetState(-1, $GUI_DROPACCEPTED) ;search in output window.. $ttt = "Search (F3)" $butt_find = GUICtrlCreateButton("search in output", 10, $height-32, 90, 24, BitOr($WS_TABSTOP,$BS_FLAT)) GUICtrlSetTipOptional(-1, "Click this button to find text inside the output window (or use Ctrl+F / F3). ", $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKBOTTOM, $GUI_DOCKSIZE)) GUICtrlSetOnEvent(-1, "FindInOutput") ; copy output to clipboard.. $ttt = "Copy Output To Clipboard (F8)" $butt_copy2clip = GUICtrlCreateButton("copy output to clipboard", $column_two-94, $height-32, 130, 24, BitOr($WS_TABSTOP,$BS_FLAT)) GUICtrlSetTipOptional(-1, "Click this button (or hit F8) to copy the contents of the output window to the clipboard. ", $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKRIGHT, $GUI_DOCKBOTTOM, $GUI_DOCKSIZE)) GUICtrlSetOnEvent(-1, "CopyOutput") ; clear the output.. $ttt = "Clear The Output (F5)" $butt_clearout = GUICtrlCreateButton("clear", $column_two+36, $height-32, 32, 24, BitOr($WS_TABSTOP,$BS_FLAT)) GUICtrlSetTipOptional(-1, "Click this button (or hit F5) to clear the output window. ", $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKRIGHT, $GUI_DOCKBOTTOM, $GUI_DOCKSIZE)) GUICtrlSetOnEvent(-1, "ClearOutput") ; GO! $ttt = "Start The Job (F1)" $butt_doit = GUICtrlCreateButton("do it!", $width-82, $height-32, 72, 24, BitOr($WS_TABSTOP,$BS_FLAT), $WS_EX_TOPMOST) GUICtrlSetTipOptional(-1, "Click this button (or hit F1) to begin the job. ", $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKRIGHT, $GUI_DOCKBOTTOM, $GUI_DOCKSIZE)) GUICtrlSetOnEvent(-1, "DoIt") if not $ffmpeg_binary then DisableActiveInputs() ; NO! $ttt = "ABORT THE JOB! (Pause/Break)" $label_abort = GUICtrlCreateLabel("To abort a job, press 'F4'. To abort a job or batch, 'Pause/Break'. To suspend/resume, use ScrLk/ScrollLock ", 10, $height-32) GUICtrlSetTipOptional(-1, "Simply hit 'F4' on your keyboard to quit the job. ", $ttt) GUICtrlSetResizing(-1, BitOr($GUI_DOCKLEFT, $GUI_DOCKBOTTOM, $GUI_DOCKSIZE)) GUICtrlSetState(-1, $GUI_HIDE) ; all done with creating the gui .. *phew* Like I said, NEVER AGAIN! CheckSize() ; show the main gui.. if not $do_gen and $minimized = $OFF then GUISetState(@SW_SHOW, $ffeGUI) if $maximized = $ON then GUISetState(@SW_MAXIMIZE, $ffeGUI) if $minimized = $ON then UnSetHotKeys() WinSetTrans($ffeGUI, "", 255 * (100 - $user_trans) / 100) endfunc ; The Application (system, aka. "App") Menu.. ; built from the bottom, up.. ; CreateSystemMenuItem($sText, $hMenu = -1, $bIsPopup=false, $nPos=0xFFFFFFFF) ; 0xFFFFFFFF means "insert at the end" func MakeAppMenu() GUIRegisterMsg($WM_SYSCOMMAND, "CheckAppMenu") CreateSystemMenuItem("", -1, false, 0) ; so we can start checking items right away.. local $hMenu = GetSystemMenu($ffeGUI, 0) ; Transparency Sub-Menu.. $am_trans = CreateSystemMenuItem("&Transparency..", -1, true, 0) for $i = 0 to 9 $arTransItems[$i] = CreateSystemMenuItem($i * 10 & "%", $am_trans) ; we filll top-down here if $i = $user_trans / 10 then $nTPChecked = $arTransItems[$i] CheckMenuItem($am_trans, $nTPChecked, $MF_CHECKED) endif next ; Visual prefs Sub-Menu.. CreateSystemMenuItem("", -1, false, 0) local $am_visual = CreateSystemMenuItem("&Visual Preferences..", -1, true, 0) $am_always_on_top = CreateSystemMenuItem("A&lways on Top", $am_visual, false, 0) CheckMenuItem($hMenu, $am_always_on_top, $always_on_top) CreateSystemMenuItem("", $am_visual, false, 0) $am_console_wordwrap = CreateSystemMenuItem("&Wrap Console Output (Restart)", $am_visual, false, 0) CheckMenuItem($hMenu, $am_console_wordwrap, $console_wordwrap) CreateSystemMenuItem("", $am_visual, false, 0) $am_image_buttons = CreateSystemMenuItem("&Images on (some) Buttons (Restart)", $am_visual, false, 0) CheckMenuItem($hMenu, $am_image_buttons, $image_buttons) CreateSystemMenuItem("", $am_visual, false, 0) $am_do_tooltips = CreateSystemMenuItem("Show &Mouseover Help (Restart)", $am_visual, false, 0) CheckMenuItem($hMenu, $am_do_tooltips, $do_tooltips) CreateSystemMenuItem("", $am_visual, false, 0) $am_sort_presets_list = CreateSystemMenuItem("&Sort Presets List (Restart)", $am_visual, false, 0) CheckMenuItem($hMenu, $am_sort_presets_list, $sort_presets_list) ; Custom Button Column Menu.. CreateSystemMenuItem("", -1, false, 0) $am_custom_buttons_columns = CreateSystemMenuItem("Custom Button Columns..", -1, true, 0) ; we only show 1-24, but you can set higher inside ffe.ini for $i = 1 to 24 $CustomButtonMenuItems[$i] = CreateSystemMenuItem($i, $am_custom_buttons_columns) ; we fill top-down here if $i = $custom_buttons_columns then $CBMChecked = $CustomButtonMenuItems[$i] CheckMenuItem($am_custom_buttons_columns, $CBMChecked, $MF_CHECKED) endif next ; Automatic columns.. CreateSystemMenuItem("", $am_custom_buttons_columns, false, 0) $CustomButtonMenuItems[501] = CreateSystemMenuItem("Automatic", $am_custom_buttons_columns, false, 0) if $custom_buttons_columns = "auto" then $CBMChecked = $CustomButtonMenuItems[501] CheckMenuItem($am_custom_buttons_columns, $CBMChecked, $MF_CHECKED) endif ; Disable CUstom Buttons altogether.. CreateSystemMenuItem("", $am_custom_buttons_columns, false, 0) $am_custom_buttons_disable = CreateSystemMenuItem("Disable Custom Buttons", $am_custom_buttons_columns, false, 0) ; CPU Priority Sub-Menu.. CreateSystemMenuItem("", -1, false, 0) $am_cpu = CreateSystemMenuItem("ffmpeg.exe Process Priorit&y..", -1, true, 0) for $i = 0 to 5 $arCPUItems[$i] = CreateSystemMenuItem($arCPU[$i], $am_cpu) if $i = $cpu_priority then $nCPUChecked = $arCPUItems[$i] CheckMenuItem($am_cpu, $nCPUChecked, $MF_CHECKED) endif next CreateSystemMenuItem("", -1, false, 0) $am_retain_exit_settings = CreateSystemMenuItem("Retain Exit Settings (Ctrl+E)", -1, false, 0) CheckMenuItem($hMenu, $am_retain_exit_settings, $retain_exit_settings) ; Reporting types sub-menu.. CreateSystemMenuItem("", -1, false, 0) local $am_reptypes = CreateSystemMenuItem("Media Probe &Reporting Type..", -1, true, 0) local $am_ffprobe = CreateSystemMenuItem("Use ffprobe..", $am_reptypes, false, 0) AppMenuItemSetState($hMenu, $am_ffprobe, $OFF) for $i = 0 to 6 $ReportTypesMenuItems[$i] = CreateSystemMenuItem(" " & $ReportTypes[$i], $am_reptypes) if $ReportTypes[$i] = $report_format then $nRTChecked = $ReportTypesMenuItems[$i] CheckMenuItem($am_reptypes, $nRTChecked, $MF_CHECKED) endif next CreateSystemMenuItem("", $am_reptypes, false, 0) $am_use_mediainfo = CreateSystemMenuItem("Use MediaInfo", $am_reptypes, false, 0) if $use_mediainfo = $ON then SetUseMediaInfo() ; Logging sub-menu.. CreateSystemMenuItem("", -1, false, 0) local $am_logging = CreateSystemMenuItem("&Logging..", -1, true, 0) ; CreateSystemMenuItem("", $am_logging, false, 0) $am_log_append = CreateSystemMenuItem("Append &Session Log", $am_logging, false, 0) CheckMenuItem($hMenu, $am_log_append, $log_append) CreateSystemMenuItem("", $am_logging, false, 0) $am_job_log_append = CreateSystemMenuItem("&Append Job Logs", $am_logging, false, 0) CheckMenuItem($hMenu, $am_job_log_append, $job_log_append) CreateSystemMenuItem("", $am_logging, false, 0) $am_log_each_job = CreateSystemMenuItem("&Log Each Job", $am_logging, false, 0) CheckMenuItem($hMenu, $am_log_each_job, $log_each_job) ; Drop Command sub-menu.. CreateSystemMenuItem("", -1, false, 0) $am_drop_command = CreateSystemMenuItem("&Drag-And-Drop Command..", -1, true, 0) for $i = 0 to 2 if $i = 2 then CreateSystemMenuItem("", $am_drop_command, false, 1) $DropCommandMenuItems[$i] = CreateSystemMenuItem("&" & $DropCommands[$i], $am_drop_command) if $DropCommands[$i] = $drop_command then $nDCChecked = $DropCommandMenuItems[$i] CheckMenuItem($hMenu, $nDCChecked, $MF_CHECKED) endif next CreateSystemMenuItem("", -1, false, 0) $am_about = CreateSystemMenuItem("&About " & $my_name, -1, false, 0) endfunc ; next = 34 ! ; unused = 27 func MakeTray() ; wipe the tray.. for $i = 0 to 999 ; tell me a better way! no, really. TrayItemDelete($i) next ; tray menu.. TrayCreateItem("About " & $my_name) TrayItemSetOnEvent(-1, "DoAboutBox") TrayCreateItem("") local $tray_recent_files = TrayCreateMenu("Recent Files..") $tray_toggle_retain_recent_files = TrayCreateItem("Retain Recent Files (opened in system's default app)", $tray_recent_files) TrayItemSetOnEvent(-1, "TrayToggleRetainRecentFiles") TrayItemSetState(-1, $retain_recent_files) TrayCreateItem("", $tray_recent_files) if IsArray($recent_files) and $recent_files[0] then TrayCreateItem("Clear Recent Files List", $tray_recent_files) TrayItemSetOnEvent(-1, "ClearRecentFiles") TrayCreateItem("", $tray_recent_files) for $i = $recent_files[0] to 1 step -1 TrayCreateItem($recent_files[$i], $tray_recent_files) TrayItemSetOnEvent(-1, "OpenRecentFile") next else TrayCreateItem("No Recent Files Yet!", $tray_recent_files) TrayItemSetState(-1, $TRAY_DISABLE) endif TrayCreateItem("") $tray_toggle_delayed_start = TrayCreateItem("Delayed Start (Ctrl+D)") TrayItemSetOnEvent(-1, "DelayedDoIt") TrayCreateItem("") $tray_abort_batch = TrayCreateItem("Abort Batch Pause/Break") TrayItemSetOnEvent(-1, "AbortBatch") TrayItemSetState(-1, $TRAY_DISABLE) TrayCreateItem("") TrayCreateItem("Edit ffe.ini..") TrayItemSetOnEvent(-1, "EditIniFile") TrayCreateItem("") if $pre_job_commands_file and FileExists($pre_job_commands_file) then TrayCreateItem("Edit Pre-Job Commands..") TrayItemSetOnEvent(-1, "EditPreJobCommands") else TrayCreateItem("Create Pre-Job Commands..") TrayItemSetOnEvent(-1, "CreatePreJobCommands") endif if $post_job_commands_file and FileExists($post_job_commands_file) then TrayCreateItem("Edit Post-Job Commands..") TrayItemSetOnEvent(-1, "EditPostJobCommands") else TrayCreateItem("Create Post-Job Commands..") TrayItemSetOnEvent(-1, "CreatePostJobCommands") endif TrayCreateItem("") TrayCreateItem("Open Log File..") TrayItemSetOnEvent(-1, "OpenLogFile") TrayCreateItem("") TrayCreateItem("Export Data..") TrayItemSetOnEvent(-1, "TrayMenuExportData") TrayCreateItem("Import Data..") TrayItemSetOnEvent(-1, "TrayMenuImportData") TrayCreateItem("") TrayCreateItem("Locate FFmpeg Binary..") TrayItemSetOnEvent(-1, "TraySetFFMpegBinaryLocation") TrayCreateItem("") $tray_toggle_drop_window = TrayCreateItem("Show Drop Window (F9)") TrayItemSetOnEvent(-1, "MenuToggleShowDropWindow") TrayItemSetState(-1, $do_drop_window) $tray_toggle_fluid_image_menu = TrayCreateItem("Fluid Menu (follows current image)") TrayItemSetOnEvent(-1, "MenuToggleDropWindowFluidMenu") TrayItemSetState(-1, $fluid_image_menu) $tray_toggle_auto_copy_images = TrayCreateItem("Copy Dragged Images (to fixed menu)") TrayItemSetOnEvent(-1, "MenuToggleAutoCopy") TrayItemSetState(-1, $auto_copy_images) if $fluid_image_menu = $ON then TrayItemSetState(-1, $TRAY_DISABLE) $tray_choose_image_folder = TrayCreateItem("Pick Images Folder.. (for fixed menu)") TrayItemSetOnEvent(-1, "MenuChooseFixedImageLocation") if $fluid_image_menu = $ON then TrayItemSetState(-1, $TRAY_DISABLE) TrayCreateItem("") TrayCreateItem("Reset Drop Window") TrayItemSetOnEvent(-1, "MenuResetDropWindow") TrayCreateItem("") $tray_toggle_start_minimized = TrayCreateItem("Start Minimized") TrayItemSetOnEvent(-1, "MenuToggleStartMinimized") TrayItemSetState(-1, $start_minimized) if $minimized = $ON then TrayItemSetState(-1, $TRAY_DISABLE) TrayCreateItem("") TrayCreateItem("Exit (Alt+F4 or Esc)") TrayItemSetOnEvent(-1, "User_DoQuit") ; system tray event.. ; left-click to show/hide the main window. TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN, "ToggleWindow") TraySetClick(8) TraySetIcon($me_app, 0) TraySetState() TraySetToolTip("left-click to toggle the main window" & $MSG_LF & "right-click to bring up the tray menu") endfunc ; If the user has no "Open" key in this filetype, this will fail.. func OpenRecentFile() local $tray_item_full_path = TrayItemGetText(@tray_id) ShellExecute($tray_item_full_path, "", "", $SHEX_OPEN) endfunc func ClearRecentFiles() redim $recent_files[1] $recent_files[0] = "" MakeTray() endfunc ; rtmp://fms.12E5.edgecastcdn.net/0012E5/mp4:videos/8Juv1MVa-485.mp4 ; The input has changed - update the output and arguments.. func UpdateInput() $inputfile = Detokenize(GUICtrlRead($inp_inputfile)) ; only update if there was a change.. if $old_inputfile <> $inputfile then $old_inputfile = $inputfile if IsDir($inputfile) then CRT($inputfile) ; If the currently set output dir is valid, leave it there.. local $out_parent = Detokenize(GUICtrlRead($inp_outputfile)) CRT($out_parent) ; if output is a dir, use that for $out_parent, otherwise the outfile parent dir.. if not IsDir($out_parent) then $out_parent = GetParent(Detokenize(GUICtrlRead($inp_outputfile))) ; valid, use it.. if FileExists($out_parent) then GUICtrlSetData($inp_outputfile, $out_parent) else ; blank it - start again! GUICtrlSetData($inp_outputfile, "") endif endif DoArgsCreate() endfunc ; Create Arguments.. ; Create the arguments for the command-line input and MATOF extensions.. ; This wrapper function is called when controls are changed. func AutoCreateArgs() ; outputfile either single complete name or a dir ; if @GUI_CtrlId = $inp_outputfile then $outputfile = GUICtrlRead($inp_outputfile) DoArgsCreate() endfunc func DoArgsCreate($batch="null") ; during batch, this is set inside DoIt() if not $inputfile then $inputfile = GUICtrlRead($inp_inputfile) endif if not $inputfile then return local $input_params, $read_vcodec, $read_acodec, $write_outputfile ; for single files, we will put back $output, later. $outputfile = "" local $outputfileCtrlRead = DeTokenize(GUICtrlRead($inp_outputfile)) CRT($outputfileCtrlRead) $extra_args = DeTokenize(GUICtrlRead($inp_extra_args)) ; we will build this string as we go.. $matof_string = "" if GUICtrlRead($inp_input_params) then $input_params = Detokenize(GUICtrlRead($inp_input_params)) else $input_params = "" endif if GUICtrlRead($check_resize_first) = $ON then AddSizing() AddCropping() else AddCropping() AddSizing() endif ; YES! DO IT! if $overwrite = $ON then $extra_args &= " -y " $read_vcodec = GUICtrlRead($combo_v_codec) $read_acodec = GUICtrlRead($combo_a_codec) if StringInStr($read_vcodec, "disable") and $do_output = $ON then $extra_args = " -vn " & $extra_args $no_video = true if StringInStr($read_acodec, "disable") then GUICtrlSetData($combo_a_codec, $audio_codecs) $read_acodec = GUICtrlRead($combo_a_codec) endif else $no_video = false endif if StringInStr($read_acodec, "disable") then $extra_args = " -an " & $extra_args $no_audio = true else $no_audio = false endif ; this over-rides everything.. if GUICtrlRead($combo_target_type) then $extra_args &= " -target " & GUICtrlRead($combo_target_type) $matof_string &= "[" & GUICtrlRead($combo_target_type) & "]" $no_video = false endif if $read_vcodec and not StringInStr($read_vcodec, "disable") then $v_codec = " -vcodec " & $read_vcodec $matof_string &= "[" & $read_vcodec & "]" else $v_codec = "" endif if not $no_video then if GUICtrlRead($combo_v_bitrate) then $extra_args &= " -b:v " & GUICtrlRead($combo_v_bitrate) $matof_string &= "[" & GUICtrlRead($combo_v_bitrate) & "]" endif if GUICtrlRead($combo_frames_per_second) then $extra_args &= " -r " & GUICtrlRead($combo_frames_per_second) $matof_string &= "[" & GUICtrlRead($combo_frames_per_second) & "]" endif endif if not $no_audio then if $read_acodec then $a_codec = " -acodec " & $read_acodec else $a_codec = "" endif if $read_acodec then $matof_string &= "[" & $read_acodec & "]" if GUICtrlRead($combo_a_bitrate) then $extra_args &= " -ab " & GUICtrlRead($combo_a_bitrate) if not $no_video then $matof_string &= "[" & GUICtrlRead($combo_a_bitrate) & "]" endif endif if GUICtrlRead($inp_extra_args) then $matof_string &= "[" & CleanPath(GUICtrlRead($inp_extra_args)) & "]" endif ; finished adding args / MATOF strings. ; not inside a job (for display purposes only).. if $batch == "null" then $batch = $OFF ; it *will* be a batch, when it is actually run.. if IsWild($inputfile) then $batch = $ON endif ; if it's a batch, you need matof, or SOMETHING.. if $do_matof = $OFF and $batch = $ON then ToggleMatofStatus(false) ConsoleAdd("MATOF: required (batch operation)") endif ; Now we set $outputfile.. ; ffe is handling the output file path.. (not disabled) if $do_output = $ON then ; during preset load, $inp_outputfile is set to $ini_outputfile (ini preset setting) ; Or user may have set it to some other gibberish! ; BE CAREFUL with StringReplace(!). If $old_matof = "" then it would return "", hence we check first if $old_matof then $outputfileCtrlRead = StringReplace($outputfileCtrlRead, $old_matof, "") local $inputfile_basename = RemoveExtension(BaseName($inputfile)) ; Set output directory from $outputfileCtrlRead/fallback dir.. if $outputfileCtrlRead then ; Directory already specified in outputfile.. if IsDir($outputfileCtrlRead) then $output_dir = $outputfileCtrlRead else ; otherwise, we will use parent dir of specified outputfile, if it exists.. if IsDir(GetParent($outputfileCtrlRead)) then $output_dir = GetParent($outputfileCtrlRead) endif endif ; blank output_dir: perhaps a URL and no outputfile (dir) specified in ini. Use fall-back if not $output_dir then ; grab here, not LoadPreset() as dynamic @tokens may have changed.. $fallback_folder = IniRead($ini_path, $current_preset, "fallback_folder", $fallback_folder) if not $fallback_folder or ($fallback_folder = "@parent" and StringInStr($inputfile, "://")) then ;bug LFN??? $fallback_folder = @MyDocumentsDir else $fallback_folder = DeTokenize($fallback_folder) endif $output_dir = $fallback_folder endif local $fallback_path = $output_dir & "\" & $inputfile_basename & "." & $default_extension ; SINGLE FILE.. ; http://jell.yfish.us/media/Jellyfish-3-Mbps.mkv ; leave output file path as-is (user-set, single file).. if $batch = $OFF then ; $do_matof = $OFF ; set to ini setting (or last-used $outputfile) first. could be blank. $outputfile = $ini_outputfile ; user changed since ini read (manual outputfile).. if $outputfileCtrlRead <> $ini_outputfile then $outputfile = $outputfileCtrlRead if IsDir($outputfile) or not $outputfile then $outputfile = $fallback_path endif ; ffmpeg needs an extension to work out codecs; they didn't use one, so we add it.. if not StringInStr(Basename($outputfile), ".") then $outputfile &= "." & $default_extension ; BATCH RUN.. else ; if counter - increment and create new base name - nah! ; simply set to input filename + default_extension, for now (MATOF is enabled, so this will get extras added to it).. $outputfile = $fallback_path endif ; by now, $outputfile is an actual file name.. ; DO MATOF! if $do_matof = $ON and $matof_string then ; default.. local $clean_outputfile_noext = RemoveExtension($outputfile) $clean_outputfile_ext = GetExtFromCodec($read_vcodec, $inputfile) local $separator ; MATOF has a new filename.. if $matof_string then $separator = $matof_separator else $separator = "" endif ; we save the matof string, to be removed before re-checking inputs again. $old_matof = $separator & $matof_string $outputfile = $clean_outputfile_noext & $old_matof & "." & $clean_outputfile_ext endif ; ; reset this (new "base" outputfile).. ; if not $ini_outputfile then $ini_outputfile = $outputfile ; ; updates live during batch run.. GUICtrlSetData($inp_outputfile, $outputfile) $write_outputfile = """" & $outputfile & """" ; user handling output file in extra args.. else $write_outputfile = "" endif local $write_loc = $ffmpeg_binary if $generate_script then $write_loc = '"' & $ffmpeg_binary & '"' ; Create the final ffmpeg argument.. $args = $write_loc & " " & $input_params & " -i " & """" & $inputfile & """" & $v_codec & " " & $a_codec & " " & $extra_args & " " & $write_outputfile ; update the command-line input display.. GUICtrlSetData($edit_in_args, $args) endfunc ; context menu wrapper func.. func MenuRefreshPresetsList() UpdatePresetsCombo() endfunc ; update the combo box with the current presets.. func UpdatePresetsCombo() local $presets_string = "" $presets = IniReadSectionNames($ini_path) if not IsArray($presets) then return for $i = 1 to $presets[0] ; only list the first occurence of each preset (you can have backups inside the ini - only the first is used) if not StringInStr($presets_string, $presets[$i] & "|") and StringLeft($presets[$i], 10) <> "--backup--" then $presets_string &= $presets[$i] & "|" endif next ; now we just show it in the list regardless, so users can more easily see how to set defaults. ;$presets_string = StringReplace($presets_string, "ffe|", "", 1) ; remove special section.. $presets_string = StringReplace($presets_string, "custom buttons|", "") $presets_string = StringReplace($presets_string, $exit_preset & "|", "") CRT($presets_string, "|") GUICtrlSetData($combo_presets, "") GUICtrlSetData($combo_presets, $presets_string) endfunc ;"DelString", occurrence func AddInputOverrideFileArgs() local $current_data = GUICtrlRead($inp_input_params) if $current_data then $current_data &= " " GUICtrlSetData($inp_input_params, $current_data & '-i ""') ;_GUICtrlEdit_Scroll($inp_input_params, $__EDITCONSTANT_SB_SCROLLCARET) ControlFocus($ffeGUI, "", $inp_input_params) ; Better yet, once you set focus, you can use these.. ControlSend($ffeGUI, "", $inp_input_params, "{RIGHT}") ControlSend($ffeGUI, "", $inp_input_params, "{LEFT}") endfunc func DelInputOverrideFileArgs() GUICtrlSetData($inp_input_params, "") endfunc ; wrapper function func ComboLoadPreset() $inputfile = "" LoadPreset() endfunc ; load the settings from a saved preset into the GUI controls.. ; a bit brain-dead, but logical.. func LoadPreset($this_preset="", $init=false) ; Generally speaking, IF the preference is specified, we update the pref & ; GUI, otherwise we leave the preference as-is. local $param, $dep_param ; command-line preset launch.. if $this_preset then if InArray($presets, $this_preset) and not InArray($not_presets, $this_preset) then GUICtrlSetData($combo_presets, $this_preset) ; user selected from drop-down.. else $this_preset = GUICtrlRead($combo_presets) $store_filepaths = GUICtrlRead($check_store_filepaths) endif ; blank, load defaults.. if not $this_preset then $this_preset = $my_name ; Set this handy global variable.. $current_preset = $this_preset if not $init then ConsoleAdd("loading preset: " & $current_preset) ConsoleWrite(".\" & @ScriptName & "(" & @ScriptLineNumber & "): ==> " & "loading preset: " & $current_preset & $LOG_LF) ; load file paths from ini, or don't.. if $store_filepaths = $ON then ; INPUT File.. ; $inputfile not sent on command-line, use ini value.. if not $inputfile then ; this is reset during manual preset loading ; in.. $param = Detokenize(IniRead($ini_path, $current_preset, "inputfile", "")) if $param then GUICtrlSetData($inp_inputfile, $param) endif ; OUTPUT File.. $ini_outputfile = "" ; not a batch, read outputfile from ini, also handle deprecated pref, the nice way.. $param = Detokenize(IniRead($ini_path, $current_preset, "outputfile", "")) $dep_param = Detokenize(IniRead($ini_path, $current_preset, "outfile", "")) if $dep_param then $param = $dep_param IniDelete($ini_path, $current_preset, "outfile") IniWrite($ini_path, $current_preset, "outputfile", $param) endif if $param then CRT($param) $ini_outputfile = $param GUICtrlSetData($inp_outputfile, $param) endif endif local $x_param if $replace_mode = $ON then WipeSettings() else $x_param = GUICtrlRead($inp_extra_args) & " " endif $param = IniRead($ini_path, $current_preset, "input_params", "") if $param then GUICtrlSetData($inp_input_params, $param) $param = IniRead($ini_path, $current_preset, "v_codec", "") if $param then GUICtrlSetData($combo_v_codec, $param) $param = IniRead($ini_path, $current_preset, "v_bitrate", "") if $param then GUICtrlSetData($combo_v_bitrate, $param) $param = IniRead($ini_path, $current_preset, "frames_per_second", "") if $param then GUICtrlSetData($combo_frames_per_second, $param) $param = IniRead($ini_path, $current_preset, "x_size", "") if $param then GUICtrlSetData($inp_x_size, $param) $param = IniRead($ini_path, $current_preset, "y_size", "") if $param then GUICtrlSetData($inp_y_size, $param) $param = IniRead($ini_path, $current_preset, "preset_resize", "") if $param then GUICtrlSetData($combo_preset_resizes, $param) $param = IniRead($ini_path, $current_preset, "crop_top", "") if $param then GUICtrlSetData($inp_crop_top, $param) $param = IniRead($ini_path, $current_preset, "crop_left", "") if $param then GUICtrlSetData($inp_crop_left, $param) $param = IniRead($ini_path, $current_preset, "crop_right", "") if $param then GUICtrlSetData($inp_crop_right, $param) $param = IniRead($ini_path, $current_preset, "crop_bottom", "") if $param then GUICtrlSetData($inp_crop_bottom, $param) $param = IniRead($ini_path, $current_preset, "a_codec", "") if $param then GUICtrlSetData($combo_a_codec, $param) $param = IniRead($ini_path, $current_preset, "a_bitrate", "") if $param then GUICtrlSetData($combo_a_bitrate, $param) $param = IniRead($ini_path, $current_preset, "target_type", "") if $param then GUICtrlSetData($combo_target_type, $param) $param = IniRead($ini_path, $current_preset, "raw_params", "") if $param then GUICtrlSetData($inp_extra_args, $x_param & $param) ; another deprecated preference.. $param = IniReadCheckBoxValue($ini_path, $current_preset, "resize_first", "") $dep_param = IniReadCheckBoxValue($ini_path, $current_preset, "resize_order", "") if $dep_param then $param = $dep_param IniDelete($ini_path, $current_preset, "resize_order") IniWriteCheckBoxValue($ini_path, $current_preset, "resize_first", $param) endif if $param then GUICtrlSetState($check_resize_first, $param) $param = IniReadCheckBoxValue($ini_path, $current_preset, "do_output", "") if $param then $do_output = $param if $do_output = $ON then GUICtrlSetState($inp_outputfile, $GUI_ENABLE) else GUICtrlSetState($inp_outputfile, $GUI_DISABLE) endif endif ; job button functions.. (TRI-STATE) ; if ini setting is blank, IniReadCheckBoxValue() will, by design, return 2 ($GUI_INDETERMINATE) ; ideally (ffe-generated) prefs are deleted; truly "unset". $do_matof = IniReadCheckBoxValue($ini_path, $current_preset, "do_matof", $do_matof, true) GUICtrlSetState($check_do_matof, $do_matof) $overwrite = IniReadCheckBoxValue($ini_path, $current_preset, "overwrite", $overwrite, true) GUICtrlSetState($check_overwrite, $overwrite) $concatenate = IniReadCheckBoxValue($ini_path, $current_preset, "concatenate", $concatenate, true) GUICtrlSetState($check_concatenate, $concatenate) $quit_when_done = IniReadCheckBoxValue($ini_path, $current_preset, "quit_when_done", $quit_when_done, true) GUICtrlSetState($check_quit_when_done, $quit_when_done) $shutdown_when_done = IniReadCheckBoxValue($ini_path, $current_preset, "shutdown_when_done", $shutdown_when_done, true) GUICtrlSetState($check_shutdown_when_done, $shutdown_when_done) ; Read-Only Settings - don't change GUI, must be set manually inside ffe.ini.. $param = IniRead($ini_path, $current_preset, "default_extension", "") if $param then if $default_extension <> $param and not $init then ConsoleAdd('default_extension: "' & $param & '"') $default_extension = $param endif $param = IniReadCheckBoxValue($ini_path, $current_preset, "kill_ffmpeg_on_exit", "") if $param then if $param <> $kill_ffmpeg_on_exit and not $init then ConsoleAdd('kill_ffmpeg_on_exit: ' & ProcessWriteHumanCheckBoxValue($param)) $kill_ffmpeg_on_exit = $param endif GetLogLocation($current_preset) UpdateInput() ; do this after input/output is set, so 'tokens work.. ; $pre_job_commands_file and $batch_commands_timeout grabbed and Toggles performed inside Load*Commands() LoadPreCommands() LoadPostCommands() $run_post_file_command = IniReadCheckBoxValue($ini_path, $current_preset, "run_post_file_command", $run_post_file_command, true) GUICtrlSetState($check_run_post_file_command, $run_post_file_command) $post_file_command = IniRead($ini_path, $current_preset, "post_file_command", $post_file_command) $batch_commands_timeout = IniRead($ini_path, $current_preset, "batch_commands_timeout", $batch_commands_timeout) ; recnet files list in tray menu.. $retain_recent_files = IniReadCheckBoxValue($ini_path, $my_name, "retain_recent_files", $OFF) if $retain_recent_files = $ON then local $tmp_rfstring = IniRead($ini_path, $this_preset, "recent_files", "") CRT($tmp_rfstring, "|") ; shouldn't be required (Stringjoin() does it on writing) if $tmp_rfstring then $recent_files = StringSplit($tmp_rfstring, "|") MakeTray() endif endif endfunc func ButtSavePreset() local $this_preset = GUICtrlRead($combo_presets) if $this_preset = $my_name and not ce_IsPressed(10) then DialogOpen() local $replace_defaults = MsgBox($MB_YESNO+$MB_TASKMODAL, "Are you SURE?", "If you use the name " & $my_name & ", your settings will become the defaults, " & _ $MSG_LF & "and will be loaded automatically at startup. Is this what you want?", 0, $ffeGUI) DialogClose() if $replace_defaults = 7 then return endif SavePreset($this_preset) endfunc ; Save the current settings to a preset.. ; We save the setting regardless of whether or not it has a value, in case the ; old preset /does/ have a value; then we are sure to overwrite it. func SavePreset($this_preset) if not $this_preset then return ; no square brackets inside names - it will mess up "EVERYTHING". $this_preset = StringReplace($this_preset, "[", "(") $this_preset = StringReplace($this_preset, "]", ")") $this_preset = StringStripWS($this_preset, 3) $presets = IniReadSectionNames($ini_path) if InArray($presets, $this_preset) and $this_preset <> $my_name and $this_preset <> $exit_preset and not ce_IsPressed(10) then DialogOpen() local $replaceit = MsgBox(4, "Replace Preset?", "That preset exists!" & $MSG_LF & "Do you wish to replace it?", 30, $ffeGUI) DialogClose() if $replaceit = 7 then return endif ; we read these prefs directly from the GUI controls.. if GUICtrlRead($check_store_filepaths) = $ON then IniWrite($ini_path, $this_preset, "inputfile", GUICtrlRead($inp_inputfile)) ; don't save the MATOF string with the pref.. if $old_matof then $outputfile = StringReplace($outputfile, $old_matof, "") CRT($outputfile) if $outputfile then IniWrite($ini_path, $this_preset, "outputfile", $outputfile) endif SavePref($this_preset, "input_params", $inp_input_params) SavePref($this_preset, "v_codec", $combo_v_codec) SavePref($this_preset, "v_bitrate", $combo_v_bitrate) SavePref($this_preset, "frames_per_second", $combo_frames_per_second) SavePref($this_preset, "x_size", $inp_x_size) SavePref($this_preset, "y_size", $inp_y_size) SavePref($this_preset, "preset_resize", $combo_preset_resizes) SavePref($this_preset, "crop_top", $inp_crop_top) SavePref($this_preset, "crop_left", $inp_crop_left) SavePref($this_preset, "crop_right", $inp_crop_right) SavePref($this_preset, "crop_bottom", $inp_crop_bottom) SavePref($this_preset, "a_codec", $combo_a_codec) SavePref($this_preset, "a_bitrate", $combo_a_bitrate) SavePref($this_preset, "target_type", $combo_target_type) SavePref($this_preset, "raw_params", $inp_extra_args) SavePref($this_preset, "resize_first", $check_resize_first, true) SavePref($this_preset, "do_matof", $check_do_matof, true) ; inherited/set and saved... (don't use SavePref() for this, no need, also, 0 would not get saved.) IniWrite($ini_path, $this_preset, "batch_commands_timeout", $batch_commands_timeout) IniWriteCheckBoxValue($ini_path, $this_preset, "run_commands_with_shell", $run_commands_with_shell) ; job buttons.. (state and bool set on preset load) ; we don't read the GUI for these next prefs, so the controls better have set the pref itself! SavePref($this_preset, "run_pre_job_commands", $check_run_pre_job_commands, true) if $pre_job_commands_file then IniWrite($ini_path, $this_preset, "pre_job_commands_file", TokenizeString($pre_job_commands_file)) SavePref($this_preset, "run_post_job_commands", $check_run_post_job_commands, true) if $post_job_commands_file then IniWrite($ini_path, $this_preset, "post_job_commands_file", TokenizeString($post_job_commands_file)) SavePref($this_preset, "run_post_file_command", $check_run_post_file_command, true) if $post_file_command then IniWrite($ini_path, $this_preset, "post_file_command", $post_file_command) SavePref($this_preset, "overwrite", $check_overwrite, true) SavePref($this_preset, "concatenate", $check_concatenate, true) if $this_preset <> $my_name then ;2do - or show dialog with 1-time warning SavePref($this_preset, "quit_when_done", $check_quit_when_done, true) SavePref($this_preset, "shutdown_when_done", $check_shutdown_when_done, true) endif ; We don't save these, this is for reference only.. ; $default_extension ; $kill_ffmpeg_on_exit ; not read from GUI, but directly.. IniWriteCheckBoxValue($ini_path, $this_preset, "do_output", $do_output) ; keep recent files.. (do this last, in case it's large and we hit the ini character length linit before it parses out) if $retain_recent_files = $ON and $recent_files[0] then IniWrite($ini_path, $this_preset, "recent_files", StringJoin($recent_files, "|")) ; update "current preset" global variable.. $current_preset = $this_preset UpdatePresetsCombo() GUICtrlSetData($combo_presets, $this_preset) if $this_preset = $my_name then $this_preset &= " (default preset)" ConsoleAdd("saved preset " & $this_preset) endfunc func SavePref($this_preset, $pref_name_string, $ctrl_to_read, $checkbox=false) local $ctrl_val = GUICtrlRead($ctrl_to_read) if $checkbox then IniWriteCheckBoxValue($ini_path, $this_preset, $pref_name_string, $ctrl_val) ; IniWriteCheckBoxValue() handles empty entries internally (deletes them). else IniWrite($ini_path, $this_preset, $pref_name_string, $ctrl_val) if IniRead($ini_path, $this_preset, $pref_name_string, "") = "" then IniDelete($ini_path, $this_preset, $pref_name_string) endif endfunc ; delete the current preset from the ini file.. func WipePreset() local $this_preset = GUICtrlRead($combo_presets) if not $this_preset then return $presets = IniReadSectionNames($ini_path) if not InArray($presets, $this_preset) then ConsoleAdd($LOG_LF & "error wiping preset: " & $this_preset & " does not exist!") return false endif if $this_preset <> $my_name then ConsoleAdd("backup """ & $this_preset & """ to " & """--backup--" & $this_preset & '"') local $backup_preset = IniReadSection($ini_path, $this_preset) if IniDelete($ini_path, $this_preset) then ConsoleAdd("wiped preset: " & $this_preset) IniWriteSection($ini_path, "--backup--" & $this_preset, $backup_preset) else ConsoleAdd($LOG_LF & "error wiping preset: " & $this_preset) endif else DialogOpen() MsgBox(0, "Not quite!", "If you wish to reset the default settings, simple hit the reset button" & $MSG_LF & _ "and then save the (blank) settings to a preset, using the name " & $my_name & "", 0, $ffeGUI) DialogClose() endif ; reset.. $current_preset = $my_name UpdatePresetsCombo() return endfunc ; delete all the backup presets.. func WipeBackups() local $got_backups = false $presets = IniReadSectionNames($ini_path) if not IsArray($presets) then return for $i = 1 to $presets[0] ; only list the first occurence of each preset (you can have backups inside the ini - only the first is used) if StringLeft($presets[$i], 10) = "--backup--" then $got_backups = true if IniDelete($ini_path, $presets[$i]) then ConsoleAdd("wiped backup preset: " & $presets[$i]) endif next if not $got_backups then ConsoleAdd("no backups found") endfunc func MenuRenamePreset() if $current_preset = $my_name then ConsoleAdd("cannot rename the default preset!") return endif DialogOpen() local $new_preset_name = InputBox("Rename Preset.. ", "Enter a new name for the preset.. ", $current_preset , "" , 350, 130, default, default, 0, $ffeGUI) DialogClose() if $new_preset_name then if InArray($not_presets, $new_preset_name) then ConsoleAdd("cannot rename: " & $new_preset_name & "!") return endif IniRenameSection($ini_path, $current_preset, $new_preset_name) ConsoleAdd("reset: " & $current_preset & " renamed to : " & $new_preset_name ) $new_preset_name = $new_preset_name endif endfunc ; Some Tray Toggles.. func MenuToggleDropWindowFluidMenu() if $fluid_image_menu = $ON then $fluid_image_menu = $OFF else $fluid_image_menu = $ON endif IniWriteCheckBoxValue($ini_path, $my_name, "fluid_image_menu", $fluid_image_menu) TrayItemSetState($tray_toggle_fluid_image_menu, $fluid_image_menu) if $fluid_image_menu = $ON then TrayItemSetState($tray_toggle_auto_copy_images, $TRAY_DISABLE) TrayItemSetState($tray_choose_image_folder, $TRAY_DISABLE) GUICtrlSetState($ctxt_toggle_fluid_image_menu, $GUI_DISABLE) GUICtrlSetState($ctxt_toggle_auto_copy_images, $GUI_DISABLE) else TrayItemSetState($tray_toggle_auto_copy_images, $TRAY_ENABLE) TrayItemSetState($tray_choose_image_folder, $TRAY_ENABLE) GUICtrlSetState($ctxt_toggle_fluid_image_menu, $GUI_ENABLE) GUICtrlSetState($ctxt_toggle_auto_copy_images, $GUI_ENABLE) endif HideDropWindow() endfunc func TrayToggleRetainRecentFiles() if $retain_recent_files = $ON then $retain_recent_files = $OFF else $retain_recent_files = $ON endif IniWriteCheckBoxValue($ini_path, $my_name, "retain_recent_files", $retain_recent_files) TrayItemSetState($tray_toggle_retain_recent_files, $retain_recent_files) endfunc func MenuToggleAutoCopy() if $auto_copy_images = $ON then $auto_copy_images = $OFF else $auto_copy_images = $ON endif IniWriteCheckBoxValue($ini_path, $my_name, "auto_copy_images", $auto_copy_images) TrayItemSetState($tray_toggle_auto_copy_images, $auto_copy_images) HideDropWindow() endfunc func MenuToggleShowDropWindow() if $do_drop_window = $ON then CloseDropWindow() else TrayItemSetState($tray_toggle_drop_window, $ON) GUICtrlSetState($check_do_drop_window, $ON) $do_drop_window = $ON endif endfunc ; closed from drop window context menu.. func CloseDropWindow() GUICtrlSetState($check_do_drop_window, $OFF) ClickToggleDropWindow() endfunc ; User Toggles Drop Window.. func ClickToggleDropWindow() $do_drop_window = GUICtrlRead($check_do_drop_window) TrayItemSetState($tray_toggle_drop_window, $do_drop_window) IniWriteCheckBoxValue($ini_path, $my_name, "do_drop_window", $do_drop_window) if $do_drop_window = $OFF then HideDropWindow() endfunc ; read ini setting and create valid image path for DropWindow, defaulting to built-in image on failure.. func GetDropWinImage() $drop_win_image = SetRelPathToDataDir(Detokenize(IniRead($ini_path, $my_name, "drop_win_image", ""))) if not $drop_win_image or not FileExists($drop_win_image) then $drop_win_image = SetRelPathToDataDir("images\ffe.png") if not FileExists(GetParent($drop_win_image)) then DirCreate(GetParent($drop_win_image)) FileInstall(".\stuff\ffe.png", $drop_win_image, 1) endif Check4GIFmethod() endfunc func GetDropWinImageFolder() $drop_win_image_folder = SetRelPathToDataDir(Detokenize(IniRead($ini_path, $my_name, "drop_win_image_folder", "images"))) if not $drop_win_image_folder or not FileExists($drop_win_image_folder) then $drop_win_image_folder = SetRelPathToDataDir("images") if not FileExists($drop_win_image_folder) then DirCreate($drop_win_image_folder) endfunc func MenuResetDropWindow() if $dropwin_visible then HideDropWindow() IniWrite($ini_path, $my_name, "drop_win_image", "images\ffe.png") IniWrite($ini_path, $my_name, "drop_win_image_folder", "images") IniWrite($ini_path, $my_name, "drop_window_x", 0) IniWrite($ini_path, $my_name, "drop_window_y", 0) GetDropWinImage() GetDropWinImageFolder() endfunc ; Show it! ; The Funky Drop Window.. v2 func ShowDropWindow() $dropwin_visible = true ; we could start this at app start, but this keeps the numbers down.. $on_top_counter = TimerInit() ; GDIPLUS.DLL --> Vista/Win 2008 installations (gdiplus.dll location must be specified).. if StringinStr(@OSVersion, "WIN_2008") or StringinStr(@OSVersion, "VISTA") then if not $GDI_dll then ConsoleAdd($LOG_LF & "cannot create png drop window.") ConsoleAdd("location of gdiplus.dll not specified.") ConsoleAdd("vista or windows server 2008 operating system detected.") ConsoleAdd("location of the gdiplus.dll must be manually specified.") ConsoleAdd($LOG_LF & "ffe is searching for a likely candidate. please wait...") local $find_gdi = RecurseDir(@WindowsDir & "\winsxs", "gdiplus.dll") ; Find the biggest DLL.. local $dsize, $oldbig=0, $biggest_dll for $i = 1 to $find_gdi[0] $dsize = FileGetSize($find_gdi[$i]) if $dsize > $oldbig then $oldbig = $dsize $biggest_dll = $find_gdi[$i] endif next if _GDIPlus_Startup($biggest_dll) then $GDI_dll = $biggest_dll ConsoleAdd("gdiplus.dll sucessfully located and loaded. saving path to ffe.ini..") IniWrite($ini_path, $my_name, "GDI_dll", $GDI_dll) else ; nah, this won't happen.. ConsoleAdd("gdiplus.dll was found but could not be loaded.") ConsoleAdd("please look in %windows%\winsxs for one that works! (use f3!).") ConsoleAdd("then set the full location inside ffe.ini and give it a whirl!") $do_drop_window = $OFF $dropwin_visible = false return endif _GDIPlus_Shutdown() endif else $GDI_dll = "gdiplus.dll" endif if not FileExists($drop_win_image) then ConsoleAdd("ffe could not find specified drop window image: " & $drop_win_image) return ResetAndReturn() endif Check4GIFmethod() ; load user settings.. local $dw_width, $dw_height local $dw_x = IniRead($ini_path, $my_name, "drop_window_x", 1) local $dw_y = IniRead($ini_path, $my_name, "drop_window_y", 1) $drop_win_transparency = IniRead($ini_path, $my_name, "drop_win_transparency", 0) GetRealTrans() ; this will load a transparent, animated GIF.. if $gif_method then local $aGIFDimension = _GIF_GetDimension($drop_win_image) $dw_width = $aGIFDimension[0] $dw_height = $aGIFDimension[1] else _GDIPlus_Startup($GDI_dll) ; this will load ANY image type (except animated gif).. ; Using this method would involve a lot of code to load WMF/EMF files.. ;$image_handle = _GDIPlus_ImageLoadFromFile($drop_win_image) ; but this works fine.. $image_handle = _GDIPlus_BitmapCreateFromFile($drop_win_image) if not $image_handle then ConsoleAdd("could not load image file: " & $drop_win_image) return ResetAndReturn() endif $dw_width = _GDIPlus_ImageGetWidth($image_handle) $dw_height = _GDIPlus_ImageGetHeight($image_handle) endif ; check we can see this image on-screen, if not, move it.. _GetMonitors() ; get far-dimensions of multi-monitor setup.. local $far_left = $monitors_list[0][1] local $far_top = $monitors_list[0][2] local $far_right = $monitors_list[0][3] local $far_height = $monitors_list[0][4] if ($dw_x+$dw_width) < $far_left then $dw_x = $far_left ; 1 = visible pixels if ($dw_x-$dw_width) > $far_right then $dw_x = $far_right-$dw_width if ($dw_y+$dw_height) > $far_height then $dw_y = $far_height-$dw_height if ($dw_y+$dw_height) < $far_top then $dw_y = $far_top ; This is flawed (unless we use ALL monitors dimensions;2do.). If monitor 2 is smaller... but hey, it will mostly save yer butt! ; ********* NEED pop-up style here or else title bar becomes inactive for CheckMouse(GUIGetCursorInfo()) $GUI_DropWindow = GUICreate("ffe file drop", $dw_width, $dw_height, $dw_x, $dw_y, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST, $WS_EX_ACCEPTFILES)) GUISetOnEvent($GUI_EVENT_DROPPED, "GetDroppedItem") GUISetOnEvent($GUI_EVENT_PRIMARYUP, "SaveDropWinLocation") HotKeySet("{LEFT}", "PreviousDropImage") HotKeySet("{RIGHT}", "NextDropImage") $lab_main_drop = GUICtrlCreateLabel("", 0, 0, $dw_width, $dw_height, $SS_NOTIFY, $GUI_WS_EX_PARENTDRAG) GUICtrlSetTipOptional(-1, "Drag media files into here to have them inserted into ffe's file input." & $MSG_LF & _ "Right-click the Drop Window for a handy context menu." & $MSG_LF & $MSG_LF & _ "Use your Left/Right arrow keys to quickly cycle through all the" & $MSG_LF & _ "images in the current directory (and sub-directories) ." & $MSG_LF & $MSG_LF & _ "Drag images into here to use them as your Drop Window.", "The Drop Window") if $gif_method then $hGIF = _GUICtrlCreateGIF($drop_win_image, "", 0, 0, default, default, default, 0x345) _WinAPI_SetLayeredWindowAttributes($GUI_DropWindow, 0x345, $dropwin_trans_real) GUISetBkColor(0x345) ; some random color else SetTransparentBitmap($GUI_DropWindow, $image_handle, $dropwin_trans_real) endif GUICtrlSetState(-1, $GUI_DROPACCEPTED) GUICtrlSetResizing(-1, $GUI_DOCKBORDERS) _WinAPI_SetParent($GUI_DropWindow, 0) ; if it takes longer than one second, post a notice.. AdLibRegister("PostScanningNotice", 1000) CreateDropWinContextMenu() AdLibUnRegister("PostScanningNotice") ; Let's go! GUISetState(@SW_SHOW, $GUI_DropWindow) ; on launch, switch immediately back to main window.. if $minimized = $OFF and not $switching then WinActivate($ffeGUI) ; we only save the new path if it loaded okay.. if $switching then SetNewDropWinImage() $switching = false return true endfunc func ResetAndReturn() ConsoleAdd("resetting to default image") IniWrite($ini_path, $my_name, "drop_win_image", "images\ffe.png") $dropwin_visible = false _GDIPlus_Shutdown() GetDropWinImage() return false endfunc ; GDI Error Codes.. ; $GDIP_ERROK = 0 ; Method call was successful ; $GDIP_ERRGENERICERROR = 1 ; Generic method call error ; $GDIP_ERRINVALIDPARAMETER = 2 ; One of the arguments passed to the method was not valid ; $GDIP_ERROUTOFMEMORY = 3 ; The operating system is out of memory ; $GDIP_ERROBJECTBUSY = 4 ; One of the arguments in the call is already in use ; $GDIP_ERRINSUFFICIENTBUFFER = 5 ; A buffer is not large enough ; $GDIP_ERRNOTIMPLEMENTED = 6 ; The method is not implemented ; $GDIP_ERRWIN32ERROR = 7 ; The method generated a Microsoft Win32 error ; $GDIP_ERRWRONGSTATE = 8 ; The object is in an invalid state to satisfy the API call ; $GDIP_ERRABORTED = 9 ; The method was aborted ; $GDIP_ERRFILENOTFOUND = 10 ; The specified image file or metafile cannot be found ; $GDIP_ERRVALUEOVERFLOW = 11 ; The method produced a numeric overflow ; $GDIP_ERRACCESSDENIED = 12 ; A write operation is not allowed on the specified file ; $GDIP_ERRUNKNOWNIMAGEFORMAT = 13 ; The specified image file format is not known ; $GDIP_ERRFONTFAMILYNOTFOUND = 14 ; The specified font family cannot be found ; $GDIP_ERRFONTSTYLENOTFOUND = 15 ; The specified style is not available for the specified font ; $GDIP_ERRNOTTRUETYPEFONT = 16 ; The font retrieved is not a TrueType font ; $GDIP_ERRUNSUPPORTEDGDIVERSION = 17 ; The installed GDI+ version is incompatible ; $GDIP_ERRGDIPLUSNOTINITIALIZED = 18 ; The GDI+ API is not in an initialized state ; $GDIP_ERRPROPERTYNOTFOUND = 19 ; The specified property does not exist in the image ; $GDIP_ERRPROPERTYNOTSUPPORTED = 20 ; The specified property is not supported ; Of course comments don't get compiled in! ; Hide it! func HideDropWindow() ; not required, but good practice.. if not $dropwin_visible then return if $gif_method then _GIF_DeleteGIF($hGIF) else _GDIPlus_BitmapDispose($image_handle) endif _GDIPlus_Shutdown() SaveDropWinLocation() HotKeySet("{LEFT}") HotKeySet("{RIGHT}") GUIDelete($GUI_DropWindow) $dropwin_visible = false $on_top_counter = 0 ; when switching images, $do_drop_window is still true, so idle loop catches this and re-opens the Drop Window. We don't have to. return endfunc func SaveDropWinLocation() local $dw_coords = WinGetPos($GUI_DropWindow) if IsArray($dw_coords) then ; prevent saving "center" default setting when user puts window at -1 px.. if $dw_coords[0] = -1 then $dw_coords[0] = 0 if $dw_coords[1] = -1 then $dw_coords[1] = 0 IniWrite($ini_path, $my_name, "drop_window_x", $dw_coords[0]) IniWrite($ini_path, $my_name, "drop_window_y", $dw_coords[1]) endif endfunc ; create transparent image GUI.. func SetTransparentBitmap($hGUI, $image_handle, $iOpacity) local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend $hScrDC = _WinAPI_GetDC(0) $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC) $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($image_handle) $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap) $tSize = DllStructCreate($tagSIZE) $pSize = DllStructGetPtr($tSize) DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($image_handle)) DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($image_handle)) $tSource = DllStructCreate($tagPOINT) $pSource = DllStructGetPtr($tSource) $tBlend = DllStructCreate($tagBLENDFUNCTION) $pBlend = DllStructGetPtr($tBlend) DllStructSetData($tBlend, "Alpha", $iOpacity) DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA); $AC_SRC_ALPHA = 0x011 _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA) _WinAPI_ReleaseDC(0, $hScrDC) _WinAPI_SelectObject($hMemDC, $hOld) _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteDC($hMemDC) endfunc ; right-click menu of current images and some controls.. func CreateDropWinContextMenu() redim $drop_images[1][3] local $img_dir = GetParent($drop_win_image) if $fluid_image_menu = $OFF then $img_dir = $drop_win_image_folder local $ctxt_the_pic = GUICtrlCreateContextMenu($lab_main_drop) GUICtrlCreateContextMenu($lab_main_drop) GUICtrlCreateMenuItem("Refresh This Menu", $lab_main_drop) GUICtrlSetOnEvent(-1, "HideDropWindow") GUICtrlCreateMenuItem("", $lab_main_drop) GUICtrlCreateMenuItem("Open Images Folder..", $lab_main_drop) GUICtrlSetOnEvent(-1, "OpenImagesFolder") GUICtrlCreateMenuItem("", $lab_main_drop) ; menu of available images.. local $img_menu = GUICtrlCreateMenu("Images..", $ctxt_the_pic) DigToMenu($img_dir, $img_menu) GUICtrlCreateMenuItem("", $lab_main_drop) $ctxt_toggle_fluid_image_menu = GUICtrlCreateContextMenu($lab_main_drop) GUICtrlCreateMenuItem("Fluid Menu (follows current image)", $lab_main_drop) GUICtrlSetOnEvent(-1, "MenuToggleDropWindowFluidMenu") GUICtrlSetState(-1, $fluid_image_menu) GUICtrlCreateMenuItem("", $lab_main_drop) $ctxt_toggle_auto_copy_images = GUICtrlCreateContextMenu($lab_main_drop) GUICtrlCreateMenuItem("Copy Dragged Images (to fixed menu)", $lab_main_drop) GUICtrlSetOnEvent(-1, "MenuToggleAutoCopy") GUICtrlSetState(-1, $auto_copy_images) if $fluid_image_menu = $ON then GUICtrlSetState(-1, $GUI_DISABLE) $ctxt_choose_image_folder = GUICtrlCreateContextMenu($lab_main_drop) GUICtrlCreateMenuItem("Pick Images Folder.. (for fixed menu)", $lab_main_drop) GUICtrlSetOnEvent(-1, "MenuChooseFixedImageLocation") if $fluid_image_menu = $ON then GUICtrlSetState(-1, $GUI_DISABLE) GUICtrlCreateMenuItem("", $lab_main_drop) GUICtrlCreateMenuItem("Close (F9)", $lab_main_drop) GUICtrlSetOnEvent(-1, "CloseDropWindow") GUICtrlCreateMenuItem("", $lab_main_drop) GUICtrlCreateMenuItem("Exit ffe", $lab_main_drop) GUICtrlSetOnEvent(-1, "User_DoQuit") endfunc ; recursive search function to dig-and-add-items-to-context-menu-as-it-goes.. ; Damn! I love recursive functions! func DigToMenu($root_dir, $menu_id=false) if not FileExists($root_dir) then return local $item_text, $item_id, $full_item local $dir_list = ReadDir($root_dir, "", "*.*") if IsArray($dir_list) then for $i = 1 to $dir_list[0] $item_text = BaseName($dir_list[$i]) $full_item = $root_dir & "\" & $dir_list[$i] if IsDir($full_item) then local $submenu = GUICtrlCreateMenu($item_text, $menu_id) DigToMenu($full_item, $submenu) elseif IsAllowedImage($item_text) then $item_id = GUICtrlCreateMenuItem(" " & $item_text, $menu_id) ; slight indentation for files cuz you ain't gettin' sortin! GUICtrlSetOnEvent(-1, "MenuSwitchImage") local $new_index = AddImageToMenuList($drop_images, $item_id, $item_text, $full_item) if $full_item = $drop_win_image then $img_index = $new_index GUICtrlSetState($item_id, $ON) endif endif next endif endfunc ; usefully returns the index of the newly created row.. func AddImageToMenuList(ByRef $array, $id, $text, $fullpath) if not IsArray($array) then global $array[1][3] else redim $array[UBound($array)+1][3] ; Redim = SLOW! endif local $idx = UBound($array)-1 $array[$idx][0] = $id $array[$idx][1] = $text $array[$idx][2] = $fullpath return $idx endfunc ; user chose a new image frmom the context menu.. func MenuSwitchImage() if not @GUI_CtrlId then return false SwitchDropImage() endfunc ; we are scanning a LARGE directory.. func PostScanningNotice() AdLibUnRegister("PostScanningNotice") ConsoleAdd("scanning for images. please wait a moment..") endfunc ; choose a new image (hotkeys or menu).. func SwitchDropImage($updown=false) GUICtrlSetState($drop_images[$img_index][0], $OFF) HideDropWindow() $switching = true local $i if $updown <> false then $i = $img_index + $updown ; wrap around.. if $i = 0 then $i = Ubound($drop_images)-1 if $i = Ubound($drop_images) then $i = 1 else if not @GUI_CtrlId then return false for $i = 1 to Ubound($drop_images)-1 if @GUI_CtrlId = $drop_images[$i][0] then exitloop next endif $img_index = $i GUICtrlSetState($drop_images[$img_index][0], $ON) $drop_win_image = $drop_images[$i][2] Check4GIFmethod() ConsoleAdd("setting drop window image to: " & $drop_images[$i][2]) endfunc ; also used when dropping images into drop-window.. func SetNewDropWinImage() local $write_img_path = $drop_win_image if StringInStr($drop_win_image, $data_parent & "\") then $write_img_path = StringReplace($drop_win_image, $data_parent & "\", "") $write_img_path = TokenizeString($write_img_path) if $write_img_path then IniWrite($ini_path, $my_name, "drop_win_image", $write_img_path) endfunc ; we run this after loading an image (sometimes more than once!) func Check4GIFmethod() $gif_method = false if $enable_animated_gif and GetExtension($drop_win_image) = "gif" then $gif_method = true endfunc ; We prepare the string on ini-load, by adding a "," to both ends. ; Then we can check for ",ps," without matching it in, for example, "eps". ; It's quicker than creating an array, especially when used inside recursive ; functions, which it is. func IsAllowedImage($image_file) if StringInStr($allowed_image_types, "," & GetExtension($image_file) & ",") then return true return false endfunc ; on-top status on windows in Windows can "drift". This ensures it styas on top.. func SetDropWinOnTop() WinSetOnTop($GUI_DropWindow, "", $WINDOWS_ONTOP) endfunc ; Those Lovely Custom Buttons.. ; Load custom buttons.. func LoadCustomButtonData() $custom_buttons_array = IniReadSection($ini_path, $NAME_BUTTONS) if IsArray($custom_buttons_array) then if $custom_buttons_array[0][0] > 500 then $custom_buttons_array[0][0] = 500 global $custom_buttons[$custom_buttons_array[0][0]+1] global $custom_buttons_rename_menu[$custom_buttons_array[0][0]+1] global $custom_buttons_delete_menu[$custom_buttons_array[0][0]+1] global $custom_buttons_notes[$custom_buttons_array[0][0]+1] for $i = 1 to $custom_buttons_array[0][0] if StringInStr($custom_buttons_array[$i][1], "|") then local $command_array = StringSplit($custom_buttons_array[$i][1], "|") if IsArray($command_array) and $command_array[0] = 2 then $custom_buttons_array[$i][1] = $command_array[1] $custom_buttons_notes[$i] = $command_array[2] endif endif next endif endfunc ; Create a grid of buttons from an array (probably created by IniReadSection()) ; Supply the button array and the x/y coordinates (top-left origin of grid).. func CreateButtonGrid(ByRef $buttons_array, $start_x, $start_y) if not IsArray($buttons_array) then return false local $i = 1, $row_num, $bmenu $start_y += $buttons_y_shunt local $rows = int((110-$buttons_y_shunt) / ($custom_buttons_height+$button_spacing)) - 1 ; -1 cuz we start at 0 for rows for $j = 0 to $rows ; 3 rows max, to fit in GUI. if $custom_buttons_columns = "auto" then $row_num = Round((($width - 150) - $grid_x)/$custom_buttons_width)-1 else $row_num = $custom_buttons_columns-1 endif ; x/y start at 0, buttons start at 1 ($i) for $k = 0 to $row_num ; no limit here - how wide is your screen? local $cbutt_left = $start_x+(($custom_buttons_width+$button_spacing-1)*$k) local $cbutt_top = $start_y+(($custom_buttons_height+$button_spacing)*$j) local $custom_notes = "" $custom_buttons[$i] = GUICtrlCreateButton($buttons_array[$i][0], $cbutt_left, $cbutt_top, $custom_buttons_width-2, $custom_buttons_height, BitOr($WS_TABSTOP,$BS_FLAT)) GUICtrlSetonEvent(-1, "ClickCustomButton") if $custom_buttons_notes[$i] then $custom_notes = $MSG_LF & $MSG_LF & '[' & StringReplace($custom_buttons_notes[$i], '\n', $MSG_LF & " ") & ']' ; tip options:: 1 = normal balloon tip, above. 3 = center tip, under control, 7 = left-side center tip, below GUICtrlSetTipOptional(-1, $MSG_LF & $buttons_array[$i][1] & $custom_notes, " " & StringReplace($buttons_array[$i][0], "&", "") & ":", $tip_icon, $tip_style) GUICtrlSetResizing(-1, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) GUICtrlSetFont(-1, $custom_buttons_font_size) $bmenu = GUICtrlCreateContextMenu($custom_buttons[$i]) $custom_buttons_delete_menu[$i] = GUICtrlCreateMenuItem("Delete: """ & $buttons_array[$i][0] & '"', $bmenu) GUICtrlSetOnEvent(-1, "DeleteButton") $custom_buttons_rename_menu[$i] = GUICtrlCreateMenuItem("Rename: """ & $buttons_array[$i][0] & '"', $bmenu) GUICtrlSetOnEvent(-1, "RenameButton") GUICtrlCreateMenuItem("", $bmenu) GUICtrlCreateMenuItem("Import Buttons", $bmenu) GUICtrlSetOnEvent(-1, "ImportButtons") GUICtrlCreateMenuItem("Export Buttons", $bmenu) GUICtrlSetOnEvent(-1, "MenuExportButtons") if $i = $buttons_array[0][0] then exitloop 2 $i += 1 next next endfunc ; Re-Build the Custom Button Grid to show new/updated buttons and columns.. func ReCreateButtonGrid(ByRef $buttons_array, $start_x, $start_y) ; no button array exists, return immediately.. if not IsArray($buttons_array) then return false ; wipe existing buttons first.. for $i = 1 to $buttons_array[0][0] GUICtrlDelete($custom_buttons[$i]) next if $custom_buttons_columns then LoadCustomButtonData() CreateButtonGrid($buttons_array, $start_x, $start_y) endif endfunc func ClickCustomButton() DoCustomButton() endfunc ; click once to add the code, a second time to remove.. func DoCustomButton($edit_only=false, $clicked=@GUI_CtrlId) local $do_edit, $do_input_args if ce_IsPressed(10) or $edit_only then $do_edit = true if ce_IsPressed(11) then $do_input_args = true local $clicked_butt = InArray($custom_buttons, $clicked) ; returns index of match if $clicked_butt < 1 or $clicked_butt > $custom_buttons_array[0][0] then ConsoleAdd("custom button error!") return endif local $this_command = $custom_buttons_array[$clicked_butt][1] if $do_edit then local $edit_butt_name = CorzFancyInputBox("Custom Button Name.. ", "Specify a name for the custom button.. " & $MSG_LF & _ "Enter a new name to create a new button.", $custom_buttons_array[$clicked_butt][0] , "" , 350 , 117, default, default, 0, $ffeGUI) if not $edit_butt_name then return local $edit_butt_args = CorzFancyInputBox("Arguments.. ", "Enter the arguments for the " & '"' & StringReplace($edit_butt_name, "&", "") & "" & " custom button.. ", $this_command , "" , 480, 100, default, default, 0, $ffeGUI) if not $edit_butt_args then return local $edit_butt_notes = CorzFancyInputBox("notes.. ", "Optionally, enter any explanatory notes for .. " & '"' & _ StringReplace($edit_butt_name, "&", "") & '"..', $custom_buttons_notes[$clicked_butt] , "" , @DesktopWidth/2, 100, default, default, 0, $ffeGUI) if @error = 1 then if $custom_buttons_notes[$clicked_butt] then $edit_butt_notes = $custom_buttons_notes[$clicked_butt] ; they can cancel this dialog, old notes will be saved. endif local $insert = "updated custom button: " if $custom_buttons_array[$clicked_butt][0] <> $edit_butt_name then $insert = "Created NEW Button: " ; I usually avoid ternary operators, because they look like this.. ; (the expression) ? <-- question mark there colon there! -> : ConsoleAdd( ($edit_butt_notes) ? $insert & '"' & $edit_butt_name & '"' & " command: " & $edit_butt_args & " (" & $edit_butt_notes & ")" : $insert & '"' & $edit_butt_name & '"' & " command: " & $edit_butt_args) ; if we switched the order of things here, we wouldn't need this. I'll leave it "as an exercise". if $edit_butt_notes then $edit_butt_notes = "|" & $edit_butt_notes IniWrite($ini_path, $NAME_BUTTONS, $edit_butt_name, $edit_butt_args & $edit_butt_notes) $this_command = $edit_butt_args ReCreateButtonGrid($custom_buttons_array, $grid_x, $grid_y) if $edit_only then return endif if StringLeft($this_command, 1) <> " " then $this_command = " " & $this_command local $my_control = $inp_extra_args if $do_input_args then $my_control = $inp_input_params ; existing extra arguments.. local $current_params = GUICtrlRead($my_control) ; add/remove the command.. if not StringInStr($current_params, $this_command) then GUICtrlSetData($my_control, $current_params & $this_command) else GUICtrlSetData($my_control, StringReplace($current_params, $this_command, "")) endif endfunc func RenameButton() local $clicked_butt = InArray($custom_buttons_rename_menu, @GUI_CtrlId) ; returns index of match (button 1 - 15, or whatever) if $clicked_butt < 1 or $clicked_butt > $custom_buttons_array[0][0] then ConsoleAdd("custom button out of bounds!") return endif DialogOpen() local $edit_butt_name = InputBox("Custom Button Name.. ", "Specify a new name for this custom button.. ", $custom_buttons_array[$clicked_butt][0] , "" , 300, 130, default, default, 0, $ffeGUI) DialogClose() if not $edit_butt_name or $edit_butt_name == $custom_buttons_array[$clicked_butt][0] then return ; case-sensitive match - user can change case of button ok local $tmp_inival = IniRead($ini_path, $NAME_BUTTONS, $custom_buttons_array[$clicked_butt][0], "") if not $tmp_inival then return if IniDelete($ini_path, $NAME_BUTTONS, $custom_buttons_array[$clicked_butt][0]) then if IniWrite($ini_path, $NAME_BUTTONS, $edit_butt_name, $tmp_inival) then ConsoleAdd("custom button """ & $custom_buttons_array[$clicked_butt][0] & """ renamed to """ & $edit_butt_name & '"') ReCreateButtonGrid($custom_buttons_array, $grid_x, $grid_y) endif endif endfunc func DeleteButton() local $clicked_butt = InArray($custom_buttons_delete_menu, @GUI_CtrlId) if $clicked_butt < 1 or $clicked_butt > $custom_buttons_array[0][0] then ConsoleAdd("custom button out of bounds!") return endif local $check_warn = IniReadCheckBoxValue($ini_path, $my_name, "warning_seen_butt_delete", $OFF) if $check_warn = $OFF then DialogOpen() MsgBox($MB_OK, "This is your only warning!", _ "ffe isn't some namby-pamby, hold-your-hand baby-app, it's designed for WORK. " & $MSG_LF & $MSG_LF & _ "In future, when you choose to delete a custom button it will be DELETED, GONE," & $MSG_LF & _ "VANISHED; NO AUTO-BACKUP, NO SECOND CHANCE. It's away to happen now..", 60, $ffeGUI) DialogClose() IniWriteCheckBoxValue($ini_path, $my_name, "warning_seen_butt_delete", $ON) endif if IniDelete($ini_path, $NAME_BUTTONS, $custom_buttons_array[$clicked_butt][0]) then ConsoleAdd("deleted button: """ & $custom_buttons_array[$clicked_butt][0] & '"') ReCreateButtonGrid($custom_buttons_array, $grid_x, $grid_y) else ConsoleAdd("error deleting custom button: """ & $custom_buttons_array[$clicked_butt][0] & '"') endif endfunc ; delayed start.. func DelayedDoIt() if $delay_start_at then TrayItemSetState($tray_toggle_delayed_start, $OFF) $delay_start_at = false return false endif DialogOpen() local $event_mode = AutoItSetOption("GUIOnEventMode", 0) local $coord_mode = AutoItSetOption("GUICoordMode", 0) local $datetime_picker, $now_date[7] = [False, @YEAR, @mon, @mday, @hour, @min, @sec] local $msg, $tip, $ttt, $aw = 285, $ah = 190 local $GUI_Delayed = GUICreate("Delayed Start Options.. ", $aw, $ah, -1, @DesktopHeight/4, $WS_CAPTION, $WS_EX_TOPMOST, $ffeGUI) local $dummy_first_control = GUICtrlCreateDummy() GUICtrlCreateLabel("You can run the job at a later time." , 15, 15, $aw-25) GUICtrlCreateLabel("Select the required countdown delay:" , 0, 20, $aw-25) $tip = "Select the number of days to wait before starting the job " $ttt = "Days Delay" local $lab_days = GUICtrlCreateLabel("Days:", 0, 27) GUICtrlSetTipOptional(-1, $tip, $ttt) local $combo_delay_days = GUICtrlCreateCombo("", 30, -2, 42) for $i = 1 to 365 GUICtrlSetData(-1, $i) next GUICtrlSetTipOptional(-1, $tip, $ttt) $tip = "Select the number of hours to wait before starting the job " $ttt = "Hours Delay" GUICtrlCreateLabel("Hours:", 55, 2) GUICtrlSetTipOptional(-1, $tip, $ttt) local $combo_delay_hours = GUICtrlCreateCombo("", 35, -2, 42) for $i = 1 to 24 GUICtrlSetData(-1, $i) next GUICtrlSetTipOptional(-1, $tip, $ttt) $tip = "Select the number of minutes to wait before starting the job " $ttt = "Minutes Delay" GUICtrlCreateLabel("Minutes:", 50, 2) GUICtrlSetTipOptional(-1, $tip, $ttt) local $combo_delay_minutes = GUICtrlCreateCombo("", 45, -2, 42) for $i = 1 to 60 GUICtrlSetData(-1, $i) next GUICtrlSetTipOptional(-1, $tip, $ttt) GUISetCoord(15, 75) GUICtrlCreateLabel("Alternatively, pick a date/time directly:" , 0, 20, $aw-25) local $check_enable_datepick = GUICtrlCreateCheckbox("", 0, 22, 26, 26, BitOr($BS_AUTOCHECKBOX, $BS_PUSHLIKE,$BS_ICON)) if @compiled then GUICtrlSetImage(-1,$me_app, $time_icon_index, 0) else GUICtrlSetImage(-1, ".\icons\ffe-time.ico", -1, 0) endif local $picker = GUICtrlCreateDate($GUI_Delayed, 30, 1, 226, 24, $DTS_UPDOWN) GUICtrlSetFont(-1, 9.5) GUICtrlSetState(-1, $GUI_DISABLE) $ttt = "Direct Date & Time Input" GUICtrlSetTipOptional(-1, "click here to instead enable direct date & time settings ", $ttt) ; grab the handle and we can use the groovy _GUICtrlDTP_* functions (similar, but better, to using _GUICtrlDTP_Create()).. $datetime_picker = GUICtrlGetHandle($picker) _GUICtrlDTP_SetFormat($datetime_picker, "ddd yyyy MMM dd hh:mm ttt") _GUICtrlDTP_SetSystemTime($datetime_picker, $now_date) local $range_array[14] = [true, @YEAR, @MON, @MDAY, @HOUR, @MIN, @SEC] _GUICtrlDTP_SetRange ($datetime_picker, $range_array ) local $dummy_last_control = GUICtrlCreateDummy() for $i = $dummy_first_control to $dummy_last_control GUICtrlSetResizing($i, BitOr($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE)) next guiSetCoord($aw-172, $ah-28) local $GUI_Delayed_NO = GUICtrlCreateButton("Cancel", 0, 0, 75, 20, BitOr($WS_TABSTOP, $BS_FLAT)) local $GUI_Delayed_OK = GUICtrlCreateButton("Set Delay", 80, 0, 80, 20, BitOr($WS_TABSTOP, $BS_FLAT, $BS_DEFPUSHBUTTON)) ControlFocus($ffeGUI, "", $combo_delay_days) GUISetState(@SW_SHOW, $GUI_Delayed) while true sleep(10) $msg = GUIGetMsg() switch $msg case $GUI_EVENT_CLOSE, $GUI_Delayed_NO exitloop case $GUI_Delayed_OK ; not required, but makes things clear.. $delay_start_at = "" if GUICtrlRead($check_enable_datepick) = $ON then local $user_time_array = _GUICtrlDTP_GetSystemTime($datetime_picker) _GUICtrlDTP_Destroy($datetime_picker) $delay_start_at = $user_time_array[0] & "/" & $user_time_array[1] & "/" & $user_time_array[2] & " " & $user_time_array[3] & ":" & $user_time_array[4] & ":" & $user_time_array[5] else ; Countdown.. if GUICtrlRead($combo_delay_days) then $delay_start_at = _DateAdd("D", GUICtrlRead($combo_delay_days), _NowCalc()) else $delay_start_at = _NowCalc() endif if GUICtrlRead($combo_delay_hours) then $delay_start_at = _DateAdd("h", GUICtrlRead($combo_delay_hours), $delay_start_at) if GUICtrlRead($combo_delay_minutes) then $delay_start_at = _DateAdd("n", GUICtrlRead($combo_delay_minutes), $delay_start_at) endif exitloop case $check_enable_datepick local $state = $GUI_ENABLE if GUICtrlRead($check_enable_datepick) = $ON then GUICtrlSetData($GUI_Delayed_OK, "Set Time") GUICtrlSetState($picker, $GUI_ENABLE) $state = $GUI_DISABLE else GUICtrlSetData($GUI_Delayed_OK, "Set Delay") GUICtrlSetState($picker, $GUI_DISABLE) endif for $i = $lab_days to $combo_delay_minutes GUICtrlSetState($i, $state) next endswitch dim $range_array[14] = [true, @YEAR, @MON, @MDAY, @HOUR, @MIN, @SEC] _GUICtrlDTP_SetRange($datetime_picker, $range_array) wend GUIDelete($GUI_Delayed) AutoItSetOption("GUIOnEventMode", $event_mode ) AutoItSetOption("GUICoordMode", $coord_mode) DialogClose() if $delay_start_at then TrayItemSetState($tray_toggle_delayed_start, $ON) endfunc ; Import / Export.. func ComboMenuImportData() MenuImportData() endfunc func TrayMenuImportData() MenuImportData() endfunc func ImportButtons() MenuImportData($NAME_BUTTONS) endfunc func MenuImportData($dtype="") local $import_dir = IniRead($ini_path, $my_name, "import_dir", @MyDocumentsDir) local $i_type = "data" if $dtype then $i_type = $dtype local $data_inifile = FileOpenDialog("locate the " & $i_type & " file..", $import_dir, "Ini files (*.ini)|All files (*.*)", $FD_PATHMUSTEXIST, "", $ffeGUI) if not $data_inifile then return if not FileExists($data_inifile) then ConsoleAdd("import aborted") return false endif IniWrite($ini_path, $my_name, "import_dir", GetParent($data_inifile)) ImportData($data_inifile, $dtype) endfunc func ImportData($import_file, $dtype="") if not FileExists($import_file) then return false ConsoleAdd($LOG_LF & "beginning data import..") local $import_ini_sections = IniReadSectionNames($import_file) ; present dialog for importing: main settings, presets, custom buttons.. DialogOpen() local $user_choice = CorzImportExportChooser($import_ini_sections, "import", 0, $dtype) local $err = @error DialogClose() if not $user_choice then local $msg = "import aborted" if not $dtype then $dtype = "usable data" if $err then $msg &= ": no " & $dtype & " found in file" ConsoleAdd($msg) return false endif local $do_add=false, $r_type, $do_added=false local $tmp_ini = @TempDir & "\ffe-import-temp.ini" local $restart_required = false local $restart_settings = StringSplit("image_buttons,sort_presets_list,do_tooltips,console_wordwrap", ",") FileCopy($ini_path, $tmp_ini) for $i = 1 to $import_ini_sections[0] $do_add = false switch $import_ini_sections[$i] case $my_name if StringInStr($user_choice, $NAME_SETTINGS) then $do_add = true $r_type = $NAME_SETTINGS endif case $NAME_BUTTONS if StringInStr($user_choice, $NAME_BUTTONS) then $do_add = true $r_type = $NAME_BUTTONS endif case else if StringInStr($user_choice, $NAME_PRESETS) and not StringInStr($import_ini_sections[$i], "--backup--") then $do_add = true $r_type = "preset" & ": " & $import_ini_sections[$i] endif endswitch ; we have something to add from this section.. if $do_add then local $this_section = IniReadSection($import_file, $import_ini_sections[$i]) if not @error then switch $import_ini_sections[$i] ; main settings.. case $my_name DialogOpen() local $warn_main_settings = MsgBox($MB_OKCANCEL+$MB_ICONWARNING, "Overwrite MAIN Settings?!?", _ "This will COMPLETELY OVERWRITE MAIN FFE SETTINGS!!!" & $MSG_LF & _ "(but only those settings present in the imported ini file)" & $MSG_LF & $MSG_LF & _ "Are you ABSOLUTELY sure you wish to do this? ", 30, $ffeGUI) DialogClose() if $warn_main_settings = 1 then for $st = 1 to $this_section[0][0] if IniWrite($ini_path, $my_name, $this_section[$st][0], $this_section[$st][1]) then ConsoleAdd("wrote setting: " & $this_section[$st][0] & "=" & $this_section[$st][1]) ; Ahhhh.. NOW we see the beauty of matching ini pref and var names... Assign($this_section[$st][0], $this_section[$st][1], $ASSIGN_EXISTFAIL) if InArray($restart_settings, $this_section[$st][0]) then $restart_required = true $do_added = true endif next endif case $NAME_BUTTONS ; we add/overwrite individual buttons, not simply replace the section.. for $st = 1 to $this_section[0][0] if IniWrite($ini_path, $NAME_BUTTONS, $this_section[$st][0], $this_section[$st][1]) then ConsoleAdd("wrote button: " & $this_section[$st][0] & "=" & $this_section[$st][1]) $do_added = true endif next ; preset.. case else if IniWriteSection($ini_path, $import_ini_sections[$i], $this_section) then ConsoleAdd("imported " & $r_type) $do_added = true endif endswitch endif endif next if StringInStr($user_choice, $NAME_PRESETS) then UpdatePresetsCombo() if StringInStr($user_choice, $NAME_BUTTONS) then ReCreateButtonGrid($custom_buttons_array, $grid_x, $grid_y) if $do_added then local $bax_ini = GetParent($ini_path) & "\PRE-IMPORT [" & @YEAR & "-" & @MON & "-" & @MDAY & "@" & @hour & "." & @min & "] ffe.ini" if $restart_required then ConsoleAdd("init settings detected - restart to see changes") if FileMove($tmp_ini, $bax_ini) then ConsoleAdd("old ffe.ini backed up to: " & $bax_ini) endif else FileDelete($tmp_ini) endif endfunc func MenuExportData() ExportData() endfunc func TrayMenuExportData() ExportData() endfunc func MenuExportButtons() ExportData($NAME_BUTTONS) endfunc func ExportData($dtype="") $presets = IniReadSectionNames($ini_path) if not IsArray($presets) then return ConsoleAdd($LOG_LF & "beginning data export..") local $tmp_ini_path = @TempDir & "\ffe-data-export.ini" if FileExists($tmp_ini_path) then FileDelete($tmp_ini_path) ; present dialog for exporting: main settings, presets, custom buttons.. DialogOpen() local $user_choice = CorzImportExportChooser($presets, "export", 0, $dtype) DialogClose() if not $user_choice then ConsoleAdd("export aborted") return false endif local $do_add=false, $r_type, $do_added=false ; run through section-by-section.. for $i = 1 to $presets[0] $do_add = false switch $presets[$i] case $my_name if StringInStr($user_choice, $NAME_SETTINGS) then $do_add = true $r_type = $NAME_SETTINGS endif case $NAME_BUTTONS if StringInStr($user_choice, $NAME_BUTTONS) then $do_add = true $r_type = $NAME_BUTTONS endif case else if StringInStr($user_choice, $NAME_PRESETS) and not StringInStr($presets[$i], "--backup--") then $do_add = true $r_type = "preset" & ": " & $presets[$i] endif endswitch if $do_add then ; ANY additions will set this flag. $do_added = true local $this_section = IniReadSection($ini_path, $presets[$i]) if not @error then switch $presets[$i] ; main settings.. case $my_name if IniWriteSection($tmp_ini_path, $my_name, $this_section) then ConsoleAdd("exported " & $r_type) ; custom buttons.. case $NAME_BUTTONS if IniWriteSection($tmp_ini_path, $NAME_BUTTONS, $this_section) then ConsoleAdd("exported " & $r_type) ; preset.. case else if not InArray($not_presets, $presets[$i]) and StringLeft($presets[$i], 10) <> "--backup--" then if IniWriteSection($tmp_ini_path, $presets[$i], $this_section) then ConsoleAdd("exporting preset: " & $r_type) endif endswitch endif endif next if $do_added then local $export_name = "ffe-export-" if StringInStr($user_choice, $NAME_SETTINGS) then $export_name &= StringLower(StringReplace($NAME_SETTINGS, " ", "-")) & "-" if StringInStr($user_choice, $NAME_BUTTONS) then $export_name &= StringLower(StringReplace($NAME_BUTTONS, " ", "-")) & "-" if StringInStr($user_choice, $NAME_PRESETS) then $export_name &= StringLower(StringReplace($NAME_PRESETS, " ", "-")) & "-" CRT($export_name, "-") local $export_dir = IniRead($ini_path, $my_name, "export_dir", @MyDocumentsDir) DialogOpen() local $saved_file = FileSaveDialog("specify a location to save the file..", $export_dir, "Ini files (*.ini)|All files (*.*)", $FD_PROMPTOVERWRITE , $export_name & ".ini", $ffeGUI) DialogClose() if $saved_file then IniWrite($ini_path, $my_name, "export_dir", GetParent($saved_file)) local $i_type = "data" if $dtype then $i_type = $dtype if FileMove($tmp_ini_path, $saved_file, 9) then ConsoleAdd("finished exporting " & $i_type & " to: " & $saved_file) else ConsoleAdd("well, that was fun.") endif endif endfunc ; Custom inport/export user chooser.. ; returns a string containing relebant substrings, "main settings", "presets" and "custom buttons". ; e.g., if everything is selected the string is, "mainpresetsbuttons". func CorzImportExportChooser(ByRef $ini_sections_array, $mode="import", $timeout=0, $dtype="") if not IsArray($ini_sections_array) then if $mode = "import" then ConsoleAdd("no ini [sections] found to import!") else ConsoleAdd("a serious ini-based error of some unknown description occured") endif return false endif local $ie_title = "ffe " & $mode & " choices.." local $prompt = "Which data do you wish to " & $mode & "?" local $err = 0, $i_type, $no_match = false local $ie_x = IniRead($ini_path, $my_name, "import_export_chooser_x", $x + 6) local $ie_y = IniRead($ini_path, $my_name, "import_export_chooser_y", $y + 26) local $ie_w = IniRead($ini_path, $my_name, "import_export_chooser_width", 300) local $ie_h = 170 local $min_w = 300 if $ie_w < $min_w then $ie_w = $min_w local $return = false, $last_event_mode = AutoItSetOption("GUIOnEventMode", 0) local $coord = AutoItSetOption("GUICoordMode", 0) local $style = BitOr($WS_CAPTION, $WS_SYSMENU, $WS_POPUP, $WS_SIZEBOX) local $styleX = BitOr($WS_EX_CONTEXTHELP, $WS_EX_TOPMOST, $WS_EX_TOOLWINDOW) local $ie_GUI = GUICreate($ie_title, $ie_w, $ie_h, $ie_x, $ie_y, $style, $styleX, $ffeGUI) GUIsetFont(9) local $but_Cancel = GUICtrlCreateButton("Cancel", 6, $ie_h-26, 60, 22) GUICtrlSetState(-1, $GUI_ONTOP) GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKLEFT+$GUI_DOCKWIDTH) local $but_OK = GUICtrlCreateButton("OK", $ie_w-60, 0, 50, 22, $BS_DEFPUSHBUTTON) GUICtrlSetState(-1, $GUI_ONTOP) GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKWIDTH+$GUI_DOCKRIGHT) GUISetCoord(10, 7) GUICtrlCreateLabel($prompt, 0, 0, $ie_w-30) GUICtrlSetFont(-1, default, 800) GUICtrlSetResizing(-1, $GUI_DOCKALL) GUISetCoord(20, 27) local $chk_everything, $chk_main_settings, $chk_presets, $chk_custom_buttons, $got_main=false, $got_presets=false, $got_buttons=false, $t_count=0 $i_type = $NAME_SETTINGS $chk_main_settings = GUICtrlCreateCheckbox(_StringProper($i_type), 0, 0) GUICtrlSetResizing(-1, $GUI_DOCKALL) if InArray($ini_sections_array, $my_name) then $got_main = true $t_count += 1 if $dtype = $i_type then GUICtrlSetState(-1, $ON) else if $dtype = $i_type then $no_match = true GUICtrlSetState(-1, $GUI_DISABLE) endif $i_type = $NAME_PRESETS $chk_presets = GUICtrlCreateCheckbox(_StringProper($i_type), 0, 22) GUICtrlSetResizing(-1, $GUI_DOCKALL) if HasPresets($ini_sections_array) then $got_presets = true $t_count += 1 if $dtype = $i_type then GUICtrlSetState(-1, $ON) else if $dtype = $i_type then $no_match = true GUICtrlSetState(-1, $GUI_DISABLE) endif $i_type = $NAME_BUTTONS $chk_custom_buttons = GUICtrlCreateCheckbox(_StringProper($i_type), 0, 22) GUICtrlSetResizing(-1, $GUI_DOCKALL) if InArray($ini_sections_array, $i_type) then $got_buttons = true $t_count += 1 if $dtype = $i_type then GUICtrlSetState(-1, $ON) else if $dtype = $i_type then $no_match = true GUICtrlSetState(-1, $GUI_DISABLE) endif if $t_count > 1 then $chk_everything = GUICtrlCreateCheckbox("All", 120, 0) GUICtrlSetResizing(-1, $GUI_DOCKALL) endif if $no_match then ; no matching (specific) sections in specified import file.. $err = 1 ; we have a match.. else ; single type specified (from contextual control) if $dtype then ; no choosing required., return type directly. $return = $dtype else ; OK, let's CHOOSE... GUISetState(@SW_SHOW, $ie_GUI) WinMove($ie_title, "", default, default, $ie_w, $ie_h) if $timeout <> 0 then local $dialog_begin = TimerInit() local $size_array, $got_ok=false WinActivate($ie_title) while true switch GUIGetMsg() case $GUI_EVENT_RESIZED $size_array = WinGetPos($ie_title) if not IsArray($size_array) then continueloop if $size_array[2] < $min_w then WinMove($ie_title, "", default, default, $min_w, $ie_h) if $size_array[3] <> $ie_h then WinMove($ie_title, "", default, default, $min_w, $ie_h) case $GUI_EVENT_CLOSE, $but_Cancel $return = "" exitloop case $but_OK if GUICtrlRead($chk_main_settings) = $ON then $return &= $NAME_SETTINGS if GUICtrlRead($chk_presets) = $ON then $return &= $NAME_PRESETS if GUICtrlRead($chk_custom_buttons) = $ON then $return &= $NAME_BUTTONS $got_ok = true exitloop case $chk_everything if GUICtrlRead($chk_everything) = $OFF then GUICtrlSetState($chk_main_settings, $OFF) GUICtrlSetState($chk_presets, $OFF) GUICtrlSetState($chk_custom_buttons, $OFF) else if $got_main then GUICtrlSetState($chk_main_settings, $ON) if $got_presets then GUICtrlSetState($chk_presets, $ON) if $got_buttons then GUICtrlSetState($chk_custom_buttons, $ON) endif endswitch if $timeout <> 0 then if TimerDiff($dialog_begin)/1000 > $timeout then exitloop endif wend if $return or $got_ok then ; save position/size for next time.. $size_array = WinGetPos($ie_title) ; 0-1-2-3:x-y-w-h if IsArray($size_array) then if $size_array[0] then IniWrite($ini_path, $my_name, "import_export_chooser_x", $size_array[0]) if $size_array[1] then IniWrite($ini_path, $my_name, "import_export_chooser_y", $size_array[1]) if $size_array[2] then IniWrite($ini_path, $my_name, "import_export_chooser_width", $size_array[2]) endif endif endif endif AutoItSetOption("GUIOnEventMode", $last_event_mode) AutoItSetOption("GUICoordMode", $coord) GUIDelete($ie_GUI) return SetError($err, 0, $return) endfunc ; checks if a given list of ini sections contains presets (return true) or is just settings and custom buttons (return false).. func HasPresets(ByRef $ini_section_names_array) if not IsArray($ini_section_names_array) then return false for $i = 1 to $ini_section_names_array[0] if $ini_section_names_array[$i] = $my_name or $ini_section_names_array[$i] = $NAME_BUTTONS then continueloop return true next endfunc ; clear all the paramater dials and switches back to their defaults.. func ClickButtWipeSettings() WipeSettings() DoArgsCreate() endfunc func WipeSettings() GUICtrlSetData($inp_input_params, "") GUICtrlSetData($combo_v_codec, $video_codecs) GUICtrlSetData($combo_v_bitrate, $video_bitrates) GUICtrlSetData($combo_frames_per_second, $frames_per_second) GUICtrlSetData($inp_x_size, "") GUICtrlSetData($inp_y_size, "") GUICtrlSetData($inp_crop_top, "") GUICtrlSetData($inp_crop_left, "") GUICtrlSetData($inp_crop_right, "") GUICtrlSetData($inp_crop_bottom, "") GUICtrlSetData($combo_a_codec, $audio_codecs) GUICtrlSetData($combo_a_bitrate, $audio_bitrates) GUICtrlSetData($combo_target_type, $target_types) GUICtrlSetData($combo_preset_resizes, $preset_resizes) GUICtrlSetData($inp_extra_args, "") ; note GUICtrlSetSTATE! .. GUICtrlSetState($check_resize_first, $OFF) endfunc ;2do - think about whether inherited settings like job buttons should follow this wipe/add toggle. func AddShortTestParam() if ce_IsPressed(10) then UserEditShortTestParams() local $current_params = GUICtrlRead($inp_extra_args) local $this_command = " " & "-vframes " & $short_test_frames if not StringInStr($current_params, $this_command) then if not StringInStr($current_params, "vframes") then GUICtrlSetData($inp_extra_args, $current_params & $this_command) else GUICtrlSetData($inp_extra_args, StringReplace($current_params, $this_command, "")) endif endfunc func UserEditShortTestParams() DialogOpen() local $user_frames = InputBox("Short Test Frames.. ", "Specify a number of frames for the short test button.. ", $short_test_frames , "" , 350, 130, default, default, 0, $ffeGUI) DialogClose() if $user_frames then $user_frames = Number($user_frames) if $user_frames < 1 or $user_frames > 10000 then $user_frames = 300 $short_test_frames = $user_frames IniWrite($ini_path, $my_name, "short_test_frames", $short_test_frames) GUICtrlSetTipOptional($butt_quicktest , " Adds some parameters to process only the first " & $short_test_frames & " frames of video. " & $MSG_LF & _ " Feel free to edit this number! (hold SHIFT key while you click to do this first) ", "Add Quick Test Parameters") endif endfunc func HelpMeNow() local $this_helpfile, $this_command, $console_out local $clicked_butt = InArray($help_butts, @GUI_CtrlId) if $clicked_butt < 1 or $clicked_butt > 5 then SetConsoleOutput("ERROR!") return endif ; SHIFT+Click to open in viewer/editor.. (grab NOW!) local $do_open = false if ce_IsPressed(10) then $do_open = true local $my_help_entry = StringSplit($help_texts[$clicked_butt], "|") $this_helpfile = $my_help_entry[2] $this_command = $my_help_entry[3] local $err, $full_log = "" local $nfo_loc = $data_parent & "\" & $this_helpfile if $portable then $nfo_loc = @ScriptDir & "\" & $this_helpfile ; always grab fresh each run, but grab only once (ffmpeg binary assumed not to be updated in this time). if not StringInStr($got_helps, $this_helpfile) or not FileExists($nfo_loc) then ; run ffmpeg with help flags (capture stdout).. local $gethelp = Run($ffmpeg_binary & " " & $this_command, "", @SW_HIDE, $STDOUT_CHILD) while true $err = false $console_out = StdoutRead($gethelp) $err = @error if $console_out then $full_log &= $console_out if $err then exitloop Sleep(5) wend StdioClose($gethelp) ; just in case.. ProcessClose($gethelp) ; write out help text to .nfo file.. if FileExists($nfo_loc) then FileDelete($nfo_loc) local $help_file_open = FileOpen($nfo_loc, $FO_OVERWRITE+ $FO_CREATEPATH+$FO_UTF8_NOBOM) FileWrite($help_file_open, $full_log) FileClose($help_file_open) ; add this help file to "already seen" list if not StringInStr($got_helps, $this_helpfile) then $got_helps &= $this_helpfile & "|" else ; read existing help file.. $full_log = FileRead($nfo_loc) endif if $do_open then ShellExecute($nfo_loc) else SetConsoleOutput($full_log, true) endif endfunc func ShowOutputButts() GUICtrlSetState($butt_copy2clip, $GUI_SHOW) GUICtrlSetState($butt_clearout, $GUI_SHOW) GUICtrlSetState($butt_find, $GUI_ENABLE) GUICtrlSetState($butt_find, $GUI_SHOW) endfunc func HideOutputButts() GUICtrlSetState($butt_copy2clip, $GUI_HIDE) GUICtrlSetState($butt_clearout, $GUI_HIDE) GUICtrlSetState($butt_find, $GUI_HIDE) GUICtrlSetState($butt_find, $GUI_DISABLE) endfunc func EnableActiveInputs() if not $ffmpeg_binary then return GUICtrlSetState($butt_doit, $GUI_ENABLE) GUICtrlSetState($inp_inputfile, $GUI_ENABLE) GUICtrlSetState($butt_quicktest, $GUI_ENABLE) GUICtrlSetState($butt_mediareport, $GUI_ENABLE) if IsArray($help_texts) then for $i = 1 to $help_texts[0] GUICtrlSetState($help_butts[$i], $GUI_ENABLE) next endif if $do_output = $ON then GUICtrlSetState($inp_outputfile, $GUI_ENABLE) $generate_script = false endfunc func DisableActiveInputs() GUICtrlSetState($butt_doit, $GUI_DISABLE) GUICtrlSetState($inp_inputfile, $GUI_DISABLE) GUICtrlSetState($butt_quicktest, $GUI_DISABLE) GUICtrlSetState($butt_mediareport, $GUI_DISABLE) if IsArray($help_texts) then for $i = 1 to $help_texts[0] GUICtrlSetState($help_butts[$i], $GUI_DISABLE) next endif GUICtrlSetState($inp_outputfile, $GUI_DISABLE) endfunc func ReturnNow($msg="error", $retval=-1) ConsoleAdd($msg) SetHotKeys() $do_drop_window = $drop_win_state ShowOutputButts() EnableActiveInputs() WinSetTitle($ffeGUI, "", $my_title) return $retval endfunc func CopyOutput() if GUICtrlRead($edit_console_output) then ClipPut(GUICtrlRead($edit_console_output)) endfunc ;2do - logging for non-output files (i.e. image sequences) func SaveOutput($output_data) if not $output_data then return false local $log_outputfile $job_log_location = DeTokenize(IniRead($ini_path, $current_preset, "job_log_location", $job_log_location)) if not $job_log_location then $job_log_location = "@datadir\logs" CRT($job_log_location) local $use_job_log_location = $job_log_location & "\" if IsWild($user_inputfile) then $use_job_log_location &= "[BATCH]_" if IsWild($user_outputfile) then $log_outputfile = $use_job_log_location & CleanPath(RemoveExtension($outputfile)) & $matof_separator & $matof_string & ".log" else $log_outputfile = $use_job_log_location & RemoveExtension(BaseName($outputfile)) & ".log" endif local $dl_append = 10 if $job_log_append = $ON then $dl_append = 9 local $my_log_file = FileOpen($log_outputfile, $dl_append) FileWriteLine($my_log_file, $output_data) FileClose($my_log_file) endfunc func ClearOutput() SetConsoleOutput("") endfunc func OpenSourceDir() local $srcdir = GetParent($inputfile) if IsDir($srcdir) then ShellExecute($srcdir) else GuiCtrlSetColor($lab_inputfile, $COLOR_RED) AdlibRegister("EndWarning", 150) endif endfunc func EndWarning() GuiCtrlSetColor($lab_inputfile, default) endfunc ; file/folder dropped onto some input.. func GetDroppedItem() if @GUI_DRAGID = -1 then switch @GUI_DROPID case $inp_inputfile, $lab_main_drop, $hGIF if IsAllowedImage(@GUI_DRAGFILE) then $drop_win_image = @GUI_DRAGFILE if $fluid_image_menu = $OFF and $auto_copy_images = $ON then FileCopy(@GUI_DRAGFILE, $drop_win_image_folder & "\" & BaseName(@GUI_DRAGFILE)) if FileExists($drop_win_image_folder & "\" & BaseName(@GUI_DRAGFILE)) then $drop_win_image = $drop_win_image_folder & "\" & BaseName(@GUI_DRAGFILE) else ConsoleAdd("error copying image to fixed drop images directory") endif endif $switching = true Check4GIFmethod() HideDropWindow() else if StringInStr(FileGetAttrib(@GUI_DRAGFILE), "D") then GUICtrlSetData($inp_inputfile, @GUI_DRAGFILE & "\*.*") else if BaseName(@GUI_DRAGFILE) = "ffmpeg.exe" then SetFFMpegBinaryLocation(@GUI_DRAGFILE) GUICtrlSetData($inp_inputfile, StringReplace(GUICtrlRead($inp_inputfile), @GUI_DRAGFILE, "")) return else ; replace.. GUICtrlSetData($inp_inputfile, @GUI_DRAGFILE) endif endif endif UpdateInput() if $drop_command then switch $drop_command case "Go" DoIt() case "Report" if not StringInStr(FileGetAttrib(@GUI_DRAGFILE), "D") then GenerateReport() endswitch DoArgsCreate() endif case $inp_outputfile ; replace data.. GUICtrlSetData($inp_outputfile, @GUI_DRAGFILE) $ini_outputfile = @GUI_DRAGFILE DoArgsCreate() case $combo_presets ImportData(@GUI_DRAGFILE) IniWrite($ini_path, $my_name, "import_dir", GetParent(@GUI_DRAGFILE)) case $inp_input_params ; default behaviour (drop path @ caret) case $edit_console_output ; ditto endswitch else ; @GUI_DRAGID <> -1 return false endif endfunc ; browse for an input file.. func BrowseForInputFile() local $input_dir = IniRead($ini_path, $my_name, "input_dir", @MyDocumentsDir) DialogOpen() local $tmp_ipf = FileOpenDialog("locate the input file..", $input_dir, $file_types, $FD_PATHMUSTEXIST, "", $ffeGUI) DialogClose() if not $tmp_ipf then return false IniWrite($ini_path, $my_name, "input_dir", GetParent($tmp_ipf)) $inputfile = $tmp_ipf GUICtrlSetData($inp_inputfile, $inputfile) DoArgsCreate() return true endfunc ; browse for an output file.. func BrowseForOutputFile() local $save_output_dir = IniRead($ini_path, $my_name, "save_output_dir", @MyDocumentsDir) DialogOpen() local $tmp_output = FileSaveDialog("specify the output file..", $save_output_dir, $file_types, 0, "", $ffeGUI) DialogClose() if not $tmp_output then return 0 if not StringInStr($tmp_output, ".") then $tmp_output &= "." & $default_extension IniWrite($ini_path, $my_name, "save_output_dir", GetParent($tmp_output)) $outputfile = $tmp_output GUICtrlSetData($inp_outputfile, $outputfile) DoArgsCreate() return true endfunc func MenuChooseFixedImageLocation() local $choose_root = "::{450D8FBA-AD25-11D0-98A8-0800361B1103}" ; "My Documents" if $drop_win_image_folder then $choose_root = $drop_win_image_folder DialogOpen() local $user_choose_folder = FileSelectFolder("Select a new image folder (for the FIXED menu)", $choose_root, 7, $choose_root, $ffeGUI) local $err = @error DialogClose() if not $user_choose_folder then if $err then ConsoleAdd("select image folder aborted: user cancelled") else ConsoleAdd("select image folder aborted: invalid selection") endif return endif if FileExists($user_choose_folder) then $drop_win_image_folder = $user_choose_folder ConsoleAdd("fixed menu image folder set to: " & $drop_win_image_folder) IniWrite($ini_path, $my_name, "drop_win_image_folder", $drop_win_image_folder) GetDropWinImageFolder() HideDropWindow() endif endfunc ; add resizing parameters.. func AddSizing() local $resize = "" local $matof_tmp_string = "" local $x_size = GUICtrlRead($inp_x_size) local $y_size = GUICtrlRead($inp_y_size) if $x_size and $y_size then $resize = $x_size & "x" & $y_size $matof_tmp_string ="[" & $resize & "]" endif if GUICtrlRead($combo_preset_resizes) then $resize = GUICtrlRead($combo_preset_resizes) $matof_tmp_string ="[size=" & $resize & "]" endif $matof_string &= $matof_tmp_string if $resize then $extra_args &= " -s " & $resize endfunc ; add cropping parameters.. func AddCropping() local $matof_tmp_string = "[crop " if GUICtrlRead($inp_crop_top) then $extra_args &= " -croptop " & GUICtrlRead($inp_crop_top) $matof_tmp_string &= "t=" & GUICtrlRead($inp_crop_top) & ";" endif if GUICtrlRead($inp_crop_right) then $extra_args &= " -cropright " & GUICtrlRead($inp_crop_right) $matof_tmp_string &= "r=" & GUICtrlRead($inp_crop_right) & ";" endif if GUICtrlRead($inp_crop_bottom) then $extra_args &= " -cropbottom " & GUICtrlRead($inp_crop_bottom) $matof_tmp_string &= "b=" & GUICtrlRead($inp_crop_bottom) & ";" endif if GUICtrlRead($inp_crop_left) then $extra_args &= " -cropleft " & GUICtrlRead($inp_crop_left) $matof_tmp_string &= "l=" & GUICtrlRead($inp_crop_left) & ";" endif ; trim space or comma.. $matof_tmp_string = StringTrimRight($matof_tmp_string, 1) $matof_tmp_string &= "]" if $matof_tmp_string <> "[crop]" then $matof_string &= $matof_tmp_string endfunc ; check for correct extension (by codec).. func GetExtFromCodec($v_codec, $file_name="") local $this_ext if not StringInStr($extra_args, "-vn") then ; VIDEO: ; copy|a64multi|a64multi5|alias_pix|amv|apng|asv1|asv2|avrp|avui|ayuv|bmp|libxavs|cinepak|cljr|libschroedinger|dnxhd|dpx|dvvideo|ffv1|ffvhuff|flashsv|flashsv2| ; flv|gif|h261|h263|h263p|libx264|libx264rgb|libx265|huffyuv|jpeg2000|libopenjpeg|jpegls|ljpeg|mjpeg|mpeg1video|mpeg2video|mpeg4|libxvid|msmpeg4v2|msmpeg4| ; msvideo1|pam|pbm|pcx|pgm|pgmyuv|png|ppm|prores|prores_aw|prores_ks|qtrle|r10k|r210|rawvideo|roqvideo|rv10|rv20|sgi|snow|sunrast|svq1|targa|libtheora|tiff| ; utvideo|v210|v308|v408|v410|libvpx|libvpx-vp9|libwebp|wmv1|wmv2|xbm|xface|xwd|y41p|yuv4|- disable video - switch true case $v_codec = "copy" $this_ext = GetExtension($inputfile) if IsWild($this_ext) then $this_ext = $default_extension case StringInStr($v_codec, "xvid"), StringInStr($v_codec, "mjpeg") $this_ext = "avi" case StringInStr($v_codec, "mpeg4") $this_ext = "mp4" case StringInStr($v_codec, "mpeg") $this_ext = "mpg" case StringInStr($v_codec, "flv"), StringInStr($v_codec, "flash") $this_ext = "flv" case StringInStr($v_codec, "wmv"), StringInStr($v_codec, "msvideo") $this_ext = "wmv" case StringInStr($v_codec, "vp"), StringInStr($v_codec, "webp") $this_ext = "webm" case else ; mkv $this_ext = $default_extension endswitch ; video is disabled.. ; try to guess some likely types.. else local $a_codec_inp = GUICtrlRead($combo_a_codec) if $a_codec_inp = "copy" then ; already exists in "$known_files" (associative array), use the pre-determined extension.. if AAExists($known_files, $file_name) then $this_ext = AAItem($known_files, $file_name) ; unknown file - run probe and find out what audio codec is used.. else $this_ext = ProbeFileForCodec($file_name) $this_ext = GetCodecExtFromCodecName($this_ext) ; store file = audio-ext key=val pair in AA if $this_ext then AAAdd($known_files, $file_name, $this_ext) endif else $this_ext = GetCodecExtFromCodecName($a_codec_inp) endif endif return $this_ext endfunc ; Use ffprobe to grab the audio codec name.. func ProbeFileForCodec($file) if not FileExists($file) then return false ; already probed this file.. (this should have been checked before calling!) if AAExists($known_files, $file) then return AAItem($known_files, $file) if IsWild($file) then return false ; if not already in $known_files Associative Array - run probe and find out what audio codec is used.. local $probe_data, $err if FileExists($ffprobe_loc) then ; select first audio stream.. local $probe_file = Run( $ffprobe_loc & " -v error -select_streams a:0 -show_entries stream=codec_name " & ' "'& $file & '"', "", @SW_HIDE, $STDOUT_CHILD) else return false endif local $console_out while true $err = false $console_out = StdoutRead($probe_file) $err = @error if $console_out then $probe_data &= $console_out if $err then exitloop Sleep(5) wend StdioClose($probe_file) ProcessClose($probe_file) if not StringInStr($probe_data, "codec_name") then return false ; better than simply checking existence of variable $probe_data = StringSplit($probe_data, "=") ; could specify StringInStr(,,-3), but best to let StringStripWS() handle /whatever/ line-break comes - who knows how you built your ffprobe! return StringStripWS(StringMid($probe_data[2], 1, StringInStr($probe_data[2], "[")-1), 3) endfunc ; Convert codec names into usable audio file extensions.. ; AUDIO: ; copy|aac|libvo_aacenc|ac3|ac3_fixed|adpcm_adx|g722|g726|adpcm_ima_qt|adpcm_ima_wav|adpcm_ms|adpcm_swf|adpcm_yamaha|alac|libopencore_amrnb| ; libvo_amrwbenc|comfortnoise|dca|eac3|flac|g723_1|libgsm|libgsm_ms|libilbc|mp2|mp2fixed|libtwolame|libmp3lame|nellymoser|libopus|pcm_alaw| ; pcm_f32be|pcm_f32le|pcm_f64be|pcm_f64le|pcm_mulaw|pcm_s16be|pcm_s16be_planar|pcm_s16le|pcm_s16le_planar|pcm_s24be|pcm_s24daud|pcm_s24le| ; pcm_s24le_planar|pcm_s32be|pcm_s32le|pcm_s32le_planar|pcm_s8|pcm_s8_planar|pcm_u16be|pcm_u16le|pcm_u24be|pcm_u24le|pcm_u32be|pcm_u32le| ; pcm_u8|real_144|roq_dpcm|s302m|sonic|sonicls|libspeex|tta|vorbis|libvorbis|wavpack|libwavpack|wmav1|wmav2|- disable audio -" func GetCodecExtFromCodecName($codec_name) local $ext switch true case StringInStr($codec_name, "dca") $ext = "dts" case StringInStr($codec_name, "flac") $ext = "flac" case StringInStr($codec_name, "gsm") $ext = "gsm" case StringInStr($codec_name, "mp3") $ext = "mp3" case StringInStr($codec_name, "mp2") $ext = "mp2" case StringInStr($codec_name, "ac3") $ext = "ac3" case StringInStr($codec_name, "aac") $ext = "aac" case StringInStr($codec_name, "opus") $ext = "opus" case StringInStr($codec_name, "real") $ext = "ra" case StringInStr($codec_name, "tta") $ext = "tta" case StringInStr($codec_name, "vorbis") $ext = "ogg" case StringInStr($codec_name, "wma") $ext = "wma" case else $ext = "wav" endswitch return $ext endfunc ; application menu functions.. ; https://msdn.microsoft.com/en-us/library/windows/desktop/ff468865%28v=vs.85%29.aspx func GetSystemMenu($hWnd, $bRevert) local $hMenu = DllCall("user32.dll", "hwnd", "GetSystemMenu", _ "hwnd", $hWnd, _ "int", $bRevert) return $hMenu[0] endfunc func InsertMenu($hMenu, $nPosition, $nFlags, $nIDNewItem, $lpNewItem) local $nResult = DllCall("user32.dll", "int", "InsertMenu", _ "hwnd", $hMenu, _ "int", $nPosition, _ "int", $nFlags, _ "int", $nIDNewItem, _ "str", $lpNewItem) return $nResult[0] endfunc func CreatePopupMenu() local $hMenu = DllCall("user32.dll", "hwnd", "CreatePopupMenu") return $hMenu[0] endfunc ; 0xFFFFFFFF means "insert at the end" func CreateSystemMenuItem($sText, $hMenu = -1, $bIsPopup=false, $nPos=0xFFFFFFFF) if $hMenu = -1 then $hMenu = GetSystemMenu($ffeGUI, 0) local $nID = GUICtrlCreateDummy() local $nFlags = 0 if $sText = "" then $nFlags = $MF_SEPARATOR elseif $bIsPopup then $nID = CreatePopupMenu() $nFlags = $MF_POPUP endif $nFlags = BitOr($MF_BYPOSITION, $nFlags) InsertMenu($hMenu, $nPos, $nFlags, $nID, $sText) return $nID endfunc func CheckMenuItem($hMenu, $nID, $nFlags) ; so we can pass values directly from "checkboxe boolean" values.. if $nFlags = $ON then $nFlags = $MF_CHECKED ; 0x00000008 if $nFlags = $OFF then $nFlags = $MF_UNCHECKED ; 0x0 DllCall("user32.dll", "int", "CheckMenuItem", "hwnd", $hMenu, "int", $nID, "int", $nFlags) endfunc func AppMenuItemSetState($hMenu, $nID, $state=$ON) if $state = $ON then ; enabled $state = 0x0 else ; disabled (greyed) $state = 0x00000002 endif DllCall("user32.dll", "int", "EnableMenuItem", "hwnd", $hMenu, "int", $nID, "int", $state) endfunc ; An app menu item was clicked.. func CheckAppMenu($hWnd, $Msg, $wParam, $lParam) #forceref $hWnd, $Msg, $lParam local $nID = BitAnd($wParam, 0x0000FFFF) switch $nID case $arTransItems[0] to $arTransItems[9] SetTransparency($nID) case $arCPUItems[0] to $arCPUItems[5] SetffmpegCPUPririty($nID) case $ReportTypesMenuItems[0] to $ReportTypesMenuItems[6] SetFFprobeFormat($nID) case $am_use_mediainfo MenuSetUseMediaInfo() case $DropCommandMenuItems[0] to $DropCommandMenuItems[2] SetDropCommand($nID) case $am_about DoAboutBox() case $am_retain_exit_settings MenuRetainExitSettings() case $am_always_on_top MenuToggleOnTop() case $am_console_wordwrap MenuToggleWrapConsole() case $am_log_each_job MenuToggleLogEachJob() case $am_log_append ToggleLogAppend() case $am_job_log_append ToggleJobLogAppend() case $am_do_tooltips MenuToggleToolTipHelp() case $am_sort_presets_list MenuToggleSortPresets() case $am_image_buttons MenuToggleImgButts() ; we keep these down here in case they get set off when adjusting visual prefs. That's right! :/ case $CustomButtonMenuItems[0] to $CustomButtonMenuItems[501] SetCustomButtonColumns($nID) case $am_custom_buttons_disable SetCustomButtonColumns($nID) endswitch endfunc ; Non-Toggling AppMenu commands.. ; Set the window transparency.. func SetTransparency($nID) ; although you can access menu vars directly in many cases, it's smart to set a convention for these calls and always use $hMenu. local $hMenu = GetSystemMenu($ffeGUI, 0) for $i = 0 to 9 if $arTransItems[$i] = $nID then exitloop next $user_trans = 10 * $i local $trans_level = 255 * (100 - $user_trans) / 100 WinSetTrans($ffeGUI, "", $trans_level) if $nTPChecked <> $nID then CheckMenuItem($hMenu, $nTPChecked, $MF_UNCHECKED) CheckMenuItem($hMenu, $nID, $MF_CHECKED) IniWrite($ini_path, $my_name, "transparency", $user_trans) $nTPChecked = $nID ConsoleAdd("transparency: " & $user_trans & "%") endfunc ; Set ffmpeg process priority.. func SetffmpegCPUPririty($nID) local $hMenu = GetSystemMenu($ffeGUI, 0) for $i = 0 to 5 if $arCPUItems[$i] = $nID then exitloop next $cpu_priority = $i ProcessSetPriority($ffmpeg, $cpu_priority) ; only works if running if $nCPUChecked <> $nID then CheckMenuItem($hMenu, $nCPUChecked, $MF_UNCHECKED) CheckMenuItem($hMenu, $nID, $MF_CHECKED) IniWrite($ini_path, $my_name, "cpu_priority", $cpu_priority) $nCPUChecked = $nID ConsoleAdd("ffmpeg process priority: " & $cpu_priority & " (" & $arCPU[$i] & ")") endfunc ; Set the type of reporting ffprobe does.. func SetFFprobeFormat($nID) local $hMenu = GetSystemMenu($ffeGUI, 0) for $i = 0 to 6 if $ReportTypesMenuItems[$i] = $nID then exitloop next ; we access the original report types array by index (and access the menu by idx), so we can style the actual menu however we want. $report_format = $ReportTypes[$i] if $nRTChecked <> $nID then CheckMenuItem($hMenu, $nRTChecked, $MF_UNCHECKED) if $store_probe_type <> $nID then CheckMenuItem($hMenu, $store_probe_type, $MF_UNCHECKED) CheckMenuItem($hMenu, $nID, $MF_CHECKED) CheckMenuItem($hMenu, $am_use_mediainfo, $MF_UNCHECKED) IniWrite($ini_path, $my_name, "report_format", $report_format) $use_mediainfo = $OFF IniWriteCheckBoxValue($ini_path, $my_name, "use_mediainfo", $use_mediainfo) if not $nRTChecked then ConsoleAdd("ffprobe reporting: enabled") $nRTChecked = $nID ConsoleAdd("ffprobe format: " & $report_format) endfunc func MenuSetUseMediaInfo() if $use_mediainfo = $ON then $use_mediainfo = $OFF else $use_mediainfo = $ON endif ConsoleAdd("mediainfo reporting: " & ProcessWriteHumanCheckBoxValue($use_mediainfo)) IniWriteCheckBoxValue($ini_path, $my_name, "use_mediainfo", $use_mediainfo) SetUseMediaInfo() endfunc func SetUseMediaInfo() local $hMenu = GetSystemMenu($ffeGUI, 0) if not FileExists($mediainfo_location) then ConsoleAdd("MediaInfo.exe not found!") LocateMediaInfo() if not FileExists($mediainfo_location) then AppMenuItemSetState($hMenu, $am_use_mediainfo, $OFF) $use_mediainfo = $OFF IniWriteCheckBoxValue($ini_path, $my_name, "use_mediainfo", $use_mediainfo) endif endif if $use_mediainfo = $ON then CheckMenuItem($hMenu, $am_use_mediainfo, $ON) CheckMenuItem($hMenu, $nRTChecked, $MF_UNCHECKED) $store_probe_type = $nRTChecked $nRTChecked = "" else CheckMenuItem($hMenu, $am_use_mediainfo, $OFF) CheckMenuItem($hMenu, $store_probe_type, $ON) ConsoleAdd("ffprobe reporting: enabled") ConsoleAdd("ffprobe format: " & $report_format) endif endfunc func LocateMediaInfo() local $mi_lookin = GetParent($mediainfo_location) if not $mi_lookin then $mi_lookin = @ProgramFilesDir DialogOpen() local $tmp_mediainfo_location = FileOpenDialog("Please locate MediaInfo.exe..", $mediainfo_location, "MediaInfo executable (MediaInfo.exe)", $ffeGUI) DialogClose() if not $tmp_mediainfo_location or @error then ConsoleAdd("still not got a valid path for mediainfo. disabling..") return false endif if FileExists($tmp_mediainfo_location) then $mediainfo_location = $tmp_mediainfo_location endif endfunc ; Set the current drag-and-drop command.. func SetDropCommand($nID) local $hMenu = GetSystemMenu($ffeGUI, 0) for $i = 0 to 2 if $nID = $DropCommandMenuItems[$i] then exitloop ; $DropCommandMenuItems[$i] = 142, or whatever. next $drop_command = $DropCommands[$i] if $nDCChecked <> $nID then CheckMenuItem($hMenu, $nDCChecked, $MF_UNCHECKED) CheckMenuItem($hMenu, $nID, $MF_CHECKED) IniWrite($ini_path, $my_name, "drop_command", $drop_command) $nDCChecked = $nID ConsoleAdd("drag-and-drop command: " & $drop_command) endfunc ; Set the number of custom button columns (updates live).. func SetCustomButtonColumns($nID) local $hMenu = GetSystemMenu($ffeGUI, 0) for $i = 1 to 500 if $CustomButtonMenuItems[$i] = $nID then exitloop next if $i = 26 then $i = 0 if $i = 501 then $i = "auto" $custom_buttons_columns = $i if $CBMChecked <> $nID then CheckMenuItem($hMenu, $CBMChecked, $MF_UNCHECKED) CheckMenuItem($hMenu, $nID, $MF_CHECKED) IniWrite($ini_path, $my_name, "custom_buttons_columns", $custom_buttons_columns) $CBMChecked = $nID ReCreateButtonGrid($custom_buttons_array, $grid_x, $grid_y) endfunc ; AppMenu Toggles.. ; Generic AppMenu toggling function.. func ToggleAppMenuItem(ByRef $setting, $menu_item, $ini_name, $report=true) local $hMenu = GetSystemMenu($ffeGUI, 0) if $setting = $OFF then $setting = $ON CheckMenuItem($hMenu, $menu_item, $MF_CHECKED) if $report then ConsoleAdd($ini_name & ": enabled") else $setting = $OFF CheckMenuItem($hMenu, $menu_item, $MF_UNCHECKED) if $report then ConsoleAdd($ini_name & ": disabled") endif IniWriteCheckBoxValue($ini_path, $my_name, $ini_name, $setting) endfunc ; Global AppMenu items.. func MenuToggleLogEachJob() ToggleAppMenuItem($log_each_job, $am_log_each_job, "log_each_job") endfunc func ToggleLogAppend() ToggleAppMenuItem($log_append, $am_log_append, "log_append") endfunc func ToggleJobLogAppend() ToggleAppMenuItem($job_log_append, $am_job_log_append, "job_log_append") endfunc func MenuRetainExitSettings() ToggleAppMenuItem($retain_exit_settings, $am_retain_exit_settings, "retain_exit_settings") endfunc func MenuToggleImgButts() ToggleAppMenuItem($image_buttons, $am_image_buttons, "image_buttons", false) ConsoleAdd("image_buttons: " & ProcessWriteHumanCheckBoxValue($image_buttons) & " (restart to see changes)") endfunc func MenuToggleSortPresets() ToggleAppMenuItem($sort_presets_list, $am_sort_presets_list, "sort_presets_list", false) ConsoleAdd("sort_presets_list: " & ProcessWriteHumanCheckBoxValue($sort_presets_list) & " (restart to see changes)") endfunc func MenuToggleToolTipHelp() ToggleAppMenuItem($do_tooltips, $am_do_tooltips, "do_tooltips", false) ConsoleAdd("do_tooltips: " & ProcessWriteHumanCheckBoxValue($do_tooltips) & " (restart to see changes)") endfunc func MenuToggleWrapConsole() ToggleAppMenuItem($console_wordwrap, $am_console_wordwrap, "console_wordwrap", false) ConsoleAdd("console_wordwrap: " & ProcessWriteHumanCheckBoxValue($console_wordwrap) & " (restart to see changes)") endfunc func MenuToggleOnTop() ToggleAppMenuItem($always_on_top, $am_always_on_top, "on_top") SetOnTop() endfunc func SetOnTop() if $always_on_top = $ON then WinSetOnTop($ffeGUI, "", 1) else WinSetOnTop($ffeGUI, "", 0) endif endfunc ; Other Global Toggles.. ; Toggle Main Window... func ToggleWindow() if $minimized = $OFF then UnSetHotKeys() GUISetState(@SW_HIDE, $ffeGUI) $minimized = $ON if $do_drop_window = $ON then GUISetState(@SW_SHOW, $GUI_DropWindow) else GUISetState(@SW_SHOW, $ffeGUI) TrayItemSetState($tray_toggle_start_minimized, $TRAY_ENABLE) SetHotKeys() $minimized = $OFF endif IniWriteCheckBoxValue($ini_path, $my_name, "minimized", $minimized) endfunc func MenuToggleStartMinimized() if $start_minimized = $ON then $start_minimized = $OFF else $start_minimized = $ON endif IniWriteCheckBoxValue($ini_path, $my_name, "start_minimized", $start_minimized) TrayItemSetState($tray_toggle_start_minimized, $start_minimized) endfunc func ToggleMaximizeWindow() if $maximized = $ON then GUISetState(@SW_RESTORE, $ffeGUI) $maximized = $OFF else GUISetState(@SW_MAXIMIZE, $ffeGUI) $maximized = $ON endif IniWriteCheckBoxValue($ini_path, $my_name, "maximized", $maximized) endfunc ; replace/add parameters from presets.. func TogglePresetMode() $replace_mode = GUICtrlRead($radio_preset_replace) IniWriteCheckBoxValue($ini_path, $my_name, "replace_mode", $replace_mode) endfunc func ToggleStorePaths() $store_filepaths = GUICtrlRead($check_store_filepaths) endfunc ; preset-level toggles.. ; ffe job button toggles.. func ClickSetPreJobCommands() $run_pre_job_commands = GUICtrlRead($check_run_pre_job_commands) ConsoleAdd("pre-job commands: " & ProcessWriteHumanCheckBoxValue($run_pre_job_commands)) endfunc func ClickSetPostJobCommands() $run_post_job_commands = GUICtrlRead($check_run_post_job_commands) ConsoleAdd("post-job commands: " & ProcessWriteHumanCheckBoxValue($run_post_job_commands)) endfunc func ClickSetPostFileCommand() $run_post_file_command = GUICtrlRead($check_run_post_file_command) ConsoleAdd("run post-file command: " & ProcessWriteHumanCheckBoxValue($run_post_file_command)) if $run_post_file_command = $ON then ConsoleAdd("post-file command: " & TokenizeString($post_file_command)) endfunc func ClickSetOverwrite() $overwrite = GUICtrlRead($check_overwrite) ConsoleAdd("overwrite: " & ProcessWriteHumanCheckBoxValue($overwrite)) AutoCreateArgs() endfunc func ClickSetConcatenateFiles() $concatenate = GUICtrlRead($check_concatenate) ConsoleAdd("concatenate: " & ProcessWriteHumanCheckBoxValue($concatenate)) endfunc func ClickSetQuitWhenDone() $quit_when_done = GUICtrlRead($check_quit_when_done) ConsoleAdd("quit_when_done: " & ProcessWriteHumanCheckBoxValue($quit_when_done)) endfunc func ClickSetShutdownWhenDone() $shutdown_when_done = GUICtrlRead($check_shutdown_when_done) ShutDownOverrideQuit() ConsoleAdd("shutdown_when_done: " & ProcessWriteHumanCheckBoxValue($shutdown_when_done)) endfunc ; Other preset-level toggles.. ; enable/disable output (for image sequences, etc.).. func ToggleOutput() if $do_output = $ON then $do_output = $OFF GUICtrlSetState($inp_outputfile, $GUI_DISABLE) ConsoleAdd("output: disabled") else $do_output = $ON GUICtrlSetState($inp_outputfile, $GUI_ENABLE) ConsoleAdd("output: enabled") endif endfunc func ClickToggleMatofStatus() ToggleMatofStatus() endfunc ; Toggle MATOF.. ; this can be set inside DoArgsCreate, hence the loop-preventing flag. func ToggleMatofStatus($new_args=true) if $do_matof = $ON then $do_matof = $OFF else $do_matof = $ON endif ; in case called from inside batch (not clicked) GUICtrlSetState($check_do_matof, $do_matof) if $ini_outputfile then GUICtrlSetData($inp_outputfile, $ini_outputfile) else GUICtrlSetData($inp_outputfile, Detokenize(GUICtrlRead($inp_inputfile))) endif if $new_args then DoArgsCreate() endfunc ; Toggling Shutdown on exit greys/ungreys Quit on exit func ShutDownOverrideQuit() if $shutdown_when_done = $ON then GuiCtrlSetState($check_quit_when_done, $ON) GuiCtrlSetState($check_quit_when_done, $GUI_DISABLE) else GuiCtrlSetState($check_quit_when_done, $quit_when_done) GuiCtrlSetState($check_quit_when_done, $GUI_ENABLE) endif endfunc ; Auxiliary Functions.. ; Check if mouse is over certain controls and act accordingly.. ; Returns the ID the mouse is currently over, if required. func CheckMouse() local $mouse_pos = GUIGetCursorInfo($ffeGUI) if not IsArray($mouse_pos) then return false if IsArray($help_texts) then if $previous_pos <> $mouse_pos[4] then if IsArray($help_butts) then if IsArray($mouse_pos) then local $help_hover = InArray($help_butts, $mouse_pos[4]) if $help_hover then GUICtrlSetData($lab_help_info, _StringProper(StringLeft($help_texts[$help_hover], StringInStr($help_texts[$help_hover], "|") - 1))) else GUICtrlSetData($lab_help_info, "") endif $previous_pos = $mouse_pos[4] endif endif endif endif ; Button text changes.. ; We set a $shifted flag to prevent updating the buttons every 1/100th second when nothing is happening select case ce_IsPressed(10) $shifted = true ; "Do It!" becomes script output.. GUICtrlSetData($butt_doit, "script output") ; set the number of frames (saved to ini) GUICtrlSetData($butt_quicktest, "set frames") ; custom buttons - let the user know these can be edited.. for $i = 1 to $custom_buttons_array[0][0] GUICtrlSetFont($custom_buttons[$i], $custom_buttons_font_size-2) GUICtrlSetData($custom_buttons[$i], "Edit " & $custom_buttons_array[$i][0]) next case $shifted GUICtrlSetData($butt_doit, "do it!") GUICtrlSetData($butt_quicktest, "short test") for $i = 1 to $custom_buttons_array[0][0] GUICtrlSetFont($custom_buttons[$i], $custom_buttons_font_size) GUICtrlSetData($custom_buttons[$i], $custom_buttons_array[$i][0]) next $shifted = false endselect ; check if mouse hovering over drop window.. local $drop_mouse_pos = GUIGetCursorInfo($GUI_DropWindow) if IsArray($drop_mouse_pos) and $drop_mouse_pos[4] then return SetExtended($drop_mouse_pos[4], $mouse_pos[4]) endif return $mouse_pos[4] endfunc ; focus detected on $inp_outputfile.. func CheckFocus($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg local $iFlag = BitShift($wParam, 16) switch $lParam case GUICtrlGetHandle($inp_outputfile) switch $iFlag case $EN_SETFOCUS FocusTo_inp_output() endswitch endswitch endfunc func FocusTo_inp_output() if $do_matof = $ON then ConsoleAdd("MATOF: disabled.") ToggleMatofStatus() endif endfunc ; Special "Running" HotKeys.. ; in case the user needs to respond to an ffmpeg prompt.. ; these send the keys to StdIn, which ffmpeg intercepts. func HK_FFmpegResponseYes() if WinActive($ffeGUI) then StdinWrite($ffmpeg, "y" & $LOG_LF) WinSetTitle($ffeGUI, "", $title_msg_string) else HotKeySet("y") Send("y") HotKeySet("y", "HK_FFmpegResponseYes") endif endfunc func HK_FFmpegResponseNo() if WinActive($ffeGUI) then StdinWrite($ffmpeg, "n" & $LOG_LF) WinSetTitle($ffeGUI, "", $title_msg_string) else HotKeySet("n") Send("n") HotKeySet("n", "HK_FFmpegResponseNo") endif endfunc ; send an abort command to the running console application (ffmpeg).. func HK_FFmpegAbort() if WinActive($ffeGUI) then StdinWrite($ffmpeg, "q") Sleep(250) ProcessClose($ffmpeg) ConsoleAdd("user aborted") DoLog($LOG_LF & "user sent abort command!" & $LOG_LF & $LOG_LF) else HotKeySet("{F4}") Send("{F4}") HotKeySet("{F4}", "HK_FFmpegAbort") endif endfunc func HK_RunningAbortBatch() if WinActive($ffeGUI) then $abort_batch = true else HotKeySet("{PAUSE}") Send("{PAUSE}") HotKeySet("{PAUSE}", "HK_RunningAbortBatch") endif endfunc func HK_ProcessPauseSuspend() if WinActive($ffeGUI) then if $paused then $paused = false ProcessSuspendResume($ffmpeg, false) WinSetTitle($ffeGUI, "", $title_msg_string) else $paused = true ProcessSuspendResume($ffmpeg) WinSetTitle($ffeGUI, "", $title_msg_string & " [paused]") endif else HotKeySet("{SCROLLLOCK}") Send("{SCROLLLOCK}") HotKeySet("{SCROLLLOCK}", "HK_ProcessPauseSuspend") endif endfunc func PrimaryUpCheckSize() CheckSize() endfunc ; get window to conform to minimum sizes.. func CheckSize() local $size_array = WinGetClientSize($ffeGUI) if not IsArray($size_array) then return false local $too_far = false ; user window made too small for controls.. if $size_array[0] < $min_width then WinMove($my_title, "", default, default , $min_width+8) $too_far = true endif if $size_array[1] < $min_height then WinMove($my_title, "", default, default , default, $min_height+$height_magic) $too_far = true endif if $too_far then $size_array = WinGetClientSize($ffeGUI) $width = $size_array[0] $height = $size_array[1] ; not actually required ; this will cause a double-run for the grid, but the wobble works well - the user went too far! It's almost Android-like.. if $custom_buttons_columns = "auto" then ReCreateButtonGrid($custom_buttons_array, $grid_x, $grid_y) endif if $minimized = $OFF then GUISetState(@SW_SHOW, $ffeGUI) return true endfunc func ResizeSaveXYPrefs() SaveXYPrefs() endfunc func SaveXYPrefs() if not CheckSize() then return ; set the actual variables, too, so we can refer to them (e.g. $width, for dynamic inp_output - no longer used. hmm). local $size_array = WinGetPos($ffeGUI) if not IsArray($size_array) then return if $size_array[0] < (@desktopWidth-25) then $x = $size_array[0] IniWrite($ini_path, $my_name, "x", $x) endif if $size_array[1] < (@desktopHeight-25) then $y = $size_array[1] IniWrite($ini_path, $my_name, "y", $y) endif $size_array = WinGetClientSize($ffeGUI) if not IsArray($size_array) then return if $size_array[0] >= $min_width then $width = $size_array[0] IniWrite($ini_path, $my_name, "width", $size_array[0]) endif if $size_array[1] >= $min_height-$height_magic then $height = $size_array[1] IniWrite($ini_path, $my_name, "height", $size_array[1]) endif ; we may need to re-calculate the number of custom button columns.. if $custom_buttons_columns = "auto" then ReCreateButtonGrid($custom_buttons_array, $grid_x, $grid_y) endfunc func AbortBatch() $abort_batch = true endfunc ; Pre-Job Commands have gone on too long.. func RunCommandsTimeout() $timeout = true 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="") if $dl_string = "out" then if $log_string then if $dl_append = 1 then $dl_append = 9 else $dl_append = 10 endif local $my_log_file = FileOpen($log_location, $dl_append) FileWriteLine($my_log_file, $my_name & " log @ "&@year&"-"&@mon&"-"&@mday&@hour&"."&@min&"."&@sec&".. " & $LOG_LF & _ "--------------------------------------------------------------------------------" & $LOG_LF) if not $log_extra then FileWriteLine($my_log_file, "command-line: " & $CmdLineRaw & $LOG_LF & $LOG_LF) FileWriteLine($my_log_file, $log_extra) FileWriteLine($my_log_file, $log_string & $LOG_LF) FileClose($my_log_file) $log_string = "" ;2do - put per-job logging here.. endif else $log_string &= UnifyCRLF($dl_string) & $LOG_LF endif return $dl_string endfunc func TestFileWrite($tmpfile) local $t = FileWrite($tmpfile, "") if $t = -1 then return false return true endfunc ; Update the user's existing ini with any new prefs.. ; ; "The maximum supported size of an INI file is 64KB. The maximum size of an individual INI section is 32KB" ; func UpdateIniFile() local $old_version = IniRead($ini_path, $my_name, "version", 0) local $vcomp = _VersionCompare($my_version, $old_version) switch $vcomp case 0, -1 ; both equal return false endswitch local $sample_custom_butts ; drop a temporary ini file somewhere.. local $tmp_ini = @TempDir & "\ffe.ini.new" FileInstall(".\stuff\ffe.ini", $tmp_ini, 1) ; delete all non-application prefs from the new (temp) ini ; basically, remove the sample batches.. local $existing_sections = IniReadSectionNames($tmp_ini) for $a = 1 to $existing_sections[0] if $existing_sections[$a] = $NAME_BUTTONS then $sample_custom_butts = IniReadSection($tmp_ini, $existing_sections[$a]) if $existing_sections[$a] <> $my_name then IniDelete($tmp_ini, $existing_sections[$a]) next ; grab settings from user's old ini file.. $existing_sections = IniReadSectionNames($ini_path) for $a = 1 to $existing_sections[0] local $section = IniReadSection($ini_path, $existing_sections[$a]) if IsArray($section) then for $b = 1 to $section[0][0] ; we manually check for # comments, as AutoIt does not.. if StringLeft($section[$b][0], 1) <> "#" then IniWrite($tmp_ini, $existing_sections[$a], $section[$b][0], $section[$b][1]) endif next endif next ; special circumstance - new section added - ensure old users get this.. if not InArray($existing_sections, $NAME_BUTTONS) then IniWriteSection($tmp_ini, $NAME_BUTTONS, $sample_custom_butts) endif ; rename their existing Batch Runner.ini to "[@date] Batch Runner.ini" FileMove($ini_path, GetParent($ini_path) & "\[" & @YEAR & "-" & @MON & "-" & @MDAY & "@" & @hour & "." & @min & "] ffe.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", $my_version) endfunc func DialogOpen() GUISetState(@SW_DISABLE, $ffeGUI) UnSetHotKeys() endfunc func DialogClose() GUISetState(@SW_ENABLE, $ffeGUI) WinActivate($ffeGUI) SetHotKeys() endfunc ; HotKeys. ; ; Also used, set elsewhere.. ; ; {SCROLLLOCK} ; {PAUSE} ; {F4} ; n ; y func SetHotKeys() HotKeySet("^f", "HK_FindInOutput") HotKeySet("{F3}", "HK_FindInOutput2") HotKeySet("{F8}", "HK_CopyOutput") HotKeySet("{F9}", "HK_MenuToggleShowDropWindow") HotKeySet("{F5}", "HK_ClearOutput") HotKeySet("{Esc}", "HK_DoQuit") HotKeySet("{TAB}", "TabToCreateArgs") if $ffmpeg_binary then HotKeySet("{F1}", "HK_DoIt") HotKeySet("^a", "HK_SelectAllConsoleOutput") HotKeySet("^e", "HK_MenuRetainExitSettings") HotKeySet("^d", "HK_MenuDelayedDoIt") HotKeySet("^m", "HK_ToggleMatofStatus") endfunc ; ^ = Ctrl func UnSetHotKeys() HotKeySet("^f") HotKeySet("{F3}") HotKeySet("{F8}") HotKeySet("{Esc}") HotKeySet("{TAB}") HotKeySet("{F1}") HotKeySet("^a") HotKeySet("^e") ; HotKeySet("^d") HotKeySet("^m") endfunc ; create the arguments afresh every time you use the key.. func TabToCreateArgs() HotKeySet("{TAB}") Send("{TAB}") HotKeySet("{TAB}","TabToCreateArgs") if WinActive($ffeGUI) then DoArgsCreate() endfunc ; hit {F1} to start the encoding process.. func HK_DoIt() ; ffe is at the front.. if WinActive($ffeGUI) then DoIt() else ; you are in some other application.. HotKeySet("{F1}") Send("{F1}") HotKeySet("{F1}","HK_DoIt") endif endfunc ; find and select the user's query text.. func HK_FindInOutput() if WinActive($ffeGUI) then FindInOutput() else HotKeySet("^f") Send("^f") HotKeySet("^f", "HK_FindInOutput") endif endfunc func HK_FindInOutput2() if WinActive($ffeGUI) then FindInOutput() else HotKeySet("{F3}") Send("{F3}") HotKeySet("{F3}", "HK_FindInOutput2") endif endfunc func FindInOutput() AutoItSetOption("GUIOnEventMode", 0) _GUICtrlEdit_Find($edit_console_output) AutoItSetOption("GUIOnEventMode", 1) endfunc func HK_SelectAllConsoleOutput() if WinActive($ffeGUI) then SelectAllConsoleOutput() else HotKeySet("^a") Send("^a") HotKeySet("^a", "HK_SelectAllConsoleOutput") endif endfunc func SelectAllConsoleOutput() GUICtrlSelectAllText($edit_console_output) endfunc func HK_MenuDelayedDoIt() if WinActive($ffeGUI) then DelayedDoIt() else HotKeySet("^d") Send("^d") HotKeySet("^d","HK_MenuDelayedDoIt") endif endfunc func HK_CopyOutput() if WinActive($ffeGUI) then CopyOutput() else HotKeySet("{F8}") Send("{F8}") HotKeySet("{F8}","HK_CopyOutput") endif endfunc func HK_ClearOutput() if WinActive($ffeGUI) then ClearOutput() else HotKeySet("{F5}") Send("{F5}") HotKeySet("{F5}","HK_ClearOutput") endif endfunc func HK_MenuRetainExitSettings() if WinActive($ffeGUI) then MenuRetainExitSettings() else HotKeySet("^e") Send("^e") HotKeySet("^e","HK_MenuRetainExitSettings") endif endfunc func HK_ToggleMatofStatus() if WinActive($ffeGUI) then ToggleMatofStatus() else HotKeySet("^m") Send("^m") HotKeySet("^m","HK_ToggleMatofStatus") endif endfunc func HK_MenuToggleShowDropWindow() if WinActive($ffeGUI) or WinActive($GUI_DropWindow) then MenuToggleShowDropWindow() else HotKeySet("{F9}") Send("{F9}") HotKeySet("{F9}","HK_MenuToggleShowDropWindow") endif endfunc ; $switching, in case they are going nuts on the keys. ; Sending a second SwitchDropImage() before the first is complete could be problematic. func PreviousDropImage() if $switching then return if WinActive($GUI_DropWindow) then SwitchDropImage(-1) else HotKeySet("{LEFT}") Send("{LEFT}") HotKeySet("{LEFT}","PreviousDropImage") endif endfunc func NextDropImage() if $switching then return if WinActive($GUI_DropWindow) then SwitchDropImage(1) else HotKeySet("{RIGHT}") Send("{RIGHT}") HotKeySet("{RIGHT}","NextDropImage") endif 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) if not FileExists($filepath) then ConsoleAdd($filepath & " not found!") return false endif if IsDir($filepath) then if not WinExists($filepath) then Run("Explorer.exe " & $filepath) ;ShellExecute($filepath) else WinActivate($filepath) endif else local $user_editor = IniRead($ini_path, $my_name, "editor", "notepad.exe") if not run($user_editor & " " & $filepath) then ConsoleAdd("ERROR! I couldn't run:" & '"' & $user_editor & '"') ConsoleAdd("Ironically, you need to check your ini settings! ") endif endif endfunc ; Functions that use it.. ; edit ini prefs.. func EditIniFile() OpenSomething($ini_path) endfunc ; log file.. func OpenLogFile() OpenSomething($log_location) endfunc ; open a folder func OpenImagesFolder() OpenSomething(GetParent($drop_win_image)) endfunc ; converts user 0-100 into real 0-255, also sets "half transparency" for mouse hover ; (normally 50%, but if user trans is too close, we make it 100%) func GetRealTrans() $dropwin_trans_real = 255 * (100 - $drop_win_transparency) / 100 $half_trans = 127 if $drop_win_transparency > 44 and $drop_win_transparency < 56 then $half_trans = 255 endfunc ; Select all the text in a control, usually edit or input controls.. ; Pass the ID of the control.. func GUICtrlSelectAllText($control) GUICtrlSetState($control, $GUI_FOCUS) DllCall('user32.dll', 'long', 'SendMessage', 'hwnd', GUICtrlGetHandle($control), 'uint', $EM_SETSEL, 'int', 0, 'int', -1) 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. ; ; 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!) ; ; So put any control-specific text into the prompt, instead. func CorzFancyInputBox($title, $prompt, $default="", $pass="", $ib_w=-1, $ib_h=-1, $ib_x=-1, $ib_y=-1, $timeout=0, $gui_ex=false, $style=-1, $inipath=$ini_path, $sectionname=$my_name) DialogOpen() local $last_event_mode = AutoItSetOption("GUIOnEventMode", 0) local $coord = AutoItSetOption("GUICoordMode", 1) local $pref_name = CompressToPrefName($title) $ib_x = IniRead($ini_path, $my_name, "inputbox_" & $pref_name & "_x", $ib_x) $ib_y = IniRead($ini_path, $my_name, "inputbox_" & $pref_name & "_y", $ib_y) $ib_w = IniRead($inipath, $sectionname, "inputbox_" & $pref_name & "_width", $ib_w) if not $ib_x or $ib_x = default then $ib_x = -1 if not $ib_y or $ib_y = default then $ib_y = -1 if not $ib_h or $ib_h = default then $ib_h = 96 if not $ib_w or $ib_w = default then $ib_w = @DesktopWidth/2 local $min_w = 200 local $return = false, $error 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-30) GUICtrlSetFont(-1, 10) local $but_OK = GUICtrlCreateButton("OK", $ib_w-45, $ib_h-30, 40, 22, $BS_DEFPUSHBUTTON) GUICtrlSetState(-1, $GUI_ONTOP) local $but_Cancel = GUICtrlCreateButton("Cancel", 5, $ib_h-30, 60, 22) GUICtrlSetState(-1, $GUI_ONTOP) local $inp_MyID = GUICtrlCreateInput($default, 70, $ib_h-30, $ib_w-125, 22, $inputstyle) GUICtrlSetState(-1, $GUI_FOCUS) GUICtrlSetFont (-1, 10 , 400, "", "Lucida Console") GUICtrlSetState(-1, $GUI_DROPACCEPTED) 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) 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 if $size_array[2] < $min_w then WinMove($title, "", default, default, $min_w, $ib_h) if $size_array[3] <> $ib_h then WinMove($title, "", default, default, $min_w, $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", $last_event_mode) AutoItSetOption("GUICoordMode", $coord) GUIDelete($ib_GUI) DialogClose() if $return then ; only write prefs if the user actually changed the position/dimensions.. 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) return $return endif return SetError($error, 0, "") endfunc ; POST-FILE command.. func SpecifyPostFileCommand() local $user_command = CorzFancyInputBox("Post-File Command..", "Enter the FULL command. Put quotes around any paths with spaces. NOTE: You can drag files into this input. You can also use @tokens.", _ $post_file_command, "", @DesktopWidth/2, 96, default, default, 0, $ffeGUI) if $user_command then $post_file_command = $user_command ConsoleAdd("post-file command set to: " & $post_file_command) endif endfunc func SpecifyPreJobCommandsFile() CreateJobCommands($pre_job_commands_file, "Pre") endfunc func SpecifyPostJobCommandsFile() CreateJobCommands($post_job_commands_file, "Post-Job") endfunc func CreatePreJobCommands() CreateJobCommands($pre_job_commands_file, "Pre-Job") endfunc func CreatePostJobCommands() CreateJobCommands($post_job_commands_file, "Post-File") endfunc func CreateJobCommands(ByRef $commands_file, $type, $do_edit=true) local $def_input = "@datadir\" & StringLower($type) & "-commands.bat" if $commands_file then $def_input = TokeniZeString($commands_file) local $user_prc_filename = CorzFancyInputBox( "Specify A " & $type & " Commands File.. ", _ "Please specify the location of the " & $type & " Commands file.. " & $MSG_LF & _ "NOTE: You can use @Tokens in this setting.", $def_input , "" , @DesktopWidth/2, 115, default, default, 0, $ffeGUI) if $user_prc_filename then local $real_user_prc_filename = DeTokenize($user_prc_filename) if $user_prc_filename and StringLeft($real_user_prc_filename, 2) <> '\\' and StringMid($real_user_prc_filename, 2, 1) <> ':' then $real_user_prc_filename = $data_parent & "\" & $real_user_prc_filename endif $commands_file = $real_user_prc_filename if FileExists($real_user_prc_filename) then ConsoleAdd('"' & $commands_file & """ already exists") else ConsoleAdd("creating: """ & $commands_file & '"') FileWrite($real_user_prc_filename, ":: ffe " & $type & " commands" & $LOG_LF & $LOG_LF) endif switch $type case "Pre-Job" LoadPreCommands() case "Post-Job" LoadPostCommands() endswitch if $do_edit then OpenSomething($commands_file) endif ; return $commands_file endfunc ; these functions are called whenever there is a change in command file or presets.. func LoadPreCommands() local $tmp_cf = IniRead($ini_path, $current_preset, "pre_job_commands_file", "---") if not $tmp_cf or $tmp_cf = "---" then $tmp_cf = $pre_job_commands_file $pre_job_commands_file = Detokenize($tmp_cf) LoadCommandsFile($pre_job_commands_file, "Pre", "run_pre_job_commands", $check_run_pre_job_commands) endfunc func LoadPostCommands() local $tmp_cf = IniRead($ini_path, $current_preset, "post_job_commands_file", "---") if not $tmp_cf or $tmp_cf = "---" then $tmp_cf = $post_job_commands_file $post_job_commands_file = Detokenize($tmp_cf) LoadCommandsFile($post_job_commands_file, "Post", "run_post_job_commands", $check_run_post_job_commands) endfunc ; the master command-file loader. ; reads the ini value for the file's path, sets the checkboxes to the correct values ; enables/disables checkboxes. func LoadCommandsFile(ByRef $commands_file, $type, $main_switch, $control) $type = StringLower($type) if $commands_file then $commands_file = SetRelPathToDataDir($commands_file) else if $main_switch = $ON then ConsoleAdd("no " & $type & "-job commands file specified!") return endif ;MAY NOT EXIST YET!!!!!!!!!!; @parent\batch.bat might not yet exist!!!!!!!! if not FileExists($commands_file) then ConsoleAdd("specified " & $type & "-job commands file not found: " & $commands_file) return endif ConsoleWrite(".\" & @ScriptName & "(" & @ScriptLineNumber & "): ==> " & "loading " & $type & "-commands file (" & $commands_file & ") for: " & $current_preset & $LOG_LF) local $tmp_do_run_cmds = IniReadCheckBoxValue($ini_path, $current_preset, $main_switch, "---", true) ; may be working from non-preset, or exit-settings if not $tmp_do_run_cmds or $tmp_do_run_cmds = "---" then $tmp_do_run_cmds = Eval($main_switch) ; may get set back, but that's okay if $commands_file and FileExists($commands_file) then ; @parent\batch.bat might not yet exist. ;2do - check for no @tokens or @tokens that WON'T exist, and disable control. GUICtrlSetState($control, $GUI_ENABLE) ConsoleWrite(".\" & @ScriptName & "(" & @ScriptLineNumber & "): ==> " & $type & "-job-commands ENABLED" & $LOG_LF) else GUICtrlSetState($control, $GUI_DISABLE) ConsoleWrite(".\" & @ScriptName & "(" & @ScriptLineNumber & "): ==> " & $type & "-job-commands DISABLED" & $LOG_LF) endif if $tmp_do_run_cmds then Assign($main_switch, Int($tmp_do_run_cmds)) ; $run_pre_job_commands = $tmp_do_run_cmds GUICtrlSetState($control, Eval($main_switch)) $batch_commands_timeout = IniRead($ini_path, $current_preset, "batch_commands_timeout", 0) $run_commands_with_shell = IniReadCheckBoxValue($ini_path, $current_preset, "run_commands_with_shell", $run_commands_with_shell) ; Update "create" / "edit" tray menu item.. MakeTray() endfunc ; There are easier ways, but none so much FUN! func RunCommandsFile(ByRef $commands_file, ByRef $logfile, ByRef $gen_file, $type) if $commands_file and FileExists($commands_file) then ; we check again before running! local $msg, $run_command, $console_out if $generate_script then ; simply read the batch file into our new batch file.. $gen_file &= FileRead($commands_file) else if $batch_commands_timeout then AdLibRegister("RunCommandsTimeout", $batch_commands_timeout*1000*60) $timeout = false local $command_run, $err if $run_commands_with_shell = $ON then if GetExtension($commands_file) <> "bat" then $msg = $type & "-job command processing aborted" & $LOG_LF & "please give your batch script a .bat extension" $logfile &= DoLog(ConsoleAdd($msg)) & $LOG_LF AdLibUnRegister("RunCommandsTimeout") return false endif ; run the .bat file directly. $msg = $LOG_LF & "running batch file: """ & $commands_file & """.." $logfile &= DoLog(ConsoleAdd($msg)) & $LOG_LF $run_command = @ComSpec & " /c " & ' "' & $commands_file & '" ' $command_run = Run($run_command, "", @SW_HIDE, $STDOUT_CHILD) while true $err = false $console_out = StdoutRead($command_run) $err = @error $console_out = StringStripWS($console_out, 3) $logfile &= DoLog(ConsoleAdd($console_out)) & $LOG_LF if @error or $timeout or not @extended then exitloop Sleep(25) wend StdioClose($command_run) else ; ffe will run the commands one-by-one, replacing @tokens along the way. local $run_commands_list FileReadToArrayOptimized($commands_file, $run_commands_list) ; populates $run_commands_list $msg = $LOG_LF & "running " & StringLower($type) & "-job commands: " & $commands_file $logfile &= DoLog(ConsoleAdd($msg)) & $LOG_LF for $i = 1 to $run_commands_list[0] if StringLeft($run_commands_list[$i], 1) = ":" or StringStripWS($run_commands_list[$i], 3) = "" then continueloop ; ignore comments and such $run_command = @ComSpec & " /c " & DeTokenize($run_commands_list[$i]) $command_run = Run($run_command, "", @SW_HIDE, $STDOUT_CHILD) while true $err = false $console_out = StdoutRead($command_run) $err = @error $console_out = StringStripWS($console_out, 3) $logfile &= DoLog(ConsoleAdd($console_out)) & $LOG_LF if $err or $timeout then exitloop Sleep(25) wend StdioClose($command_run) next endif AdLibUnRegister("RunCommandsTimeout") endif else $msg = $type & "-Job Commands File NOT FOUND!" $logfile &= DoLog(ConsoleAdd($msg)) & $LOG_LF endif return true 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_parent & "\" & $some_path CRT($some_path) endif return $some_path endfunc func EditPostJobCommands() if $post_job_commands_file then OpenSomething($post_job_commands_file) LoadPostCommands() endif endfunc func EditPreJobCommands() if $pre_job_commands_file then OpenSomething($pre_job_commands_file) LoadPreCommands() endif endfunc ; Where oh where is ffmpeg.exe.. func TraySetFFMpegBinaryLocation() SetFFMpegBinaryLocation() endfunc func SetFFMpegBinaryLocation($binary_location=false) ; binary location not supplied in arguments, locate.. if not $binary_location then local $ffmpeg_bin_dir = IniRead($ini_path, $my_name, "ffmpeg_bin_dir", @ProgramFilesDir) if FileExists(Getparent($ffmpeg_binary)) then $ffmpeg_bin_dir = Getparent($ffmpeg_binary) DialogOpen() local $tmp_ffmpeg_binary = FileOpenDialog("Please locate the ffmpeg binary..", $ffmpeg_bin_dir, "ffmpeg binary (ffmpeg.exe)", $ffeGUI) DialogClose() if not $tmp_ffmpeg_binary or @error then ConsoleAdd("ffmpeg binary location setting unchanged: user aborted") return false endif $tmp_ffmpeg_binary = Detokenize($tmp_ffmpeg_binary) $binary_location = Detokenize($tmp_ffmpeg_binary) endif if $binary_location = $ffmpeg_binary then ConsoleAdd("ffmpeg binary location setting unchanged") return false endif IniWrite($ini_path, $my_name, "ffmpeg_bin_dir", GetParent($binary_location)) if FileExists($binary_location) then $ffmpeg_binary = $binary_location local $user_ffmpeg_binary = TokenizeString($ffmpeg_binary) IniWrite($ini_path, $my_name, "ffmpeg_binary", $user_ffmpeg_binary) ConsoleAdd("ffmpeg binary location set to: """ & $user_ffmpeg_binary & """") EnableActiveInputs() endif endfunc ; add some text onto the end of the console output and scroll to end of the output.. func ConsoleAdd($out_string) GUICtrlSetData($edit_console_output, StringStripWS(GUICtrlRead($edit_console_output), 2) & $LOG_LF & $out_string) _GUICtrlEdit_Scroll($edit_console_output, $__EDITCONSTANT_SB_SCROLLCARET) return $out_string endfunc ; REPLACE the console output with some new output.. func SetConsoleOutput($out_string, $scroll_top=false) GUICtrlSetData($edit_console_output, $out_string) if $scroll_top then _GUICtrlEdit_Scroll($edit_console_output, 0) else _GUICtrlEdit_Scroll($edit_console_output, $__EDITCONSTANT_SB_SCROLLCARET) endif return $out_string endfunc func GetEditStyles() if $console_wordwrap = $ON then return BitOR($ES_AUTOVSCROLL, $WS_VSCROLL, $ES_WANTRETURN, $ES_MULTILINE, $ES_NOHIDESEL) else return BitOR($WS_HSCROLL, $ES_AUTOVSCROLL, $WS_VSCROLL, $ES_AUTOHSCROLL, $ES_MULTILINE, $ES_WANTRETURN, $ES_NOHIDESEL) endif endfunc ; 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 = Center the tip horizontally under the control ; And so on. See below this function for more details. ; func GUICtrlSetTipOptional($control_ID, $tip_text, $title="Information:", $icon=$tip_icon, $options=$tip_style) if $do_tooltips = $OFF then return local $style = 0, $hicon, $ret $control_ID = GUICtrlGetHandle($control_ID) if BitAND($options, 1) then $style = $TTS_BALLOON $style = BitOr($style, $TTS_ALWAYSTIP, $TTS_NOPREFIX) 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) _GUIToolTip_SetDelayTime($hToolTip, $TTDT_INITIAL, 400) ; (500ms) Time the pointer must remain stationary within a tool's bounding rectangle before the window appears. _GUIToolTip_SetDelayTime($hToolTip, $TTDT_AUTOPOP, $tooltip_time) ; (5000ms) Time the ToolTip window remains visible if the pointer is stationary within a tool's bounding rectangle. _GUIToolTip_SetDelayTime($hToolTip, $TTDT_RESHOW, 150) ; (100ms) Time it takes for subsequent ToolTip windows to appear as the pointer moves from one tool to another. 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 ; ; [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 the 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 func IsWild($string) if StringInStr($string, "*") or StringInStr($string, "?") then return true return false endfunc ; there are 8 path tokens. ; the usual error checking has been omitted here - let the user func DeTokenize($string) if not $string then return $string if not StringInStr($string, "@") then return $string $string = FixPathSlashes($string) ; dynamic @tokens.. $string = StringReplace($string, "@item", RemoveExtension(BaseName($inputfile))) $string = StringReplace($string, "@ext", GetExtension($inputfile)) $string = StringReplace($string, "@oext", GetExtension($outputfile)) $string = StringReplace($string, "@ofilename", BaseName($outputfile)) $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) ; path @tokens.. $string = StringReplace($string, "@mydocuments", @MyDocumentsDir) $string = StringReplace($string, "@desktop", @DesktopDir) $string = StringReplace($string, "@tempdir", @TempDir) $string = StringReplace($string, "@datadir", $data_parent) $string = StringReplace($string, "@outdir", GetParent($outputfile)) $string = StringReplace($string, "@parent", GetParent($inputfile)) $string = StringReplace($string, "@homedir", @HomeDrive & @HomePath) $string = StringReplace($string, "@programfiles", @ProgramFilesDir) $string = StringReplace($string, "@outputfile", $outputfile) return $string endfunc func TokenizeString($string) if not $string then return $string $string = FixPathSlashes($string) $string = StringReplace($string, @DesktopDir, "@desktop") $string = StringReplace($string, @MyDocumentsDir, "@mydocuments") $string = StringReplace($string, @TempDir, "@tempdir") if $data_parent <> "" then $string = StringReplace($string, $data_parent, "@datadir") if GetParent($outputfile) <> "" then $string = StringReplace($string, GetParent($outputfile), "@outdir") if GetParent($inputfile) <> "" then $string = StringReplace($string, GetParent($inputfile), "@parent") $string = StringReplace($string, @HomeDrive & @HomePath, "@homedir") $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 $string = StringReplace($string, "/", "\") $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. ; ; We do this a lot.. ; ; if StringRight($string, 1) = "\" then $string = StringTrimRight($string, 1) ; ; Functions work on the string ByRef, so you simply do: ; ; CRT("my string") ; ; The idea of the names is; quick to type. ; ; so.. func CRT(ByRef $string, $character="\") local $char_num = StringLen($character) if StringRight($string, $char_num) = $character then $string = StringTrimRight($string, $char_num) endfunc ; And for the left-hand side. func CLT(ByRef $string, $character="\") local $char_num = StringLen($character) if StringLeft($string, $char_num) = $character then $string = StringTrimLeft($string, $char_num) endfunc ; 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". ; func ArrayAdd(byref $array, $item, $dont_dupe=false, $update=false) if not IsArray($array) then return local $size = UBound($array) if $dont_dupe 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 ; 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 StringJoin(ByRef $array, $join_str=$LOG_LF) local $ret_str for $i = 1 to $array[0] $ret_str &= $array[$i] & $join_str next CRT($ret_str, $join_str) return $ret_str endfunc ; ffprobe/mediainfo media reporting.. func GenerateReport() if IsWild($inputfile) then ConsoleAdd("cannot report on directories or multiple files!" & $LOG_LF & "replace the wildcards with a file name!") return false endif if not GetReportingValues() then return false ; GetReportingValues() ; SHIFT+Click to open in viewer/editor (grab this input NOW).. local $do_open = false if ce_IsPressed(10) then $do_open = true local $report_name = Basename(RemoveExtension($inputfile)) & "." & $report_extension if not FileExists($report_directory) then $report_directory = GetParent($inputfile) local $report_loc = $report_directory & "\" & $report_name local $report_str, $err, $probe_file, $sw = "" ; run ffprobe (capturing stdout).. if $use_mediainfo = $ON and FileExists($mediainfo_location) then if $mediainfo_switches then $sw = ' ' & $mediainfo_switches & " " $probe_file = Run( $mediainfo_location & $sw & ' "' & $inputfile & '"', "", @SW_HIDE, $STDOUT_CHILD) else if $report_switches then $sw = " " & $report_switches & " " $probe_file = Run( $ffprobe_loc & " -v error -show_format -show_streams -print_format " & $report_format & $sw & ' "'& $inputfile & '"', "", @SW_HIDE, $STDOUT_CHILD) endif while true $err = false local $console_out = StdoutRead($probe_file) $err = @error if $console_out then $report_str &= $console_out if $err then exitloop Sleep(5) wend StdioClose($probe_file) ProcessClose($probe_file) if $un_escape_output = $ON then $report_str = StringReplace($report_str, "\\", "\") $report_str = StringReplace($report_str, "\:", ":") endif if FileExists($report_loc) then FileDelete($report_loc) local $report_file_open = FileOpen($report_loc, $FO_OVERWRITE+ $FO_CREATEPATH+$FO_UTF8_NOBOM) FileWrite($report_file_open, $report_str) FileClose($report_file_open) if $do_open then ShellExecute($report_loc) else SetConsoleOutput($report_str, true) endif endfunc ; grab this fresh for every report.. func GetReportingValues() $report_format = IniRead($ini_path, $my_name, "report_format", "ini") $report_directory = Detokenize(IniRead($ini_path, $my_name, "report_directory", "@parent")) $report_extension = IniRead($ini_path, $my_name, "report_extension", "ini") $report_switches = IniRead($ini_path, $my_name, "report_switches", "") $un_escape_output = IniReadCheckBoxValue($ini_path, $my_name, "un_escape_output", $ON) $use_mediainfo = IniReadCheckBoxValue($ini_path, $my_name, "use_mediainfo", $OFF) $mediainfo_location = IniRead($ini_path, $my_name, "mediainfo_location", "") $mediainfo_switches = IniRead($ini_path, $my_name, "mediainfo_switches", "") local $mediainfo_extension = IniRead($ini_path, $my_name, "mediainfo_extension", "nfo") if $use_mediainfo = $ON then $report_extension = $mediainfo_extension if not FileExists($mediainfo_location) then ConsoleAdd("MediaInfo.exe not found") return false endif else if $report_extension = "auto" then switch $report_format case "compact" $report_extension = "txt" case else $report_extension = "nfo" endswitch endif $ffprobe_loc = GetParent($ffmpeg_binary) & "\ffprobe.exe" if not FileExists($ffprobe_loc) then ConsoleAdd("ffprobe.exe not found next to ffmpeg" & $LOG_LF & "please place ffprobe.exe next to ffmpeg.exe") return false endif endif return true endfunc func GetLogLocation($this_preset=$my_name) $i = DeTokenize(IniRead($ini_path, $this_preset, "log_location", "")) if $i <> "-" then if $portable then if $i and TestFileWrite($i) then $log_location = $i else if TestFileWrite(@ScriptDir & "\" & $my_name & ".log") then $log_location = @ScriptDir & "\" & $my_name & ".log" endif elseif IsDir($i) and TestFileWrite($i & "\" & $my_name & ".log") then $log_location = $i & "\" & $my_name & ".log" elseif $i and TestFileWrite($i) then $log_location = $i else $log_location = @TempDir & "\" & $my_name & ".log" endif endif endfunc ; Suspend/Resume a process. ; NOTE: You *must* do this before sending DebugSetProcessKillOnExit, or else it will have no effect. func ProcessSuspendResume($proc_name, $do_suspend=true) if IsString($proc_name) then $proc_name = ProcessExists($proc_name) if not $proc_name then return SetError(2, 0, 0) if $do_suspend then DllCall('kernel32.dll','ptr','DebugActiveProcess','int',$proc_name) ; note: opens process with PROCESS_ALL_ACCESS else DllCall('kernel32.dll','ptr','DebugActiveProcessStop','int',$proc_name) endif endfunc ;; Functions from from corz_essentials.. ; 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 ; 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]] if $e <> $some_name and not StringInStr($e, "\") then ; "." was not found - extensionless file, possibly in a path with a dot return $e else return "" endif endfunc ; RemoveExtension() ; ; removes the extension of a file name (including the dot ".") ; requires the above functions func RemoveExtension($some_name) local $add = 0 if StringInStr(BaseName($some_name), ".") then $add = 1 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 ; 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 ; 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 "$dont_recurse" 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, $dont_recurse=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) $n_dirnames[$dircount] = $dir if not FileExists($dir) then return 0 while $dircount > $n_dircount ; keep on looping until all directories are scanned.. ; if $quit = 1 then return $n_dircount += 1 $n_search = FileFindFirstFile($n_dirnames[$n_dircount] & "\*.*") while true ; find all subdirs in this directory and store them in a array.. $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 $dont_recurse 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 quicker than redimming on every loop if $return_dirs then local $tmp_str = "" $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 $dump_file = FileOpen($dump, 2) FileWrite($dump_file, $filenames) FileClose($dump_file) endif return($file_array) endfunc ; IniReadCheckBoxValue() ; ; Slightly altered for ffe 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. Why? .. ; ; Windows annoyingly 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.. 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", "-" 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 ; for display purposes.. func ProcessWriteHumanCheckBoxValue($some_string, $on_str="enabled", $off_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 ; 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") switch $wcbv_val case $GUI_CHECKED $wcbv_val = $tru_val case $GUI_UNCHECKED $wcbv_val = $fal_val case $GUI_INDETERMINATE $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. ; quick switcharoo.. func SwitchBool($bool) if $bool = $ON then return $OFF return $ON 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) 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" if $ia_string = $ia_array[$i] then return $i next return false endfunc ; from the UDF's.. ; here to save including the whole files. ; Description: _Singleton ; Author(s): Valik Func ce_Singleton($occurenceName, $flag = 0) Local $ERROR_ALREADY_EXISTS = 183 $occurenceName = StringReplace($occurenceName, "\", "") ; to avoid error Local $handle = DllCall("kernel32.dll", "int", "CreateMutex", "int", 0, "long", 1, "str", $occurenceName) Local $lastError = DllCall("kernel32.dll", "int", "GetLastError") If $lastError[0] = $ERROR_ALREADY_EXISTS Then If $flag = 0 Then Exit -1 Else SetError($lastError[0]) Return 0 endif endif Return $handle[0] EndFunc ;==>_Singleton ; _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 ; VisitURL() ; ; send the "default browser" to our URL.. ; This uses the USER'S SYSTEM BROWSER! (eg. Firefox) func VisitURL($vu_url="http://corz.org/") ShellExecute($vu_url) if @error <> 0 then return true else return SetError (@error, default , true) endif endfunc ; CleanPath() ; ; Clean-up potentially problematic Windows file path characters.. func CleanPath($string) ; The very brave might use this.. ; $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, "?", "¿") ; For compatibility, I recommend this.. $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 func CompressToPrefName($string) $string = CleanPath($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 ; 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 seconds to readable H/M/S time.. func SecondsToDHMS($sec=0) 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 ; from octet.au3, author unknown.. (note: this is slow) func MakeRandomAlphaNumericString($iLen) local $sString = '' do switch Random ( 1, 3, 1 ) case 1 $sString &= Chr(Random( 48, 57, 1)) ; 0 to 9 case 2 $sString &= Chr(Random( 65, 90, 1)) ; A to Z case 3 $sString &= Chr(Random( 97, 122, 1)) ; a to z endswitch until StringLen($sString) = $iLen return $sString endfunc ; UDF updates.. ; these are 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...........: FileReadToArrayOptimized ; Description ...: Reads the specified file into an array. ; Syntax.........: FileReadToArrayOptimized($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 FileReadToArrayOptimized($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 ;; debugging functions.. ; debug() ; ; provides quick debug report in your console.. ; ; if your text editor can do it (probably), this is a great ; way to get debug output without halting the script execution.. ; ; NOTE: if you call debug() in a compiled script, and $c-debug is set to $ON, ; you will get the debug() output dump()ed, instead. func debug($d_string, $ln=false) if @compiled then return 0 endif ; unlikely to catch anything under normal circumstances (string prepended to input).. if IsArray($d_string) then return PrintArray($d_string, "NOT A STRING!") local $pre if $ln then $pre = ".\" & @ScriptName & "(" & $ln & "): ==> " ConsoleWrite($pre & $d_string & $LOG_LF) endfunc ; PrintArray() ; ; debug output of an array, in the console ; (your text editor can probably display this for you, if you so desire).. func PrintArray(ByRef $array, $tring="array", $limit=0, $ln="") if @compiled then if ($do_debug = 0 or $do_debug = $OFF) then return 0 if $do_debug = $ON then DumpArray($array, "debug") return endif endif local $pre if $ln then $pre = ".\" & @ScriptName & "(" & $ln & ") : ==> " 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 Print2DArray($array, $tring, $limit, $ln) local $pa_string = "" local $count = 0 for $element in $array $pa_string &= '[' & $count & '] : ' & $element & $LOG_LF $count += 1 if $count = $limit then exitloop next ConsoleWrite($pre & $tring & ": " & $LOG_LF & $pa_string & $LOG_LF) endfunc ; Like PrintArray, but will handle arrays with more than two columns.. ; ; Like Debug (), the output will enable you to double-click to go straight to the line of code ; at least, in a decent text editor it will. ; ; ; 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, need $array[0][0] to be meaningful.. func Print2DArray(ByRef $array, $tring="array", $limit=0, $ln="") ; $limit for compatability only if @compiled and ($do_debug = 0 or $do_debug = $OFF) then return 0 local $pre if $ln then $pre = ".\" & @ScriptName & " (" & $ln & ") : ==> " 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 ; 1-dimensional array sent.. if UBound($array, 0) < 2 then return PrintArray($array, $tring, $limit, $ln) $limit += 1 local $cols = UBound($array, 2) local $pa_string = "" ; for $i = 0 to $array[0][0] 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 @compiled then dump($LOG_LF & $pre & $tring & ": " & $LOG_LF & $pa_string & $LOG_LF, "compiled", "debug") else ConsoleWrite($LOG_LF & $pre & $tring & ": " & $LOG_LF & $pa_string & $LOG_LF) endif endfunc ; dump() ; ; like debug (), but to a file.. func dump($d_string, $dump_file="dump", $ln=false) if @compiled and $do_debug = $OFF then return 0 local $pre if $ln then $pre = ".\" & @ScriptName & " (" & $ln & ") : ==> " local $fileh = FileOpen($dump_file, 130) ; overwrite + UTF-8 FileWriteLine($fileh, $pre & $d_string & $LOG_LF) endfunc ; DumpArray() ; debug output of an array, to a file.. func DumpArray(ByRef $array, $dump_file="dump", $new=true) if @compiled and ($do_debug = 0 or $do_debug = $OFF) then return 0 if not IsArray($array) then return 0 if UBound($array, 0) > 1 then return Print2DArray($array, $dump_file, $new) if $new then FileOpen($dump_file, 130) ; UTF8 + Overwrite local $da_string = "" local $count = 0 for $element in $array $da_string &= '[' & $count & '] : ' & $element & $LOG_LF $count += 1 next FileWrite($dump_file, $da_string) 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, $my_version, $GUI=default) 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 DialogOpen() local $do_checkver = InputBox("Automatic Version Checking?", $v_name & " can check online for a new version of itself." & $MSG_LF & _ "Enter the number of days between checks (0 to disable version checking). ", "" , " M" , _ 400, 150 , (@DesktopWidth/2)-200, (@DesktopHeight/2)-50, 0, $GUI) DialogClose() if $do_checkver = "" then return false ; cancelled out of inputbox IniWrite($my_ini, $my_section, "version_checking", Number($do_checkver)) ; they enter "fuck off!", we write "0" 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=" & $my_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 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($my_version, $published_version) switch $vcomp case 0, 1 ; both equal (or $my_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, so you better have one up! (set current position with $start) func BackGroundDownload($dl_URL, $timeout=5000, $start=0) Local $c_time, $TmpFile = _WinAPI_GetTempFileName(@TempDir) 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() 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) ProgressSet(0, "", "Failed. Connexion Timeout.") return SetError(1, 2, false) ; 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 ProgressSet(0, "", "Failed. Suspect Firewall.") return SetError(1, 3, false) ; 3 = check firewall else ProgressSet(0, "", "Failed. Suspect Server Unresponsive.") return SetError(1, 1, false) ; 1 = server down endif endif local $fData = FileRead($TmpFile) ProgressSet(0, "", "Success. Got version " & $fData) FileDelete($TmpFile) return $fData endfunc ; Associative Array Functions ; We use a COM object for this (see top of script).. 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) $dict_obj.ADD($key, $val) 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 AAItem(ByRef $dict_obj, $key) return $dict_obj.Item($key) endfunc func AAWipe(ByRef $dict_obj) $dict_obj.RemoveAll() endfunc func AAError() Local $err = $oMyError.number If $err = 0 Then $err = -1 SetError($err) ; to check for after this function returns endfunc func DoAboutBox() DialogOpen() AutoItSetOption("GUIOnEventMode", 0) local $aw = 330, $ah = 210 local $GUI_About = GUICreate(" about " & $my_name & ".. ", $aw, $ah, -1, @DesktopHeight/4, $WS_CAPTION, $WS_EX_TOPMOST, $ffeGUI) GUICtrlCreateIcon($me_app, 0, 15, 10, 32, 32) GUICtrlCreateLabel($my_name & " v" & $my_version & $MSG_LF & _ chr(169) & " cor at " & $my_domain & " 2007-" & @YEAR & " ;o) ", 55, 10, 200, 50) GUICtrlCreateLabel($my_name & " is a simple, powerful front-end for ffmpeg, " & _ "enabling quick alterations to its parameters for rapid testing and production. " & $MSG_LF & $MSG_LF & _ "ffe uniquely uses MATOF" & chr(153) & " technology to automatically update output filenames to " & _ "match your encoding parameters, enabling you to save lots of slightly different versions of a file " & _ "very, very quickly; in other words, 'find the best settings'" & $MSG_LF & _ $MSG_LF & _ "Do you want to visit the " & $my_name & " web page at this time? ", 15, 50, $aw-25, $ah-90) local $GUI_About_NO = GUICtrlCreateButton("Nah", $aw-170, $ah-25, 75, 20, BitOr($WS_TABSTOP,$BS_FLAT)) local $GUI_About_OK = GUICtrlCreateButton("Okay", $aw-85, $ah-25, 75, 20, BitOr($WS_TABSTOP,$BS_FLAT)) GUICtrlSetState($GUI_About_OK, $GUI_FOCUS) GUISetState(@SW_SHOW, $GUI_About) local $msg while true sleep(10) $msg = GUIGetMsg() switch $msg case $GUI_EVENT_CLOSE, $GUI_About_NO exitloop case $GUI_About_OK VisitURL($my_url) exitloop endswitch wend GUIDelete($GUI_About) AutoItSetOption("GUIOnEventMode", 1) DialogClose() endfunc ; Bye Now! func HK_DoQuit() if WinActive($ffeGUI) then DoQuit(-9) else HotKeySet("{Esc}") Send("{Esc}") HotKeySet( "{Esc}" , "HK_DoQuit") endif endfunc func User_DoQuit() DoQuit(-9) endfunc ; Really, Bye! func DoQuit($ext=0) if $kill_ffmpeg_on_exit = $ON then ProcessSuspendResume($ffmpeg) DllCall('kernel32.dll', 'ptr', 'DebugSetProcessKillOnExit', 'int', true) else ProcessSuspendResume($ffmpeg) DllCall('kernel32.dll', 'ptr', 'DebugSetProcessKillOnExit', 'int', false) endif if $minimized = $OFF and $maximized = $OFF then SaveXYPrefs() if (not $go) and ($retain_exit_settings = $ON) then SavePreset($exit_preset) VersionCheckOnline($my_name, $versioncheck_url, $download_url, $ini_path, $my_name, $my_version) GUIDelete($ffeGUI) ; do this AFTER the saving X/Y prefs for main GUI, or else it will be GONE. if $dropwin_visible then HideDropWindow() AAWipe($known_files) ; don't delete this, user may need it. Gets deleted before re-creating. ;if $concatenate and FileExists($concat_list) then FileDelete($concat_list) exit $ext 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 ; compiler directives.. #Region #pragma compile(inputboxres, true) ; AutoIt Wrapper.. #AutoIt3Wrapper_Run_Au3Stripper = y #Au3Stripper_Parameters = /StripOnly #AutoIt3Wrapper_Compile_Both = Y #AutoIt3Wrapper_UseUpx = N #AutoIt3Wrapper_Run_AU3Check = y ;#AutoIt3Wrapper_AU3Check_Parameters = -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -v 1 #AutoIt3Wrapper_AU3Check_Parameters = -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w 7 -v 1 ;#AutoIt3Wrapper_AU3Check_Parameters = -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 -v 1 #AutoIt3Wrapper_AU3Check_Stop_OnWarning = y #AutoIt3Wrapper_Icon = icons\ffe.ico ;-5. #AutoIt3Wrapper_Res_Icon_Add = icons\document-outline.ico ;-6. #AutoIt3Wrapper_Res_Icon_Add = icons\magic-wand.ico ;-7. #AutoIt3Wrapper_Res_Icon_Add = icons\document-small.ico ;-8. #AutoIt3Wrapper_Res_Icon_Add = icons\folder-small.ico ;-9. #AutoIt3Wrapper_Res_Icon_Add = icons\folder-small-outline.ico ;-10. #AutoIt3Wrapper_Res_Icon_Add = icons\auto-out.ico ;-11. #AutoIt3Wrapper_Res_Icon_Add = icons\ffe-time.ico ;-12. #AutoIt3Wrapper_Res_Icon_Add = icons\tooltip.ico ;-13. #AutoIt3Wrapper_Res_Icon_Add = icons\target.ico ; Free-Form Res Fields.. #AutoIt3Wrapper_Res_Field = Author|Cor #AutoIt3Wrapper_Res_Field = CompanyName|corz.org #AutoIt3Wrapper_Res_Field = Contact|windows@corz.org #AutoIt3Wrapper_Res_Field = Copyright|corz.org #AutoIt3Wrapper_Res_Field = Instructions|enable MATOF, drag and drop files into ffe, choose a preset, do it! #AutoIt3Wrapper_Res_Field = Long Description|ffe is a Windows front-end for the marvelous ffmpeg. It was designed for rapid testing of the many (many) ffmpeg settings, enabling one to quickly find the best settings for a particular file, and when you do, save it as a preset. Find any cute settings along the way, save those as a preset button. Of course you can also use ffe to perform the actual conversions! #AutoIt3Wrapper_Res_Field = ProductName|ffe #AutoIt3Wrapper_Res_Field = Publisher|corz.org #AutoIt3Wrapper_Res_Field = Web Page|http://corz.org/windows/software/ffe/ #AutoIt3Wrapper_Res_Field = Compiled|%date% %time% ; application's resource info.. #AutoIt3Wrapper_Res_Comment = ffe ; this is the one that shows up in Process Explorer.. #AutoIt3Wrapper_Res_Description = corz ffmpeg front-end for windows #AutoIt3Wrapper_Res_LegalCopyright = corz.org #AutoIt3Wrapper_Res_ProductVersion = 2 #AutoIt3Wrapper_Res_Fileversion = 2.0.0.0 #AutoIt3Wrapper_Res_Field = Build|Public Release ;#AutoIt3Wrapper_Res_Field = Build|Beta Release ;#AutoIt3Wrapper_Res_Field = Build|DEBUG ; copy latest binaries to app folders.. #AutoIt3Wrapper_Run_After = copy "%out%" "C:\Program Files (x86)\corz\ffe\ffe.exe" #AutoIt3Wrapper_Run_After = copy "%outx64%" "C:\Program Files\corz\ffe\ffe.exe" ;; My UBER ffmpeg version.. (many func, but it's slow!) ;#AutoIt3Wrapper_Run_After = copy "%outx64%" "C:\Program Files\corz\ffe+\ffe.exe" ; copy latest binaries to distro folders.. #AutoIt3Wrapper_Run_After = copy "%out%" "..\ffe\ffe.exe" #AutoIt3Wrapper_Run_After = copy "%outx64%" "..\ffe_x64\ffe.exe" #AutoIt3Wrapper_Run_After = copy ".\stuff\ffe.ini" "..\ffe\stuff\ffe.ini" #AutoIt3Wrapper_Run_After = copy ".\stuff\ffe.ini" "..\ffe_x64\stuff\ffe.ini" ; Latest codecs/settings upgrade.. #AutoIt3Wrapper_Run_After = copy ".\stuff\upgrade.ini" "..\ffe\stuff\upgrade.ini" #AutoIt3Wrapper_Run_After = copy ".\stuff\upgrade.ini" "..\ffe_x64\stuff\upgrade.ini" ; grab master license file.. #AutoIt3Wrapper_Run_After = copy "I:\Cor\Dev\AutoIt\Free Software License.txt" ".\stuff\Free Software License.txt #AutoIt3Wrapper_Run_After = copy ".\stuff\Free Software License.txt" "..\ffe\info\Free Software License.txt" #AutoIt3Wrapper_Run_After = copy ".\stuff\Free Software License.txt" "..\ffe_x64\info\Free Software License.txt" #AutoIt3Wrapper_Run_After = copy ".\stuff\QuickStart.txt" "..\ffe\info\QuickStart.txt" #AutoIt3Wrapper_Run_After = copy ".\stuff\QuickStart.txt" "..\ffe_x64\info\QuickStart.txt" ; move latest binaries to top folder (out of way of source pack).. #AutoIt3Wrapper_Run_After = mv "%out%" "..\..\ffe.exe" #AutoIt3Wrapper_Run_After = mv "%outx64%" "..\..\ffe_x64.exe" ; delete temporary script.. #AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_stripped.au3" #EndRegion #cs command-line tests.. "I:\Rip\ffe\MKV\PS3-Baby.flv" load(Convert >> FLAC) load(Convert >> MP3) load(Convert >> FLAC) "I:\Rip\ffe\MKV\PS3-Baby.flv" load(x264 slow preset crf 18 (MAX Q) COPY audio) http://jell.yfish.us/media/Jellyfish-3-Mbps.mkv go "I:\Rip\ffe\MKV\PS3-Baby.flv" ^^ this should NOT go! go(ffe) "I:\Rip\ffe\MKV\PS3-Baby.flv" go(x264 slow preset crf 18 (MAX Q) COPY audio) "I:\Rip\ffe\MKV\PS3-Baby.flv" go(ffe backup mp4) "I:\Rip\ffe\MKV\PS3-Baby.flv" go(FLV to AVI) "I:\Rip\ffe\MKV\PS3-Baby.flv" go(ffe) "I:\Rip\ffe\MKV\PS3-Baby.flv" load(x265 HEVC AAC medium preset AAC Audio HQ Video) "I:\Rip\ffe\MKV\PS3-Baby.flv" go(x265 HEVC AAC medium preset AAC Audio HQ Video) "I:\Rip\ffe\MKV\PS3-Baby.flv" go(Convert >> MP3) "I:\Rip\ffe\MKV\PS3-Baby.flv" go(ffe) "I:\Rip\ffe\MKV\Gigi Rivera [1080p].mkv" go(Convert >> MP3 (TEST)) "I:\Rip\ffe\MKV\Gigi Rivera [1080p].mkv" go(x264 medium preset crf=22 (HQ) COPY Audio (TEST)) "I:\Rip\ffe\MKV\Gigi Rivera [1080p].mkv" load(x265 HEVC AAC medium preset AAC Audio HQ Video) "I:\Rip\ffe\MKV\PS3-Baby.flv" go(x265 HEVC AAC medium preset AAC Audio HQ Video) "I:\Rip\ffe\MKV\PS3-Baby.flv" go(Convert >> MP3) "I:\Rip\ffe\MKV\PS3-Baby.flv" run(Convert >> MP3) "I:\Rip\ffe\MKV\PS3-Baby.flv" generate(Convert >> MP3) "I:\Rip\ffe\MKV\PS3-Baby.flv" generate(x265 HEVC AAC medium preset AAC Audio HQ Video (TEST)) "I:\Rip\ffe\MKV\*.mkv" go(Grab 100 Frames from URL) go(TEST) go(TEST) "I:\Rip\ffe\MKV\PS3-Baby 2.flv" go(TEST) "I:\Rip\ffe\MKV\Humans.S01E??.mkv" go(TEST) "I:\Rip\ffe\MKV\*.mkv" go(TEST) "I:\Rip\ffe\MKV\*.mov" Sample RTMP Streams: rtmp://cp67126.edgefcs.net/ondemand/mp4:mediapm/ovp/content/test/video/spacealonehd_sounas_640_300.mp4 rtmp://fms.12E5.edgecastcdn.net/0012E5/mp4:videos/8Juv1MVa-485.mp4 #ce