QuickScript

A simple text window that will run and/or compile AutoIt3 code.

Download | Source | Icon

Using the compiled version of this script you should be able to run and
compile AutoIt code on machines that do not have AutoIt installed.

#NoTrayIcon
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=QuickScript icon.ico
#AutoIt3Wrapper_Outfile_x64=QuickScript.exe
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_UseUpx=y
#AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Res_Description=QuickScript
#AutoIt3Wrapper_Res_Fileversion=2.10.0.0
#AutoIt3Wrapper_Res_SaveSource=y
#AutoIt3Wrapper_Res_Language=1033
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#pragma compile(AutoItExecuteAllowed, True)

#region - Document

#cs =====README==========README==========README==========README==========README==========README=====
QuickScript - by Rob Saunders - www.therks.com
==============================================

A simple text window that will run and/or compile AutoIt3 code.
Using the compiled version of this script you should be able to run and
compile AutoIt code on machines that do not have AutoIt installed.

The main window has two text areas: the Content (top) and the Console (bottom,
which is not shown by default). Type up your code in the Content area, and then
click the Script menu and choose Run. This will run your code through the
AutoIt interpreter. If your code writes any data to the STDOUT or STDERR stream
the console area will automatically become visible to display that data.
Here's a quick example, try copying and pasting this into the Content and then running it:

    ConsoleWrite('You are running version ' & FileGetVersion(@AutoItExe) & ' of QuickScript')

Config/settings
---------------
By default the program attempts to save/load settings to a config file (QuickScript.ini)
located in the Application Data folder (%AppData%) but if you wish to run the program in
portable mode (ie: from a USB drive) then create a new "QuickScript.ini" (or copy the one
from %AppData%) in the program's parent folder.
eg: Program is stored at "X:\Files\QuickScript.exe" so create/copy to "X:\Files\QuickScript.ini"
The program can also do this automatically if you click the "Options" menu and choose "Enable Portable Mode".

Script menu
-----------
To run the code in the content area, click the "Script" menu and then choose "Run"
or press Ctrl+R. You can also choose "Run w/Params" if you want to run your script
with command line parameters.
To force a running script to end (in the case of an infinite loop, for example),
choose "Force Quit" in the "Script" menu or press Ctrl+Q.
To continue using QuickScript without ending a running script choose "Detach Process"
from the "Script" menu or press Ctrl+D.
To compile your code into a standalone application (exe) or as an encoded script
file (a3x) choose the appropriate option in the "Compile" submenu. You can also export
the compiling program from this submenu.

Options menu
------------
You can setup an alternate program you may wish to open your scripts with, such as
SciTE or TextPad. First choose "Set alt. Program" and browse for the program you
wish to use, then adjust the command line in the following prompt as needed. Then
run the alternate program by choosing "Run alt. program".

Additional include file paths can be set with the "Include paths" menu, separated
by semi-colon. Unfortunately this setting is interpreted directly by AutoIt and must
be stored in the registry instead of the config file (and subsequently is not portable).
The registry key is "HKEY_CURRENT_USER\Software\AutoIt v3\AutoIt" and the item is "Include".

In addition to the extra include locations mentioned above the compiler also stores
some information under the "HKEY_CURRENT_USER\Software\AutoIt v3" registry key, you
can choose to clear all this data with the "Clear registry data" option.

You can also adjust the size of tab characters, the font settings for the content
and console areas, open the config file to edit it manually, or you can export the
AutoIt compiler (Aut2Exe) to a directory of your choosing so you can use it's full features.

Snippets menu
-------------
Snippets are bits of code that you can store for quick use. It's a good place
to store a piece of code used in common tests, like a GUI template or a
hotkey loop. A few snippets come pre-loaded. You can add your own by using
the Snippet menu, or manually editing the config file. The first 10 snippets will
by hotkeyed to Ctrl+0 through Ctrl+9.

Important Notes
---------------
The folders searched for #include <File> are as follows in order:
    - Standard library - The path to QuickScript with "\Include" appended
    - User libraries   - Paths saved in the registry
    - Script directory - The directory of the currently executing script
If the include file is referenced with "" (ie: #include "File") then the search
order is reversed: Script directory, User libraries, Standard library.

User libraries can be set by choosing "Include paths" from the "Options" menu.

If you wish to compile this script yourself you may need to alter the lines
that pertain to the location of the AutoIt3 compiler files. Look for the
functions "_CompilerGetFiles" and "_CompilerFilesCheckCopy" and edit accordingly.

The standard AutoIt include files (String.au3, File.au3, GUIConstants.au3, etc.)
are not installed by this program (too much overhead). You will have to get those yourself.

Version History
---------------
2.10 (2017-Jan-29)
    Change: Method of selecting using line counter. Was having issues with 64 bit due to _GUICtrlEdit_LineIndex() not returning -1 when expected.
    Fix: Script > Run was using params set by Run w/Params.
2.9 (2016-Oct-02)
    Updated for compile with AutoIt v3.3.14.2.
    Change: Replaced _Singleton() with _MySingleton(). _Singleton() wasn't detecting prior instances on some systems.
    Change: WinTitleMatchMode set to 3 (Exact match). Had issues reading handle from proper window in _PreviousInstance() function.
    Change: Renamed STDOUT_MERGED references to STDERR_MERGED.
    Change: Compiler functions to work with new compiler files.
    Change: Added approximate dates to version history, where available.
    Removed: Declaration of STDERR_MERGED and STDOUT_CHILD (now included in AutoItConstants.au3, also STDOUT_CHILD wasn't being used?)
2.8 (2015-Sep-11)
    Change: Replaced all _GUIGetFocus (self written redundant function) usage with Win API functions (_WinAPI_GetFocus & _WinAPI_GetClassName).
    Change: Some wording in the help content.
    Change: Added a second check to the Clear Registry option.
2.7 (2012-Jun-22)
    Change: "Portable mode" method.
2.6 (Date lost)
    Addition: "Portable mode" setting.
    Change: Config file location check (no prompts).
2.5 (2012-Jan-23)
    Change: Command line parameter handling.
    Change: Add Snippet dialog now uses dropdown with existing snippet names (for easier overwrite).
2.4 (2011-Nov-21)
    Change: Compiling more intuitive with Save As dialog (choose Executable, Screen Saver or Encoded Script from "Save as type" dropdown).
    Addition: /new Command line parameter (opens a new window without prompt regardless of Options > Multiple Windows setting).
    Addition: File > New Window menu item.
    Addition: Help > Online Help menu item.
    Addition: Snippets Export.
    Addition: Configurable Escape key action.
    Fix: Set Alt Program menu item now works properly.
2.3 (2011-Oct-09)
    Addition: Menu items for changing multiple instance behaviour. (Options > Multiple windows)
    Addition: New instances launched with filename param will pass filename to previous instance for loading if single instance enabled.
    Change: Disabled Find/Replace, Snippet Inserts and Options menu while script running.
    Change: Prompt when drag/drop file or command line file and script is running.
    Fix: Cancelling drag/drop put dropped filename into edit field.
2.2 (2011-Aug-14)
    Addition: Process detach function. Closes stdio stream to child process so application can proceed while launched script continues to run.
    Addition: Run with parameters option.
    Change: Moved all Script related menu items into their own Scripts menu.
    Change: Rewrote the ReadMe section.
    Fix: Environment variables being evaluated on file save and script run.
    Fix: Viewing ReadMe or source stalling program.
    Fix: Script with Run(@ComSpec) does not close stdio stream even when script process ends. Seems to be fixed now.
2.1 (2011-Jul-26)
    Addition: 64-bit compile ability.
    Change: Compiling process.
2.0 (Date lost)
    Addition: Prompts concerning config file.
    Addition: Menu items New, Save as...
    Addition: Menu item to set alternate program.
    Fix: Errors while scrolling.
    Change: Program icon.
    Change: Program functions more like a normal file editor with respect to loaded/saved files.
    Change: Improved find/replace regular expression handling - still not perfect.
    Change: AutoIt version info displayed in status bar.
    Change: "External Editor" to "Alternate Program"
1.4 (Date lost)
    Fix: Fatal error when using Go To dialog.
    Fix: Escape now closes Find/Replace dialog.
    Fix: Positioning issue when starting with Line Numbers shown.
1.3 (Date lost)
    Addition: Working directory .INI option.
    Addition: Include file menu option.
    Addition: Find/replace dialog.
1.2 (Date lost)
    Addition: Open file from command line parameter. (QuickScript.exe <filename>)
    Change: Line count monitoring, not as slow.
    Change: Word jumping behaviour (Ctrl+Arrows).
    Change: Menu item ordering/grouping.
    Change: "Go to" dialog.
    Change: Help > View ReadMe and View Source now open text files instead of filling editor.
1.1 (Date lost)
    Change: Tweaked the check for two instances a bit.
1.0 (Date lost)
    First numbered version.

AutoIt
------
For more information about AutoIt check online at http://www.autoitscript.com

#ce
=====README==========README==========README==========README==========README==========README=====


;~ #include <Variable.au3>
;~ TraySetState(1)
;~ Opt('TrayIconDebug', 1)
;~ MsgBox(0x30, 'DEBUG', 'This program is in DEBUG mode.', 1)

#region - Constants ----------------------------------------------------------------------------
Global Const $APP_NAME = 'QuickScript'
Global Const $APP_VERSION = '2.10'
Global Const $APP_TITLE = $APP_NAME & ' v' & $APP_VERSION

Global $T = ' 32-bit'
If @AutoItX64 Then $T = ' 64-bit'
Global Const $APP_BIT = $T
Global Const $AUTOIT_VERSION = @AutoItVersion & $APP_BIT
Global $SINGLETON = 'AUTOIT3APPTRACK-' & $APP_NAME

Global Const $EDIT_MAX_LIMIT = 2147483647 ; Max signed int: 0x7fffffff, 2^31-1
Global Const $SIZER_HEIGHT = 5
Global Const $SIZER_TOPLIMIT = 40
Global Const $SIZER_BOTTOMLIMIT = 65
Global Const $STATBAR_HEIGHT = 20
Global Const $MINMAX_SIZE[4] = [ 0, 0, @DesktopWidth, @DesktopHeight ]

Global Enum $COMPILER_FOLDER, $COMPILER_FOLDERWARN, $COMPILER_EXE, $COMPILER_UPX, $COMPILER_UBOUND

Global Const $CBS_DROPDOWNLIST = 0x0003
#endregion
;endregion - Constants ----------------------------------------------------------------------------

#region - Includes ----------------------------------------------------------------------------
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <ScrollBarConstants.au3>
#include <WinApi.au3>
#include <GUIEdit.au3>
#include <File.au3>
#include <Misc.au3>
#include <MySingleton.au3>
#endregion
;endregion - Includes ----------------------------------------------------------------------------

Global $g_iMsgBox, $g_CmdLine = $CmdLine
Opt('MustDeclareVars', 1)
Opt('WinTitleMatchMode', 3)
Opt('GUIOnEventMode', 1)
Opt('GUICloseOnESC', 0)
; Opt('ExpandEnvStrings', 1) ; "Duh" note: When the script is READ from $ed_Content, env vars will be evaluated. Thus any vars in there will be converted BEFORE even being saved to file.

#region - Compiler files check ----------------------------------------------------------------------------
; Whenever the script is run uncompiled it will check if it has up-to-date versions of the compiler files and
; if not it will copy them to the local directory that the FileInstall functions look in.
; If you want to manage these files manually or otherwise don't want this check performed, you can comment out
; the function call below or even just erase it and the function entirely.
_CompilerFilesCheckCopy()
#endregion
;endregion - Compiler files check ----------------------------------------------------------------------------

#region - Config file setup ----------------------------------------------------------------------------
Global $g_sIniFile = _IniFilePreference()
Global $g_bIsPortable = @extended
#endregion - Config file setup
;endregion - Config file setup ----------------------------------------------------------------------------

#region - Command line handling ----------------------------------------------------------------------------
Global $g_bUseNewWinParam, $g_sLoadFile

For $i = 1 To $g_CmdLine[0]
    If $g_CmdLine[$i] = '/new' Then
        $g_bUseNewWinParam = True
    ElseIf FileExists($g_CmdLine[$i]) Then
        If Not $g_sLoadFile Then
            $g_sLoadFile = $g_CmdLine[$i]
        Else
            Run('"' & @AutoItExe & '" /new "' & $g_CmdLine[$i] & '"')
        EndIf
    EndIf
Next

If Not $g_bUseNewWinParam And Not $g_sLoadFile Then
    $g_sLoadFile = _IniReadWrap($g_sIniFile, 'Config', 'LastFile', '')
    If Not FileExists($g_sLoadFile) Then
        $g_sLoadFile = _IniReadWrap($g_sIniFile, 'Config', 'LastRanFile', '')
        If Not FileExists($g_sLoadFile) Then
            $g_sLoadFile = ''
        EndIf
    EndIf
EndIf

#endregion
;endregion - Command line handling ----------------------------------------------------------------------------

#region - Handle multiple instances ----------------------------------------------------------------------------
Global $g_iMultiInstanceFlag = Int(_IniReadWrap($g_sIniFile, 'Config', 'Multi', '-1'))
AutoItWinSetTitle(Random())
Global $g_hAutoItWindow = WinGetHandle(AutoItWinGetTitle())

If Not $g_bUseNewWinParam And Not _MySingleton($SINGLETON, 1) Then
    Switch $g_iMultiInstanceFlag
        Case -1
            $g_iMsgBox = MsgBox(0x2223, $APP_NAME & ' - Notice', $APP_NAME & ' is already running. Open a new window?' & @LF & @LF & _
                ' - (Y)es will open a new window.' & @LF & _
                ' - (N)o will activate the existing window.' & @LF & _
                ' - Cancel will do neither.')
            If $g_iMsgBox = 7 Then
                _PreviousInstance()
            ElseIf $g_iMsgBox = 2 Then
                Exit 2
            EndIf
        Case 0
            _PreviousInstance()
    EndSwitch
EndIf
AutoItWinSetTitle($SINGLETON)

#endregion
;endregion - Handle multiple instances ----------------------------------------------------------------------------

#region - Config settings load ----------------------------------------------------------------------------
Global $g_sWordChars = _IniReadWrap($g_sIniFile, 'Config', 'WordChars', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_@#$')
If @error Then IniWrite($g_sIniFile, 'Config', 'WordChars', $g_sWordChars)

Global $g_iEscapeKeyClose = Int(_IniReadWrap($g_sIniFile, 'Config', 'EscapeClose', '-1'))

; "Duh" Note: Use two variables because WM_MOVE and WM_SIZE will rewrite the var before the window can be initially sized
Global $g_aSaveWinPos, $g_aLoadWinPos = StringSplit(_IniReadWrap($g_sIniFile, 'Config', 'LastWinPos', '-1|-1|-1|-1'), '|')

Global $g_iTabSize = Int(_IniReadWrap($g_sIniFile, 'Config', 'TabSize', 4))
If $g_iTabSize < 1 Then $g_iTabSize = 4
Global $g_aTabStops4Letter[1] = [ $g_iTabSize * 4 ]

Global $g_bAlwaysShowConsole = _IniReadWrap($g_sIniFile, 'Config', 'ShowConsole', 'False')
If $g_bAlwaysShowConsole = 'False' Then $g_bAlwaysShowConsole = False

_IniReadWrap($g_sIniFile, 'Config', 'FirstRun')
If @error Then
    Global $g_aSnippetsData[7][2] = [ [ 6 ], [ '&MsgBox' ], [ '&HotKey Test' ], [ 'Simple &Timer Test' ], [ '&All GUI constants includes' ], [ '&GUI Message Loop Sample' ], [ 'G&UI OnEventMode Sample' ] ]
    $g_aSnippetsData[1][1] = 'MsgBox(0, '''', '''')\n'
    $g_aSnippetsData[2][1] = 'HotKeySet(''{esc}'', ''_Exit'')\n;HotKeySet(''#!^+'', ''_HotKey'')\n\nWhile 1\n\tToolTip(''Looping...'')\n\tSleep(10)\nWEnd\n\nFunc _HotKey()\n\tMsgBox(0x40, ''HotKey:'', @HotKeyPressed)\nEndFunc\n\nFunc _Exit()\n\tExit\nEndFunc\n'
    $g_aSnippetsData[3][1] = '$nTimer = TimerInit()\n; Test\n$nDiff = TimerDiff($nTimer)\nConsoleWrite($nDiff & @LF)\n'
    $g_aSnippetsData[4][1] = '#include <GUIConstants.au3>\n#include <WindowsConstants.au3>\n#include <ButtonConstants.au3>\n#include <ComboConstants.au3>\n#include <ListboxConstants.au3>\n#include <EditConstants.au3>\n#include <ProgressConstants.au3>\n#include <UpdownConstants.au3>\n#include <StaticConstants.au3>\n#include <TabConstants.au3>\n#include <AVIConstants.au3>\n#include <DateTimeConstants.au3>\n#include <TreeviewConstants.au3>\n#include <SliderConstants.au3>\n#include <ListviewConstants.au3>\n'
    $g_aSnippetsData[5][1] = '; #include <GUIConstants.au3>\nGlobal Const $GUI_EVENT_CLOSE = -3\n\n$hGUI = GUICreate('''', 300, 200)\n;GUICtrlCreate\nGUISetState()\n\nWhile 1\n\t$iGUIGetMsg = GUIGetMsg()\n\tSwitch $iGUIGetMsg\n\t\tCase $GUI_EVENT_CLOSE\n\t\t\tExitLoop\n\t\tCase Else\n\t\t\tIf $iGUIGetMsg > 0 Then\n\t\t\t\tToolTip($iGUIGetMsg & '':'' & GUICtrlRead($iGUIGetMsg))\n\t\t\tEndIf\n\tEndSwitch\nWEnd\n'
    $g_aSnippetsData[6][1] = '; #include <GUIConstants.au3>\nGlobal Const $GUI_EVENT_CLOSE = -3\n\nOpt(''GUIOnEventMode'', 1)\n\n$hGUI = GUICreate('''', 200, 200)\n\tGUISetOnEvent($GUI_EVENT_CLOSE, ''_Handler'')\n;GUICtrlCreate\n;\tGUICtrlSetOnEvent(-1, ''_Handler'')\nGUISetState()\n\nWhile 1\n\tSleep(1)\nWEnd\n\nFunc _Handler()\n\tSwitch @GUI_CtrlId\n\t\tCase $GUI_EVENT_CLOSE\n\t\t\tExit\n\t\tCase Else\n\t\t\tIf @GUI_CtrlId > 0 Then\n\t\t\t\tToolTip(@GUI_CtrlId & '':'' & GUICtrlRead(@GUI_CtrlId))\n\t\t\tEndIf\n\tEndSwitch\nEndFunc\n'
    IniWriteSection($g_sIniFile, 'Snippets', $g_aSnippetsData, 1)
EndIf
#endregion - Config settings load
;endregion - Config settings load ----------------------------------------------------------------------------

#region - Variable initializing ----------------------------------------------------------------------------
Global $g_bIgnore_WM_MOVE = False
#endregion
;endregion - Variable initializing ----------------------------------------------------------------------------

#region - Font setting variables ----------------------------------------------------------------------------
Enum $FONT_NAME = 1, $FONT_SIZE, $FONT_WEIGHT, $FONT_ATTS
Global $g_aContentFont = StringSplit(_IniReadWrap($g_sIniFile, 'Config', 'ContentFont', 'Courier New|9|400|0'), '|')
Global $g_aConsoleFont = StringSplit(_IniReadWrap($g_sIniFile, 'Config', 'ConsoleFont', 'Courier New|8|400|0'), '|')
ReDim $g_aContentFont[5] ; Make sure the array is 5 elements, easier error prevention than checking for each index
ReDim $g_aConsoleFont[5] ; Same as above
#endregion
;endregion - Font setting variables ----------------------------------------------------------------------------

#region - Script executing vars ----------------------------------------------------------------------------
Global $g_sGlobalTempFile = @TempDir & '\' & $APP_NAME & '.tmp.au3'
Global $g_sLoadedFile, $g_sLocalTempFile, $g_iRunTimer, $g_iScriptPID, $g_iStdoutRead, $g_sRunParams
Global $g_bShowConsole, $g_bSelectLines
Global $g_bShowLines = _IniReadWrap($g_sIniFile, 'Config', 'ShowLines', 'True')
If $g_bShowLines = 'False' Then $g_bShowLines = False
#endregion
;endregion - Script executing vars ----------------------------------------------------------------------------

#region - Snippet vars ----------------------------------------------------------------------------
Global $g_aSnippetsData[1], $g_aSnippetsMenuItems[1]
#endregion
;endregion - Snippet vars ----------------------------------------------------------------------------

#region - Status bar and line count variables ----------------------------------------------------------------------------
Global $g_sStatusAutoItInfo
If $g_bIsPortable Then $g_sStatusAutoItInfo &= '[ Portable Mode ]'
If @Compiled Then
    $g_sStatusAutoItInfo &= '[ Compiled: AutoIt v' & $AUTOIT_VERSION & ' ]'
Else
    $g_sStatusAutoItInfo &= '[ Running: AutoIt v' & $AUTOIT_VERSION & ' (' & @AutoItExe & ') ]'
EndIf


$g_sStatusAutoItInfo &= '[ Config: ' & $g_sIniFile & ' ]'

Global $g_aEditSel[2], $g_aEditSelMem[2] = [ 1, -1 ]
Global $g_sContent, $g_iLineFromChar, $g_iCharacter, $g_sStatusBarText
Global $g_iLineCount, $g_iLineCountMem = -1, $g_sLineCounterText, $g_iLineVis, $g_iLineVisMem = 0, $g_iLineCountCutOff
#endregion
;endregion - Status bar and line count variables ----------------------------------------------------------------------------

#region - Script source and help file variables ----------------------------------------------------------------------------

Global $g_sSourcePath = @TempDir & '\QuickScript Source.txt'
While Not FileInstall('QuickScript.au3', $g_sSourcePath, 1)
    $g_sSourcePath = _TempFile(@TempDir, 'QuickScript Source ~', '.txt', 8)
WEnd

Global $g_sReadMePath = @TempDir & '\QuickScript ReadMe.txt'
While Not _MakeReadMe($g_sSourcePath, $g_sReadMePath)
    $g_sReadMePath = _TempFile(@TempDir, 'QuickScript ReadMe ~', '.txt', 8)
WEnd

#endregion
;endregion - Script source and help file variables ----------------------------------------------------------------------------

OnAutoItExitRegister('_OnAutoItExit')

#region - Main window ----------------------------------------------------------------------------
Global $g_hGUIMain, _
    $dm_AccelTabShift, $dm_AccelTabCtrlShift, $dm_AccelTabCtrl, $dm_AccelTab, $dm_AccelEscape, $dm_AccelWordRight, $dm_AccelWordLeft, _
    $dm_AccelWordShiftRight, $dm_AccelWordShiftLeft, $dm_AccelCtrlBack, $dm_Stop, _
    $me_File, $mi_FileNew, $mi_FileOpen, $mi_FileReload, $mi_FileSave, $mi_FileSaveAs, $mi_FileNewWin, $mi_FileExit, _
    $me_Edit, $mi_EditFind, $mi_EditFindNext, $mi_EditFindPrev, $mi_EditGoTo, $mi_EditSelectAll, _
    $me_View, $mi_ViewLines, $mi_ViewConsole, $mi_ViewConsoleAlways, _
    $me_Script, $mi_ScriptRun, $mi_ScriptRunParams, $mi_ScriptStop, $mi_ScriptDetach, $mi_ScriptCompile, _
    $me_Options, $mi_OptionsAltProg, $mi_OptionsAltProgSet, $me_OptionsEscapeClose, $mi_OptionsEscapeCloseNo, $mi_OptionsEscapeCloseYes, $mi_OptionsEscapeClosePrompt, _
        $me_OptionsMultiple, $mi_OptionsMultiNo, $mi_OptionsMultiPrompt, $mi_OptionsMultiYes, $mi_OptionsIncludePath, $mi_OptionsTabSize, _
        $mi_OptionsContentFont, $mi_OptionsConsoleFont, $mi_OptionsConfig, $mi_OptionsPortable, $mi_OptionsDelCfg, $mi_OptionsClearReg, _
    $me_Snippets, $mi_SnippetAdd, $mi_SnippetRemove, $mi_SnippetRefresh, $mi_SnippetExport, $me_SnippetInsert, $adm_SnippetKey[10], _
    $me_Help, $mi_HelpDocs, $mi_HelpReadMe, $mi_HelpSource, $mi_HelpAbout, _
    $lb_ContentFrame, $lb_SizerFrame, $lb_ConsoleFrame, $lb_Status

$g_hGUIMain = GUICreate('', 400, 320, -1, -1, $WS_OVERLAPPEDWINDOW, $WS_EX_ACCEPTFILES)
    GUISetOnEvent($GUI_EVENT_CLOSE, '_MainHandler')
    GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, '_MainHandler')
    GUISetOnEvent($GUI_EVENT_PRIMARYUP, '_MainHandler')
    GUISetOnEvent($GUI_EVENT_SECONDARYDOWN, '_MainHandler')
    GUISetOnEvent($GUI_EVENT_SECONDARYUP, '_MainHandler')

    #region - Accelerator dummies ----------------------------------------------------------------------------
    $dm_AccelTabShift = GUICtrlCreateDummy()
        GUICtrlSetOnEvent(-1, '_MainHandler')
    $dm_AccelTabCtrlShift = GUICtrlCreateDummy()
        GUICtrlSetOnEvent(-1, '_MainHandler')
    $dm_AccelTabCtrl = GUICtrlCreateDummy()
        GUICtrlSetOnEvent(-1, '_MainHandler')
    $dm_AccelTab = GUICtrlCreateDummy()
        GUICtrlSetOnEvent(-1, '_MainHandler')
    $dm_AccelEscape = GUICtrlCreateDummy()
        GUICtrlSetOnEvent(-1, '_MainHandler')
    $dm_AccelWordRight = GUICtrlCreateDummy()
        GUICtrlSetOnEvent(-1, '_MoveCaretByWord')
    $dm_AccelWordLeft = GUICtrlCreateDummy()
        GUICtrlSetOnEvent(-1, '_MoveCaretByWord')
    $dm_AccelWordShiftRight = GUICtrlCreateDummy()
        GUICtrlSetOnEvent(-1, '_MoveCaretByWord')
    $dm_AccelWordShiftLeft = GUICtrlCreateDummy()
        GUICtrlSetOnEvent(-1, '_MoveCaretByWord')
    $dm_AccelCtrlBack = GUICtrlCreateDummy()
        GUICtrlSetOnEvent(-1, '_CtrlBackspace')
    #endregion
    ;endregion - Accelerator dummies ----------------------------------------------------------------------------

    $dm_Stop = GUICtrlCreateDummy()
        GUICtrlSetOnEvent(-1, '_ScriptRun')
    #region - Menu ----------------------------------------------------------------------------
    $me_File = GUICtrlCreateMenu('&File')
        $mi_FileNew = GUICtrlCreateMenuItem('&New' & @TAB & 'Ctrl+N', $me_File)
            GUICtrlSetOnEvent(-1, '_MenuHandler')
        $mi_FileOpen = GUICtrlCreateMenuItem('&Open' & @TAB & 'Ctrl+O', $me_File)
            GUICtrlSetOnEvent(-1, '_MenuHandler')
        $mi_FileReload = GUICtrlCreateMenuItem('&Reload', $me_File)
            GUICtrlSetOnEvent(-1, '_MenuHandler')
        $mi_FileSave = GUICtrlCreateMenuItem('&Save' & @TAB & 'Ctrl+Alt+S', $me_File)
            GUICtrlSetOnEvent(-1, '_ScriptSave')
        $mi_FileSaveAs = GUICtrlCreateMenuItem('Save &As...' & @TAB & 'Ctrl+S', $me_File)
            GUICtrlSetOnEvent(-1, '_ScriptSave')
        GUICtrlCreateMenuItem('', $me_File)
        $mi_FileNewWin = GUICtrlCreateMenuItem('New &Window' & @TAB & 'Ctrl+Shift+N', $me_File)
            GUICtrlSetOnEvent(-1, '_MainHandler')
        $mi_FileExit = GUICtrlCreateMenuItem('E&xit' & @TAB & 'Alt+F4', $me_File)
            GUICtrlSetOnEvent(-1, '_MainHandler')

    $me_Edit = GUICtrlCreateMenu('&Edit')
        $mi_EditFind = GUICtrlCreateMenuItem('&Find/Replace' & @TAB & 'Ctrl+F', $me_Edit)
            GUICtrlSetOnEvent(-1, '_FindReplaceHandler')
        $mi_EditFindNext = GUICtrlCreateMenuItem('Find &Next' & @TAB & 'F3', $me_Edit)
            GUICtrlSetOnEvent(-1, '_FindReplaceHandler')
        $mi_EditFindPrev = GUICtrlCreateMenuItem('Find &Prev' & @TAB & 'Shift+F3', $me_Edit)
            GUICtrlSetOnEvent(-1, '_FindReplaceHandler')
        $mi_EditGoTo = GUICtrlCreateMenuItem('&Go To...' & @TAB & 'Ctrl+G', $me_Edit)
            GUICtrlSetOnEvent(-1, '_GoToHandler')
        GUICtrlCreateMenuItem('', $me_Edit)
        $mi_EditSelectAll = GUICtrlCreateMenuItem('Select &All' & @TAB & 'Ctrl+A', $me_Edit)
            GUICtrlSetOnEvent(-1, '_MenuHandler')

    $me_View = GUICtrlCreateMenu('&View')
        $mi_ViewLines = GUICtrlCreateMenuItem('&Line Numbers' & @TAB & 'Alt+L', $me_View)
            GUICtrlSetOnEvent(-1, '_MenuHandler')
        $mi_ViewConsole = GUICtrlCreateMenuItem('&Console' & @TAB & 'Alt+C', $me_View)
            GUICtrlSetOnEvent(-1, '_MenuHandler')
        $mi_ViewConsoleAlways = GUICtrlCreateMenuItem('&Always Show Console', $me_View)
            GUICtrlSetOnEvent(-1, '_MenuHandler')
        If $g_bAlwaysShowConsole Then GUICtrlSetState(-1, $GUI_CHECKED)

    $me_Script = GUICtrlCreateMenu('&Script')
        $mi_ScriptRun = GUICtrlCreateMenuItem('&Run' & @TAB & 'Ctrl+R', $me_Script)
            GUICtrlSetOnEvent(-1, '_ScriptRun')
        $mi_ScriptRunParams = GUICtrlCreateMenuItem('Run &w/Params' & @TAB & 'Ctrl+Shift+R', $me_Script)
            GUICtrlSetOnEvent(-1, '_ScriptRun')
        $mi_ScriptStop = GUICtrlCreateMenuItem('Force &Quit' & @TAB & 'Ctrl+Q', $me_Script)
            GUICtrlSetState(-1, $GUI_DISABLE)
            GUICtrlSetOnEvent(-1, '_ScriptRun')
        $mi_ScriptDetach = GUICtrlCreateMenuItem('&Detach Process' & @TAB & 'Ctrl+D', $me_Script)
            GUICtrlSetState(-1, $GUI_DISABLE)
            GUICtrlSetOnEvent(-1, '_MenuHandler')
            GUICtrlCreateMenuItem('', $me_Script)
        $mi_ScriptCompile = GUICtrlCreateMenuItem('&Compile' & @TAB & 'Ctrl+Alt+C', $me_Script)
            GUICtrlSetOnEvent(-1, '_ScriptSave')

    $me_Snippets = GUICtrlCreateMenu('Sn&ippets')
        $me_SnippetInsert = GUICtrlCreateMenu('&Insert Snippet', $me_Snippets)
        For $i = 0 To 9
            $adm_SnippetKey[$i] = GUICtrlCreateDummy()
                GUICtrlSetOnEvent(-1, '_SnippetsHandler')
        Next
        $mi_SnippetAdd = GUICtrlCreateMenuItem('&Add Snippet' & @TAB & 'Alt+A', $me_Snippets)
            GUICtrlSetOnEvent(-1, '_SnippetsHandler')
        $mi_SnippetRemove = GUICtrlCreateMenuItem('Re&move Snippet' & @TAB & 'Alt+R', $me_Snippets)
            GUICtrlSetOnEvent(-1, '_SnippetsHandler')
        $mi_SnippetRefresh = GUICtrlCreateMenuItem('&Refresh Snippets', $me_Snippets)
            GUICtrlSetOnEvent(-1, '_SnippetsHandler')
        $mi_SnippetExport = GUICtrlCreateMenuItem('E&xport Snippets', $me_Snippets)
            GUICtrlSetOnEvent(-1, '_SnippetsHandler')

    $me_Options = GUICtrlCreateMenu('&Options')
        $mi_OptionsAltProg = GUICtrlCreateMenuItem('Run Alt. &Program' & @TAB & 'Ctrl+P', $me_Options)
            GUICtrlSetOnEvent(-1, '_MenuHandler')
        $mi_OptionsAltProgSet = GUICtrlCreateMenuItem('Set &Alt. Program' & @TAB & 'Ctrl+Alt+P', $me_Options)
            GUICtrlSetOnEvent(-1, '_MenuHandler')
        GUICtrlCreateMenuItem('', $me_Options)
        $me_OptionsEscapeClose = GUICtrlCreateMenu('&Close on Escape Key', $me_Options)
            $mi_OptionsEscapeCloseNo = GUICtrlCreateMenuItem('No', $me_OptionsEscapeClose, 1, 1)
                GUICtrlSetOnEvent(-1, '_MenuHandler')
            $mi_OptionsEscapeCloseYes = GUICtrlCreateMenuItem('Yes', $me_OptionsEscapeClose, 2, 1)
                GUICtrlSetOnEvent(-1, '_MenuHandler')
            $mi_OptionsEscapeClosePrompt = GUICtrlCreateMenuItem('Confirm', $me_OptionsEscapeClose, 3, 1)
                GUICtrlSetOnEvent(-1, '_MenuHandler')
            Switch $g_iEscapeKeyClose
                Case 0
                    GUICtrlSetState($mi_OptionsEscapeCloseNo, $GUI_CHECKED)
                Case 1
                    GUICtrlSetState($mi_OptionsEscapeCloseYes, $GUI_CHECKED)
                Case -1
                    GUICtrlSetState($mi_OptionsEscapeClosePrompt, $GUI_CHECKED)
            EndSwitch

        $me_OptionsMultiple = GUICtrlCreateMenu('&Multiple Windows', $me_Options)
            $mi_OptionsMultiNo = GUICtrlCreateMenuItem('Re-use &one window', $me_OptionsMultiple, 1, 1)
                GUICtrlSetOnEvent(-1, '_MenuHandler')
            $mi_OptionsMultiYes = GUICtrlCreateMenuItem('Use &multiple windows', $me_OptionsMultiple, 2, 1)
                GUICtrlSetOnEvent(-1, '_MenuHandler')
            $mi_OptionsMultiPrompt = GUICtrlCreateMenuItem('&Prompt for each new window', $me_OptionsMultiple, 3, 1)
                GUICtrlSetOnEvent(-1, '_MenuHandler')
            Switch $g_iMultiInstanceFlag
                Case 0
                    GUICtrlSetState($mi_OptionsMultiNo, $GUI_CHECKED)
                Case 1
                    GUICtrlSetState($mi_OptionsMultiYes, $GUI_CHECKED)
                Case Else
                    GUICtrlSetState($mi_OptionsMultiPrompt, $GUI_CHECKED)
            EndSwitch
        $mi_OptionsTabSize = GUICtrlCreateMenuItem('Change &Tab Size: ' & $g_iTabSize, $me_Options)
            GUICtrlSetOnEvent(-1, '_MenuHandler')
        $mi_OptionsContentFont = GUICtrlCreateMenuItem('Content &Font', $me_Options)
            GUICtrlSetOnEvent(-1, '_FontSettings')
        $mi_OptionsConsoleFont = GUICtrlCreateMenuItem('Console F&ont', $me_Options)
            GUICtrlSetOnEvent(-1, '_FontSettings')
        GUICtrlCreateMenuItem('', $me_Options)
        $mi_OptionsIncludePath = GUICtrlCreateMenuItem('Set &Include Paths', $me_Options)
            GUICtrlSetOnEvent(-1, '_MenuHandler')
        $mi_OptionsConfig = GUICtrlCreateMenuItem('Open &Config File', $me_Options)
            GUICtrlSetOnEvent(-1, '_MenuHandler')
        If Not $g_bIsPortable Then
            $mi_OptionsPortable = GUICtrlCreateMenuItem('Enable &Portable Mode', $me_Options)
                GUICtrlSetOnEvent(-1, '_MenuHandler')
        EndIf
        GUICtrlCreateMenuItem('', $me_Options)
;~      If $g_bTwoIniFiles Then
;~          $mi_OptionsDelCfg = GUICtrlCreateMenuItem('Delete Extra Config File', $me_Options)
;~              GUICtrlSetOnEvent(-1, '_MenuHandler')
;~      EndIf
        $mi_OptionsClearReg = GUICtrlCreateMenuItem('Clear Registry Data', $me_Options)
            GUICtrlSetOnEvent(-1, '_MenuHandler')
        GUICtrlCreateMenuItem('E&xport Compiler Files', $me_Options)
            GUICtrlSetOnEvent(-1, '_CompilerExport')

    $me_Help = GUICtrlCreateMenu('&Help')
        $mi_HelpDocs = GUICtrlCreateMenuItem('AutoIt3 Online &Help', $me_Help)
            GUICtrlSetOnEvent(-1, '_HelpMenu')
        GUICtrlCreateMenuItem('', $me_Help)
        $mi_HelpReadMe = GUICtrlCreateMenuItem('View &ReadMe', $me_Help)
            GUICtrlSetOnEvent(-1, '_HelpMenu')
        $mi_HelpSource = GUICtrlCreateMenuItem('View &Source Code', $me_Help)
            GUICtrlSetOnEvent(-1, '_HelpMenu')
        GUICtrlCreateMenuItem('', $me_Help)
        $mi_HelpAbout = GUICtrlCreateMenuItem('&About ' & $APP_NAME, $me_Help)
            GUICtrlSetOnEvent(-1, '_HelpMenu')
    #endregion
    ;endregion - Menu ----------------------------------------------------------------------------

$lb_ContentFrame = GUICtrlCreateLabel('ContentFrame', 0, 0, 400, 280, $SS_SUNKEN)
    GUICtrlSetResizing(-1, $GUI_DOCKBORDERS)
    GUICtrlSetState(-1, $GUI_HIDE)

$lb_SizerFrame = GUICtrlCreateLabel('SizerFrame', 0, 180, 400, $SIZER_HEIGHT, $SS_SUNKEN)
    GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKRIGHT+$GUI_DOCKLEFT)
    GUICtrlSetState(-1, $GUI_HIDE)

$lb_ConsoleFrame = GUICtrlCreateLabel('ConsoleFrame', 0, 185, 400, 95, $SS_SUNKEN)
    GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKRIGHT+$GUI_DOCKLEFT)
    GUICtrlSetState(-1, $GUI_HIDE)


$lb_Status = GUICtrlCreateLabel('', 0, 280, 400, $STATBAR_HEIGHT, BitOR($SS_CENTERIMAGE, $SS_SUNKEN))
    GUICtrlSetResizing(-1, $GUI_DOCKSTATEBAR+$GUI_DOCKRIGHT+$GUI_DOCKLEFT)
#endregion
;endregion - Main window ----------------------------------------------------------------------------

#region - Main window sub frames ----------------------------------------------------------------------------
Global $g_hGUIFrameTop, $ed_Lines, $ed_Content, $g_hGUIFrameBot, $ed_Console, $g_hGUIFrameSize
$g_hGUIFrameTop = GUICreate('ContentFrameWin', 100, 100, 0, 0, $WS_CHILD, Default, $g_hGUIMain)
    GUISetOnEvent($GUI_EVENT_CLOSE, '_MainHandler')
    GUISetOnEvent($GUI_EVENT_DROPPED, '_MainHandler')
    $ed_Lines = GUICtrlCreateEdit('1', 0, 0, 50, 100, BitOR($ES_READONLY, $ES_RIGHT))
        GUICtrlSetCursor(-1, 2)
        GUICtrlSetResizing(-1, BitXOR($GUI_DOCKBORDERS, $GUI_DOCKRIGHT, $GUI_DOCKWIDTH))
        GUICtrlSetFont(-1, $g_aContentFont[$FONT_SIZE], $g_aContentFont[$FONT_WEIGHT], $g_aContentFont[$FONT_ATTS], $g_aContentFont[$FONT_NAME])
        _GUICtrlEdit_SetLimitText($ed_Lines, $EDIT_MAX_LIMIT)
    $ed_Content = GUICtrlCreateEdit('', 50, 0, 50, 100, BitOR($GUI_SS_DEFAULT_EDIT, $ES_NOHIDESEL))
        GUICtrlSetResizing(-1, $GUI_DOCKBORDERS)
;~      GUICtrlSetState(-1, $GUI_DROPACCEPTED)
        GUICtrlSetFont(-1, $g_aContentFont[$FONT_SIZE], $g_aContentFont[$FONT_WEIGHT], $g_aContentFont[$FONT_ATTS], $g_aContentFont[$FONT_NAME])
        _GUICtrlEdit_SetTabStops($ed_Content, $g_aTabStops4Letter)
        _GUICtrlEdit_SetMargins($ed_Content, $EC_LEFTMARGIN, 10)
        _GUICtrlEdit_SetLimitText($ed_Content, $EDIT_MAX_LIMIT)
GUISetState()

$g_hGUIFrameBot = GUICreate('ConsoleFrameWin', 400, 90, 0, 190, $WS_CHILD, Default, $g_hGUIMain)
    GUISetOnEvent($GUI_EVENT_CLOSE, '_MainHandler')
    $ed_Console = GUICtrlCreateEdit('', 0, 0, 400, 90)
        GUICtrlSetResizing(-1, $GUI_DOCKBORDERS)
        GUICtrlSetFont(-1, $g_aConsoleFont[$FONT_SIZE], $g_aConsoleFont[$FONT_WEIGHT], $g_aConsoleFont[$FONT_ATTS], $g_aConsoleFont[$FONT_NAME])
        _GUICtrlEdit_SetTabStops($ed_Console, $g_aTabStops4Letter)
        _GUICtrlEdit_SetMargins($ed_Console, $EC_LEFTMARGIN, 10)
        _GUICtrlEdit_SetLimitText($ed_Console, 2^31-1) ; 0x7fffffff, 2147483647

$g_hGUIFrameSize = GUICreate('SizerFrameWin', 400, $SIZER_HEIGHT, 0, 180, $WS_CHILD, Default, $g_hGUIMain)
    GUISetCursor(11, 1)
    GUICtrlCreateLabel('', -5, 0, 410, $SIZER_HEIGHT, Default, $GUI_WS_EX_PARENTDRAG)
        GUICtrlSetResizing(-1, $GUI_DOCKBORDERS)
GUISetState()
#endregion
;endregion - Main window sub frames ----------------------------------------------------------------------------

#region - Compile options window ----------------------------------------------------------------------------
Global $g_hGUICompile, $cb_CompileCompress, $in_CompileIcon, $bt_CompileIcon, $ch_CompilePack, $ch_Compile64, $ch_CompileConsole, $bt_CompileOK, $bt_CompileCancel
$g_hGUICompile = GUICreate('Compile Options', 300, 150, Default, Default, BitOR($WS_CAPTION, $WS_SYSMENU), Default, $g_hGUIMain)
    GUISetOnEvent($GUI_EVENT_CLOSE, '_CompileOptHandler')
GUICtrlCreateLabel('Custom &icon:', 5, 5, 70, 20, $SS_CENTERIMAGE)
$in_CompileIcon = GUICtrlCreateInput('', 70, 5, 195, 20)
$bt_CompileIcon = GUICtrlCreateButton('...', 265, 5, 30, 20)
    GUICtrlSetOnEvent(-1, '_CompileOptHandler')

GUICtrlCreateLabel('C&ompression level:', 5, 30, 100, 20, $SS_CENTERIMAGE)
$cb_CompileCompress = GUICtrlCreateCombo('', 100, 30, 80, 100, $CBS_DROPDOWNLIST)
    GUICtrlSetData(-1, 'Lowest|Low|Normal|High|Highest', 'Highest')

$ch_CompilePack = GUICtrlCreateCheckbox('Pack with UP&X', 5, 55, 160, 20)
    GUICtrlSetState(-1, $GUI_CHECKED)
$ch_Compile64 = GUICtrlCreateCheckbox('Compile for 64 &bit systems', 5, 75, 160, 20)
$ch_CompileConsole = GUICtrlCreateCheckbox('Compile as &console application', 5, 95, 160, 20)

$bt_CompileOK = GUICtrlCreateButton('OK', 170, 120, 60, 25)
    GUICtrlSetOnEvent(-1, '_CompileOptHandler')
$bt_CompileCancel = GUICtrlCreateButton('Cancel', 235, 120, 60, 25)
    GUICtrlSetOnEvent(-1, '_CompileOptHandler')
#endregion
;endregion - Compile options window ----------------------------------------------------------------------------

#region - Compile status window ----------------------------------------------------------------------------
Global $g_hGUICompileStatus, $lb_CompileStatus
$g_hGUICompileStatus = GUICreate('Compiling...', 200, 75, Default, Default, BitOR($WS_POPUP, $WS_BORDER), Default, $g_hGUIMain)
$lb_CompileStatus = GUICtrlCreateLabel('', 0, 0, 200, 75, BitOR($SS_CENTERIMAGE, $SS_CENTER))
#endregion
;endregion - Compile status window ----------------------------------------------------------------------------

#region - Find window ----------------------------------------------------------------------------
Global $g_hGUIFind, $in_FindFind, $in_FindReplace, $bt_FindFind, $bt_FindReplace, $bt_FindReplaceAll, $bt_FindClose, $ch_FindCase, $ch_FindEscape, $ch_FindRegEx
$g_hGUIFind = GUICreate('Find/Replace', 310, 105, Default, Default, BitOR($WS_CAPTION, $WS_SYSMENU), Default, $g_hGUIMain)
    GUISetOnEvent($GUI_EVENT_CLOSE, '_FindReplaceHandler')
GUICtrlCreateLabel('Fi&nd:', 5, 5, 45, 20, $SS_CENTERIMAGE)
$in_FindFind = GUICtrlCreateInput('', 55, 5, 175, 20)
GUICtrlCreateLabel('Re&place:', 5, 30, 45, 20, $SS_CENTERIMAGE)
$in_FindReplace = GUICtrlCreateInput('', 55, 30, 175, 20)
$bt_FindFind = GUICtrlCreateButton('&Find', 235, 5, 70, 20)
    GUICtrlSetState(-1, $GUI_DEFBUTTON)
    GUICtrlSetOnEvent(-1, '_FindReplaceHandler')
$bt_FindReplace = GUICtrlCreateButton('&Replace', 235, 30, 70, 20)
    GUICtrlSetOnEvent(-1, '_FindReplaceHandler')
$bt_FindReplaceAll = GUICtrlCreateButton('Replace &All', 235, 55, 70, 20)
    GUICtrlSetOnEvent(-1, '_FindReplaceHandler')
$bt_FindClose = GUICtrlCreateButton('Close', 235, 80, 70, 20)
    GUICtrlSetOnEvent(-1, '_FindReplaceHandler')
$ch_FindCase = GUICtrlCreateCheckbox('Match &case', 5, 55, 220, 15)
$ch_FindEscape = GUICtrlCreateCheckbox('Transform &escape chars (\r \n \t \\)', 5, 70, 220, 15)
    GUICtrlSetTip(-1, '\r = Carriage return. \n = New line. \t = Tab. \\ = \')
$ch_FindRegEx = GUICtrlCreateCheckbox('Regular e&xpressions (ref''s = \1 or $1)', 5, 85, 220, 15)
    GUICtrlSetOnEvent(-1, '_FindReplaceHandler')
    GUICtrlSetTip(-1, 'For group back references use \# or $# where # is the group number (starting from 1)')
#endregion
;endregion - Find window ----------------------------------------------------------------------------

#region - Go to window ----------------------------------------------------------------------------
Global $g_hGUIGoTo, $in_GoToLine, $in_GoToColumn, $lb_GoToCurrLine, $lb_GoToCurrCol, $lb_GoToLastLine, $lb_GoToLastColLabel, $lb_GoToLastCol, $bt_GoToOK, $bt_GoToCancel
$g_hGUIGoTo = GUICreate('Go to...', 280, 70, Default, Default, BitOR($WS_CAPTION, $WS_SYSMENU), Default, $g_hGUIMain)
    GUISetOnEvent($GUI_EVENT_CLOSE, '_GoToHandler')
GUICtrlCreateLabel('Go to &Line:', 5, 5, 65, 20, $SS_CENTERIMAGE)
$in_GoToLine = GUICtrlCreateInput('', 70, 5, 45, 20, BitOR($ES_LEFT, $ES_AUTOHSCROLL, $ES_NUMBER))
GUICtrlCreateLabel('&Column:', 130, 5, 45, 20, $SS_CENTERIMAGE)
$in_GoToColumn = GUICtrlCreateInput('', 175, 5, 40, 20, BitOR($ES_LEFT, $ES_AUTOHSCROLL, $ES_NUMBER))

GUICtrlCreateLabel('Current Line:', 5, 25, 65, 20, $SS_CENTERIMAGE)
$lb_GoToCurrLine = GUICtrlCreateLabel('', 70, 25, 45, 20, $SS_CENTERIMAGE)
GUICtrlCreateLabel('Column:', 130, 25, 45, 20, $SS_CENTERIMAGE)
$lb_GoToCurrCol = GUICtrlCreateLabel('', 175, 25, 40, 20, $SS_CENTERIMAGE)

GUICtrlCreateLabel('Last Line:', 5, 45, 65, 20, $SS_CENTERIMAGE)
$lb_GoToLastLine = GUICtrlCreateLabel('', 70, 45, 45, 20, $SS_CENTERIMAGE)
$lb_GoToLastColLabel = GUICtrlCreateLabel('Column:', 130, 45, 45, 20, $SS_CENTERIMAGE)
$lb_GoToLastCol = GUICtrlCreateLabel('', 175, 45, 40, 20, $SS_CENTERIMAGE)

$bt_GoToOK = GUICtrlCreateButton('Go', 225, 5, 50, 25)
    GUICtrlSetState(-1, $GUI_DEFBUTTON)
    GUICtrlSetOnEvent(-1, '_GoToHandler')
$bt_GoToCancel = GUICtrlCreateButton('Cancel', 225, 35, 50, 25)
    GUICtrlSetOnEvent(-1, '_GoToHandler')
#endregion
;endregion - Go to window ----------------------------------------------------------------------------

#region - Accelerators ----------------------------------------------------------------------------
Global $g_aAccelKeys[42][2] = [ _
    [ '^n', $mi_FileNew ], _
    [ '^o', $mi_FileOpen ], _
    [ '^!s', $mi_FileSave ], _
    [ '^s', $mi_FileSaveAs ], _
    [ '^+n', $mi_FileNewWin ], _
    [ '^a', $mi_EditSelectAll ], _
    [ '^r', $mi_ScriptRun ], _
    [ '^+r', $mi_ScriptRunParams ], _
    [ '^q', $mi_ScriptStop ], _
    [ '^d', $mi_ScriptDetach ], _
    [ '^!c', $mi_ScriptCompile ], _
    [ '^p', $mi_OptionsAltProg ], _
    [ '^!p', $mi_OptionsAltProgSet ], _
    [ '^g', $mi_EditGoTo ], _
    [ '!c', $mi_ViewConsole ], _
    [ '!l', $mi_ViewLines ], _
    [ '!a', $mi_SnippetAdd ], _
    [ '!r', $mi_SnippetRemove ], _
    [ '{esc}', $dm_AccelEscape ], _
    [ '{tab}', $dm_AccelTab ], _
    [ '+{tab}', $dm_AccelTabShift ], _
    [ '^{tab}', $dm_AccelTabCtrl ], _
    [ '^+{tab}', $dm_AccelTabCtrlShift ], _
    [ '^{left}', $dm_AccelWordLeft ], _
    [ '^{right}', $dm_AccelWordRight ], _
    [ '^+{left}', $dm_AccelWordShiftLeft ], _
    [ '^+{right}', $dm_AccelWordShiftRight ], _
    [ '^{bs}', $dm_AccelCtrlBack ], _
    [ '^f', $mi_EditFind ], _
    [ '^h', $mi_EditFind ], _
    [ '{f3}', $mi_EditFindNext ], _
    [ '+{f3}', $mi_EditFindPrev ], _
    [ '^1', $adm_SnippetKey[1] ], _
    [ '^2', $adm_SnippetKey[2] ], _
    [ '^3', $adm_SnippetKey[3] ], _
    [ '^4', $adm_SnippetKey[4] ], _
    [ '^5', $adm_SnippetKey[5] ], _
    [ '^6', $adm_SnippetKey[6] ], _
    [ '^7', $adm_SnippetKey[7] ], _
    [ '^8', $adm_SnippetKey[8] ], _
    [ '^9', $adm_SnippetKey[9] ], _
    [ '^0', $adm_SnippetKey[0] ] ]
GUISetAccelerators($g_aAccelKeys, $g_hGUIMain)

Global $g_aAccelKeys[1][2] = [ [ '{esc}', $bt_GoToCancel ] ]
GUISetAccelerators($g_aAccelKeys, $g_hGUIGoTo)

Global $g_aAccelKeys[1][2] = [ [ '{esc}', $bt_FindClose ] ]
GUISetAccelerators($g_aAccelKeys, $g_hGUIFind)
#endregion
;endregion - Accelerators ----------------------------------------------------------------------------

GUIRegisterMsg($WM_DROPFILES, 'WM_DROPFILES')
GUIRegisterMsg($WM_COMMAND, 'WM_COMMAND')
GUIRegisterMsg($WM_GETMINMAXINFO, 'WM_GETMINMAXINFO')
GUIRegisterMsg($WM_SIZE, 'WM_SIZE')
GUIRegisterMsg($WM_MOVE, 'WM_MOVE')
GUIRegisterMsg($WM_PAINT, 'WM_PAINT')

_SnippetLoad()

GUISetState(@SW_SHOW, $g_hGUIMain)
_ToggleLines($g_bShowLines, $g_bShowLines)
If $g_bAlwaysShowConsole Then _ToggleConsole($g_bShowConsole)

If $g_aLoadWinPos[0] = 4 And $g_aLoadWinPos[1] <> -1 And $g_aLoadWinPos[2] <> -1 Then
    WinMove($g_hGUIMain, '', $g_aLoadWinPos[1], $g_aLoadWinPos[2], $g_aLoadWinPos[3], $g_aLoadWinPos[4])
EndIf
$g_aSaveWinPos = WinGetPos($g_hGUIMain)

If $g_sLoadFile Then
    _LoadFileContents($g_sLoadFile)
EndIf


ControlFocus($g_hGUIMain, '', $ed_Content)
_GUICtrlEdit_SetSel($ed_Content, 0, 0)

ControlSetText($g_hAutoItWindow, '', 1, $g_hGUIMain)

#region - Program idle ----------------------------------------------------------------------------
While 1
    #region - Monitor for second launch with file ----------------------------------------------------------------------------
    Global $g_sExternalInfo = ControlGetText($g_hAutoItWindow, '', 1)
    If $g_sExternalInfo <> $g_hGUIMain Then
        If $g_iScriptPID Then
            If Not _ScriptRun() Then
                ControlSetText($g_hAutoItWindow, '', 1, $g_hGUIMain)
                ContinueLoop
            EndIf
        EndIf
        If _SaveChangesPrompt() Then
            If @extended = -1 Then
                ControlSetText($g_hAutoItWindow, '', 1, $g_hGUIMain)
                ContinueLoop
            ElseIf @extended = 1 Then
                If Not _ScriptSave() Then
                    ControlSetText($g_hAutoItWindow, '', 1, $g_hGUIMain)
                    ContinueLoop
                EndIf
            EndIf
        EndIf

        _LoadFileContents($g_sExternalInfo)
        ControlSetText($g_hAutoItWindow, '', 1, $g_hGUIMain)
    EndIf
    #endregion
    ;endregion - Monitor for second launch with file ----------------------------------------------------------------------------

    #region - Running script tracker ----------------------------------------------------------------------------
    If _ScriptRunTracker($g_iScriptPID) Then
        _AppSetTitle('Running script... (PID: ' & $g_iScriptPID & '; Time: ' & Round(TimerDiff($g_iRunTimer) / 1000, 2) & ')')
    Else
        _AppSetTitle()
    EndIf
    #endregion
    ;endregion - Running script tracker ----------------------------------------------------------------------------

    #region - Status bar info ----------------------------------------------------------------------------
    $g_aEditSel = _GUICtrlEdit_GetSel($ed_Content)
    If $g_aEditSel[0] <> $g_aEditSelMem[0] Or $g_aEditSel[1] <> $g_aEditSelMem[1] Then
        $g_iLineFromChar = _GUICtrlEdit_LineFromChar($ed_Content, -1)
        $g_iCharacter = $g_aEditSel[0] - _GUICtrlEdit_LineIndex($ed_Content, $g_iLineFromChar)
        $g_sStatusBarText = StringFormat('[ Line: %d/%d ][ Column: %d/%d ][ Selection: %d/%d chars ]%s', _
            $g_iLineFromChar + 1, _
            _GUICtrlEdit_GetLineCount($ed_Content), _
            $g_iCharacter + 1, _
            _GUICtrlEdit_LineLength($ed_Content, $g_iLineFromChar - 1) + 1, _
            Abs($g_aEditSel[0] - $g_aEditSel[1]), _
            _GUICtrlEdit_GetTextLen($ed_Content), _
            $g_sStatusAutoItInfo)

        GUICtrlSetData($lb_Status, ' ' & $g_sStatusBarText)
        GUICtrlSetTip($lb_Status, $g_sStatusBarText)

        $g_aEditSelMem = $g_aEditSel

        #region - Correct linefeeds missing carriage returns (causes visual issues) ----------------------------------------------------------------------------
        ; Nestled in here keeps it to checking only when caret moves
        If _GUICtrlEdit_GetModify($ed_Content) Then
            $g_sContent = GUICtrlRead($ed_Content)
            If StringRegExp($g_sContent, '[^\r]\n') Then
                $g_sContent = StringStripCR($g_sContent)
                $g_sContent = StringAddCR($g_sContent)
                GUICtrlSetData($ed_Content, $g_sContent)
                _GUICtrlEdit_Scroll($ed_Content, $SB_SCROLLCARET)
            EndIf
        EndIf
        #endregion
    EndIf
    #endregion
    ;endregion - Status bar info ----------------------------------------------------------------------------

    #region - Line tracking ----------------------------------------------------------------------------
    If $g_bShowLines Then
        $g_iLineCount = _GUICtrlEdit_GetLineCount($ed_Content)
        If $g_iLineCount <> $g_iLineCountMem Then
            $g_iLineCountCutOff = StringInStr($g_sLineCounterText, @CRLF, 0, $g_iLineCount)
            If $g_iLineCountCutOff = 0 Then
                Global $g_sLineCounterText = ''
                For $for = 1 to $g_iLineCount + 100
                    $g_sLineCounterText &= $for & @CRLF
                Next
                $g_iLineCountCutOff = StringInStr($g_sLineCounterText, @CRLF, 0, $g_iLineCount)
            EndIf

            _GUICtrlEdit_BeginUpdate($ed_Lines)
            GUICtrlSetData($ed_Lines, StringLeft($g_sLineCounterText, $g_iLineCountCutOff) & @CRLF & @CRLF)
            _GUICtrlEdit_EndUpdate($ed_Lines)
            $g_iLineCountMem = $g_iLineCount
            $g_iLineVisMem = -1
        EndIf

        $g_iLineVis = _GUICtrlEdit_GetFirstVisibleLine($ed_Content)

        If $g_iLineVis <> $g_iLineVisMem Then
            _SendMessage(GUICtrlGetHandle($ed_Lines), $WM_VSCROLL, $SB_TOP)
            _GUICtrlEdit_LineScroll($ed_Lines, 0, $g_iLineVis)
            $g_iLineVisMem = $g_iLineVis
        EndIf
    EndIf
    #endregion
    ;endregion - Line tracking ----------------------------------------------------------------------------

    Sleep(10)
WEnd
#endregion
;endregion - Program idle ----------------------------------------------------------------------------

#region - Main GUI Handlers ----------------------------------------------------------------------------
Func _MainHandler()
    Switch @GUI_CtrlId
        ; Tab actions
        Case $dm_AccelTab, $dm_AccelTabShift
            Local $hFocusCtrl = _WinAPI_GetFocus()
            If $hFocusCtrl = GUICtrlGetHandle($ed_Content) OR $hFocusCtrl = GUICtrlGetHandle($ed_Console) Then
                _GUICtrlEdit_BeginUpdate($hFocusCtrl)
                Local $aLineSel[2], $aEditSel, $aEditSelByAnchor, $iAnchor = 0, $iLineLen, $sNewText, $sSelText
                $aEditSel = _GUICtrlEdit_GetSel($hFocusCtrl)
                $aEditSelByAnchor = _GUICtrlEdit_GetSelByAnchor($hFocusCtrl)
                If $aEditSel[0] = $aEditSelByAnchor[0] Then $iAnchor = 1

                $aLineSel[0] = _GUICtrlEdit_LineFromChar($hFocusCtrl, $aEditSel[0])
                $aLineSel[1] = _GUICtrlEdit_LineFromChar($hFocusCtrl, $aEditSel[1])

                If $aLineSel[0] <> $aLineSel[1] Then
                    $iLineLen = _GUICtrlEdit_LineLength($hFocusCtrl, $aLineSel[1])
                    $aLineSel[0] = _GUICtrlEdit_LineIndex($hFocusCtrl, $aLineSel[0])
                    $aLineSel[1] = _GUICtrlEdit_LineIndex($hFocusCtrl, $aLineSel[1])

                    If $aEditSel[1] <> $aLineSel[1] Then $aLineSel[1] += $iLineLen

                    _GUICtrlEdit_SetSel($hFocusCtrl, $aLineSel[0], $aLineSel[1])
                    $sSelText = StringMid(_GUICtrlEdit_GetText($hFocusCtrl), $aLineSel[0] + 1, $aLineSel[1]-$aLineSel[0])

                    If @GUI_CtrlId = $dm_AccelTab Then
                        $sNewText = StringRegExpReplace($sSelText, '(?m)^(.*)', @TAB & '\1')
                    Else
                        $sNewText = StringRegExpReplace($sSelText, '(?m)^\t(.*)', '\1')
                    EndIf
                    _GUICtrlEdit_ReplaceSel($hFocusCtrl, $sNewText, True)
                    If $iAnchor Then
                        _GUICtrlEdit_SetSel($hFocusCtrl, $aLineSel[0], $aLineSel[0]+StringLen($sNewText))
                    Else
                        _GUICtrlEdit_SetSel($hFocusCtrl, $aLineSel[0]+StringLen($sNewText), $aLineSel[0])
                    EndIf
                ElseIf @GUI_CtrlId = $dm_AccelTab Then
                    _GUICtrlEdit_ReplaceSel($hFocusCtrl, @TAB, True)
                EndIf
                _GUICtrlEdit_EndUpdate($hFocusCtrl)
            EndIf
        Case $dm_AccelTabCtrlShift, $dm_AccelTabCtrl
            If $g_bShowConsole Then
                Local $hFocusCtrl = _WinAPI_GetFocus()
                If $hFocusCtrl = GUICtrlGetHandle($ed_Console) Then
                    ControlFocus($g_hGUIMain, '', $ed_Content)
                Else
                    ControlFocus($g_hGUIMain, '', $ed_Console)
                EndIf
            EndIf

        ; Window events
        Case $GUI_EVENT_PRIMARYDOWN
            Local $gc = GUIGetCursorInfo($g_hGUIFrameTop)
            If $gc[4] = $ed_Lines Then $g_bSelectLines = True
        Case $GUI_EVENT_PRIMARYUP
            If $g_bSelectLines Then
                Local $aLineSel = _GUICtrlEdit_GetSel($ed_Lines) ; Get selection
                Local $iStartLine = _GUICtrlEdit_LineFromChar($ed_Lines, $aLineSel[0]) ; Get line of sel start
                Local $iEndLine = _GUICtrlEdit_LineFromChar($ed_Lines, $aLineSel[1]) ; Get line of sel end

                Local $iStartSel = _GUICtrlEdit_LineIndex($ed_Content, $iStartLine) ; First char of start line
                If $iStartSel = -1 Then
                    ; If start line is out of bounds, cancel selection and return
                    ControlFocus($g_hGUIFrameTop, '', $ed_Content)
                    $g_bSelectLines = False
                    Return
                EndIf

                Local $iEndSel
                If $iEndLine >= _GUICtrlEdit_GetLineCount($ed_Content) Then ; If line selection is greater than lines in Content then select to end of Content
                    $iEndSel = _GUICtrlEdit_GetTextLen($ed_Content)
                Else
                    ; First char of end line (LineIndex), plus the line length, plus 2 for @CRLF
                    $iEndSel = _GUICtrlEdit_LineIndex($ed_Content, $iEndLine) + _GUICtrlEdit_LineLength($ed_Content, $iEndLine) + 2
                EndIf

                _GUICtrlEdit_SetSel($ed_Content, $iStartSel, $iEndSel)
                ControlFocus($g_hGUIFrameTop, '', $ed_Content)

                $g_bSelectLines = False
            EndIf
        Case $mi_FileNewWin
            If IsArray($g_aSaveWinPos) And UBound($g_aSaveWinPos) >= 3 Then
                IniWrite($g_sIniFile, 'Config', 'LastWinPos', $g_aSaveWinPos[0] + 16 & '|' & $g_aSaveWinPos[1] + 16 & '|' & $g_aSaveWinPos[2] & '|' & $g_aSaveWinPos[3])
            EndIf
            If @Compiled Then
                Run('"' & @AutoItExe & '" /new')
            Else
                Run('"' & @AutoItExe & '" "' & @ScriptFullPath & '" /new')
            EndIf
        Case $GUI_EVENT_CLOSE, $mi_FileExit, $dm_AccelEscape
            If $g_iScriptPID Then
                GUICtrlSendToDummy($dm_Stop, 1)
            Else
                If @GUI_CtrlId = $dm_AccelEscape Then
                    If $g_iEscapeKeyClose = -1 Then
                        If MsgBox(0x42024, $APP_NAME & ' - Confirm', 'Exit ' & $APP_NAME & '?', 0, $g_hGUIMain) = 7 Then Return
                    ElseIf $g_iEscapeKeyClose = 0 Then
                        Return
                    EndIf
                EndIf

                If _SaveChangesPrompt() Then
                    If @extended = -1 Then Return
                    If @extended = 0 Then Exit 99
                    If @extended = 1 Then
                        If _ScriptSave() Then Exit 99
                    EndIf
                Else
                    Exit 99
                EndIf
            EndIf
    EndSwitch
EndFunc

Func _MenuHandler()
    Switch @GUI_CtrlId
        ; File menu actions ----------------------------------------------------------------------------
        Case $mi_FileNew
            If _SaveChangesPrompt() Then
                If @extended = -1 Then Return
                If @extended = 1 Then
                    If Not _ScriptSave() Then Return
                EndIf
            EndIf

            GUICtrlSetData($ed_Content, '')
            _SetLoadedFile('')
        Case $mi_FileOpen
            If _SaveChangesPrompt() Then
                If @extended = -1 Then Return
                If @extended = 1 Then
                    If Not _ScriptSave() Then Return
                EndIf
            EndIf

            Local $sFileOpen = FileOpenDialog('Open', _PathSplitWrap($g_sLoadedFile, 1+2), 'AutoIt (*.au3)|All files (*.*)', 1, '', $g_hGUIMain)
            If Not @error Then
                _LoadFileContents($sFileOpen)
            EndIf
        Case $mi_FileReload
            If $g_sLoadedFile And _GUICtrlEdit_GetModify($ed_Content) Then
                If MsgBox(0x2031, $APP_NAME & ' - Warning', 'Reloading the file will cause you to lose your changes. Continue?') = 1 Then
                    _LoadFileContents($g_sLoadedFile)
                EndIf
            EndIf

        ; Edit menu actions ----------------------------------------------------------------------------
        Case $mi_EditSelectAll

            Local $hFocusCtrl = _WinAPI_GetFocus()
            Local $sFocusClass = _WinAPI_GetClassName($hFocusCtrl)
            If $sFocusClass = 'Edit' Then _GUICtrlEdit_SetSel($hFocusCtrl, 0, -1)

        ; View menu actions ----------------------------------------------------------------------------
        Case $mi_ViewConsole
            _ToggleConsole($g_bShowConsole)
        Case $mi_ViewConsoleAlways
            If BitAND(GUICtrlRead($mi_ViewConsoleAlways), $GUI_CHECKED) Then
                GUICtrlSetState($mi_ViewConsoleAlways, $GUI_UNCHECKED)
                $g_bAlwaysShowConsole = False
            Else
                GUICtrlSetState($mi_ViewConsoleAlways, $GUI_CHECKED)
                $g_bAlwaysShowConsole = True
                _ToggleConsole($g_bShowConsole, True)
            EndIf
        Case $mi_ViewLines
            _ToggleLines($g_bShowLines)

        ; Options menu actions ----------------------------------------------------------------------------
        Case $mi_OptionsEscapeCloseYes
            $g_iEscapeKeyClose = 1
            IniWrite($g_sIniFile, 'Config', 'EscapeClose', $g_iEscapeKeyClose)
        Case $mi_OptionsEscapeCloseNo
            $g_iEscapeKeyClose = 0
            IniWrite($g_sIniFile, 'Config', 'EscapeClose', $g_iEscapeKeyClose)
        Case $mi_OptionsEscapeClosePrompt
            $g_iEscapeKeyClose = -1
            IniWrite($g_sIniFile, 'Config', 'EscapeClose', $g_iEscapeKeyClose)

        Case $mi_OptionsMultiYes
            $g_iMultiInstanceFlag = 1
            IniWrite($g_sIniFile, 'Config', 'Multi', $g_iMultiInstanceFlag)
        Case $mi_OptionsMultiNo
            $g_iMultiInstanceFlag = 0
            IniWrite($g_sIniFile, 'Config', 'Multi', $g_iMultiInstanceFlag)
        Case $mi_OptionsMultiPrompt
            $g_iMultiInstanceFlag = -1
            IniWrite($g_sIniFile, 'Config', 'Multi', $g_iMultiInstanceFlag)
        Case $mi_OptionsTabSize
            Local $iNewTabSize = InputBox('Set tab size', 'Tab size', $g_iTabSize, '', 200, 130, Default, Default, 0, $g_hGUIMain)
            If Not @error Then
                $iNewTabSize = Int($iNewTabSize)
                If $iNewTabSize >= 1 Then
                    $g_iTabSize = $iNewTabSize
                    $g_aTabStops4Letter[0] = $g_iTabSize * 4

                    _GUICtrlEdit_SetTabStops($ed_Content, $g_aTabStops4Letter)
                    _GUICtrlEdit_SetTabStops($ed_Console, $g_aTabStops4Letter)
                    GUICtrlSetData($mi_OptionsTabSize, 'Change &Tab Size: ' & $g_iTabSize)
                Else
                    MsgBox(0x2030, $APP_NAME & ' - Notice', 'Invalid tab size.', 0, $g_hGUIMain)
                EndIf
            EndIf
        Case $mi_OptionsIncludePath
            Local $sIncludePath = RegRead('HKCU\SOFTWARE\AutoIt v3\AutoIt', 'Include')
            $sIncludePath = InputBox('Include paths', 'Include file directories (semi-colon separated).' & @CRLF & _
                '* NOTE: This value is written/read from the registry at:' & @CRLF & _
                'HKEY_CURRENT_USER\SOFTWARE\AutoIt v3\AutoIt', $sIncludePath, '', 400, 160, Default, Default, 0, $g_hGUIMain)
            If Not @error Then RegWrite('HKCU\SOFTWARE\AutoIt v3\AutoIt', 'Include', 'REG_SZ', $sIncludePath)
        Case $mi_OptionsClearReg
            If MsgBox(0x2134, $APP_NAME & ' - Clear registry', 'Warning: This will erase the entire "HKEY_CURRENT_USER\SOFTWARE\AutoIt v3" registry key, are you sure you want to do this?', 0, $g_hGUIMain) = 6 Then
                If MsgBox(0x2134, $APP_NAME & ' - Clear registry (double check)', 'Last warning: Please note, if you have AutoIt installed, this could negatively impact how it operates and it may need to be reinstalled. Are you absolutely sure you want to continue?', 0, $g_hGUIMain) = 6 Then
                    RegDelete('HKCU\SOFTWARE\AutoIt v3')
                EndIf
            EndIf
        Case $mi_OptionsConfig
            If Not _IniReadWrap($g_sIniFile, 'Config', 'ConfigWarned', False) Then
                MsgBox(0x2040, $APP_NAME & ' - Notice', 'You may need to restart the application for any changes to be effective.' & @LF & 'This message will not be shown again.', 0, $g_hGUIMain)
                IniWrite($g_sIniFile, 'Config', 'ConfigWarned', 1)
            EndIf
            ShellExecute($g_sIniFile)
        Case $mi_OptionsPortable
            If MsgBox(0x2021, $APP_NAME & ' - Confirm', 'Are you sure you want to enable Portable Mode?' & @LF & _
                'This will attempt to copy the settings file into the program''s folder' & @LF & _
                '(' & @ScriptDir & ') and then restart the program.', 0, $g_hGUIMain) = 1 Then
                If _SaveChangesPrompt() Then
                    If @extended = -1 Then Return
                    If @extended = 1 Then
                        If Not _ScriptSave() Then Return
                    EndIf
                EndIf
                If Not FileCopy($g_sIniFile, @ScriptDir & '\' & $APP_NAME & '.ini') Then
                    MsgBox(0x2030, $APP_NAME & ' - Warning', 'Unable to create file. Write permission may be unavailable.', 0, $g_hGUIMain)
                Else
                    If @Compiled Then
                        Local $sRelaunchScript = _TempFile()
                        _FileSave($sRelaunchScript, '#NoTrayIcon' & @CRLF & 'ProcessWaitClose(' & @AutoItPID & ')' & @CRLF & 'Sleep(1000)' & @CRLF & 'Run(FileGetShortName(@AutoItExe))' & @CRLF & 'FileDelete(@ScriptFullPath)')
                        Run('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & $sRelaunchScript & '"')
                        Exit
                    Else
                        GUIDelete($g_hGUIMain)
                        MsgBox(0x40, $APP_NAME & ' - Notice', 'The program must be restarted manually in non-compiled mode.')
                        Exit
                    EndIf
                EndIf
            EndIf
;~      Case $mi_OptionsDelCfg
;~          Local $sIniDelete = $g_sIniUser
;~          If $g_sIniFile == $g_sIniUser Then $sIniDelete = $g_sIniLocal
;~          If MsgBox(0x2134, $APP_NAME & ' - Notice', 'Are you sure you want to delete the other config file?' & @LF & $sIniDelete, 0, $g_hGUIMain) = 6 Then
;~              FileDelete($sIniDelete)
;~              GUICtrlDelete($mi_OptionsDelCfg)
;~          EndIf
        Case $mi_OptionsAltProg
            If $g_sLoadedFile <> '' Then
                Local $sAltProgram = _IniReadWrap($g_sIniFile, 'Config', 'AltProg', '', True)
                If Not $sAltProgram Then Return MsgBox(0x2010, $APP_NAME & ' - Error', 'Alternate program not set.', 0, $g_hGUIMain)

                If _SaveChangesPrompt() Then
                    If @extended = -1 Then Return
                    If @extended = 1 Then
                        If Not _ScriptSave() Then Return
                    EndIf
                EndIf
                $sAltProgram = StringReplace($sAltProgram, '%1', $g_sLoadedFile)
                $sAltProgram = StringReplace($sAltProgram, '%file%', $g_sLoadedFile)
                $sAltProgram = StringReplace($sAltProgram, '%line%', $g_iLineFromChar + 1)
                $sAltProgram = StringReplace($sAltProgram, '%col%', $g_iCharacter + 1)
                $sAltProgram = _WinAPI_ExpandEnvironmentStrings($sAltProgram)
                Run($sAltProgram)
                If @error Then MsgBox(0x2030, $APP_NAME & ' - Warning', 'Unable to start the following command:' & @LF & $sAltProgram, 0, $g_hGUIMain)
            Else
                MsgBox(0x2030, $APP_NAME & ' - Warning', 'No file loaded to open in alternate program.', 0, $g_hGUIMain)
            EndIf
        Case $mi_OptionsAltProgSet
            Local $sAltProgram = _IniReadWrap($g_sIniFile, 'Config', 'AltProg', Default, True)
            Local $sAltProgTip = 'Enter the command line for the alternate program:' & @LF & @LF & _
                'Available variables:' & @LF & _
                ' - %1, %file% = File path' & @LF & _
                ' - %line% = Current line number' & @LF & _
                ' - %col% = Current column number' & @LF & _
                ' eg: "C:\SciTE\SciTE.exe" "%file%" -goto:%line%'

            $sAltProgram = InputBox('Alternate Program', $sAltProgTip & @LF & @LF & _
                'Enter "?" to browse for a file.', $sAltProgram, '', 400, 250, Default, Default, 0, $g_hGUIMain)
            If @error Then Return
            If $sAltProgram = '?' Then

                $sAltProgram = FileOpenDialog('Choose program:', '', 'Applications (*.exe)|All files (*.*)', 1, '', $g_hGUIMain)
                If @error Then Return

                $sAltProgram = InputBox('Alternate program command line', $sAltProgTip, _
                    '"' & $sAltProgram & '" "%file%"', '', 400, 220, Default, Default, 0, $g_hGUIMain)
                If @error Then Return
            EndIf
            IniWrite($g_sIniFile, 'Config', 'AltProg', $sAltProgram)

        ; Script menu actions ----------------------------------------------------------------------------
        Case $mi_ScriptDetach
            _ScriptRunTracker($g_iScriptPID, -1)
    EndSwitch
EndFunc

Func _GoToHandler()
    Switch @GUI_CtrlId
        Case $mi_EditGoTo
            Local $iCurrLine = _GUICtrlEdit_LineFromChar($ed_Content, -1)
            Local $aEditSel = _GUICtrlEdit_GetSel($ed_Content)
            Local $iColumn = $aEditSel[0] - _GUICtrlEdit_LineIndex($ed_Content, $iCurrLine) + 1
            Local $iLastLine = _GUICtrlEdit_GetLineCount($ed_Content)

            GUICtrlSetData($in_GoToLine, '')
            GUICtrlSetData($in_GoToColumn, '')
            GUICtrlSetData($lb_GoToCurrLine, $iCurrLine+1)
            GUICtrlSetData($lb_GoToCurrCol, $iColumn)
            GUICtrlSetData($lb_GoToLastLine, $iLastLine)

            GUISetState(@SW_DISABLE, $g_hGUIMain)
            GUISetState(@SW_SHOW, $g_hGUIGoTo)
            ControlFocus($g_hGUIGoTo, '', $in_GoToLine)
        Case $bt_GoToOK
            Local $iGoToLine = GUICtrlRead($in_GoToLine)
            If $iGoToLine Then
                _GoTo($iGoToLine, GUICtrlRead($in_GoToColumn))
            EndIf
            GUISetState(@SW_ENABLE, $g_hGUIMain)
            GUISetState(@SW_HIDE, $g_hGUIGoTo)
;~          ContinueCase ; Fatal error au3.3.7.9
        Case $GUI_EVENT_CLOSE, $bt_GoToCancel
            GUISetState(@SW_ENABLE, $g_hGUIMain)
            GUISetState(@SW_HIDE, $g_hGUIGoTo)
    EndSwitch
EndFunc

Func _FindReplaceHandler()
    Switch @GUI_CtrlId
        Case $bt_FindFind, $mi_EditFindNext, $mi_EditFindPrev, $bt_FindReplace
            Local $sContent = GUICtrlRead($ed_Content)
            Local $sFindString = GUICtrlRead($in_FindFind)
            If Not $sFindString Or Not $sContent Then Return

            Local $aEditSel, $aRegEx, $iOffset, $iFoundLen, $iStart, $iEnd, $sSelString, $iPos
            Local $iOccurence = 1, $iWrapPos = 1, $iCaseSense = 0
            If BitAND(GUICtrlRead($ch_FindCase), $GUI_CHECKED) Then $iCaseSense = 1

            Local $sReplaceString = GUICtrlRead($in_FindReplace)
            If BitAND(GUICtrlRead($ch_FindEscape), $GUI_CHECKED) Then $sReplaceString = StringFormat(StringReplace($sReplaceString, '%', '%%'))

            ; If we're in regex mode:
            If BitAND(GUICtrlRead($ch_FindRegEx), $GUI_CHECKED) Then
                Local $aEditSel = _GUICtrlEdit_GetSel($ed_Content)
                ; Regex Find Prev
                If @GUI_CtrlId = $mi_EditFindPrev Then
                    ; Quick explanation: Since there's no native way to do a StringRegExp in reverse (ie: search from the end to the start of a string)
                    ; I invented this method:
                    ; 1) I StringLeft() $sContent to the current caret position ($sPartContent).
                    ; 2) I StringRight() $sPartContent 1 char at a time ($sSubpartContent) testing the regex each time.
                    ; 3) I continue testing until A) the regex is successful and B) the match is as large as it can be, because
                    ;    if I ended at the first successful match then a pattern like "a+b" would stop at "ab" when it should be "aaaaab"
                    ; 4) If I get no result, I redo the whole thing with the entire $sContent (ie: wrap around to the content end).
                    Local $aContentEnd[2] = [ $aEditSel[0], StringLen($sContent) ], $sPartContent, $sSubpartContent, $aRegEx, $iOffset
                    For $forRedo = 0 To 1
                        $sPartContent = StringLeft($sContent, $aContentEnd[$forRedo])
                        For $for = 1 to StringLen($sPartContent)
                            $sSubpartContent = StringRight($sPartContent, $for)
                            $aRegEx = StringRegExp($sSubpartContent, $sFindString, 2)
                            If @error = 2 Then Return MsgBox(0x2030, $APP_NAME & ' - Notice', 'Bad regex pattern. Error at ' & @extended, 0, $g_hGUIFind)
                            $iOffset = @extended-1
                            If Not @error And ($iOffset > StringLen($aRegEx) Or $for = StringLen($sPartContent)) Then
                                $iOffset += StringLen($sPartContent) - $for
                                _GUICtrlEdit_SetSel($ed_Content, $iOffset - StringLen($aRegEx[0]), $iOffset)
                                Return
                            EndIf
                        Next
                    Next
                    MsgBox(0x2040, $APP_NAME & ' - Notice', 'No regex matches for "' & $sFindString & '"', 0, $g_hGUIFind)
                Else
                    $aEditSel = _GUICtrlEdit_GetSel($ed_Content)
                    ; Regex Replace
                    If @GUI_CtrlId = $bt_FindReplace Then
                        $aRegEx = StringRegExp($sContent, $sFindString, 2, $aEditSel[0]+1)
                        If @error = 2 Then
                            Return MsgBox(0x2030, $APP_NAME & ' - Notice', 'Bad regex pattern. Error at ' & @extended, 0, $g_hGUIFind)
                        ElseIf @error = 1 Then
                            $aRegEx = StringRegExp($sContent, $sFindString, 2)
                            If @error Then Return MsgBox(0x2040, $APP_NAME & ' - Notice', 'No regex matches for "' & $sFindString & '"', 0, $g_hGUIFind)
                        EndIf

                        $iOffset = @extended - 1
                        $iFoundLen = StringLen($aRegEx[0])
                        _GUICtrlEdit_SetSel($ed_Content, $iOffset - $iFoundLen, $iOffset)
                        Local $aEditSel[2] = [ $iOffset - $iFoundLen, $iOffset ]

                        $sReplaceString = StringRegExpReplace($aRegEx[0], $sFindString, $sReplaceString)
                        If Not @error And @extended Then
                            _GUICtrlEdit_ReplaceSel($ed_Content, $sReplaceString, True)
                            $sContent = GUICtrlRead($ed_Content)
                            $aEditSel[1] = $aEditSel[0]
                        EndIf
                    EndIf
                    ; This covers the regex Find and continues from the Replace
                    $aRegEx = StringRegExp($sContent, $sFindString, 2, $aEditSel[1]+1)
                    If @error = 2 Then
                        Return MsgBox(0x2030, $APP_NAME & ' - Notice', 'Bad regex pattern. Error at ' & @extended, 0, $g_hGUIFind)
                    ElseIf @error = 1 Then
                        $aRegEx = StringRegExp($sContent, $sFindString, 2)
                        If @error Then Return MsgBox(0x2040, $APP_NAME & ' - Notice', 'No regex matches for "' & $sFindString & '"', 0, $g_hGUIFind)
                    EndIf

                    $iOffset = @extended - 1
                    $iFoundLen = StringLen($aRegEx[0])
                    _GUICtrlEdit_SetSel($ed_Content, $iOffset - $iFoundLen, $iOffset)
                EndIf
            Else
                ; This is all the non-regex find/replace
                If @GUI_CtrlId = $mi_EditFindPrev Then
                    ; If we're doing Find Prev it's just a simple switch of some vars.
                    $iOccurence = -1
                    $iWrapPos = StringLen($sContent)
                EndIf
                If BitAND(GUICtrlRead($ch_FindEscape), $GUI_CHECKED) Then $sFindString = StringFormat(StringReplace($sFindString, '%', '%%'))

                $aEditSel = _GUICtrlEdit_GetSel($ed_Content)
                ; Here's the Replace section
                If @GUI_CtrlId = $bt_FindReplace Then
                    $iPos = StringInStr($sContent, $sFindString, $iCaseSense, $iOccurence, $aEditSel[0]+1)
                    If Not $iPos Then
                        $iPos = StringInStr($sContent, $sFindString, $iCaseSense, $iOccurence, $iWrapPos)
                        If Not $iPos Then Return MsgBox(0x2040, $APP_NAME & ' - Notice', 'Cannot find "' & $sFindString & '"', 0, $g_hGUIFind)
                    EndIf
                    _GUICtrlEdit_SetSel($ed_Content, $iPos-1, $iPos-1+StringLen($sFindString))
                    _GUICtrlEdit_ReplaceSel($ed_Content, $sReplaceString, True)
                    $sContent = GUICtrlRead($ed_Content)
                    Local $aEditSel[2] = [ $iPos-1, $iPos-1 ]
                EndIf
                ; The Find section, also continues from the Replace section
                $iPos = StringInStr($sContent, $sFindString, $iCaseSense, $iOccurence, $aEditSel[1]+$iOccurence)
                If Not $iPos Then
                    $iPos = StringInStr($sContent, $sFindString, $iCaseSense, $iOccurence, $iWrapPos)
                    If Not $iPos Then Return MsgBox(0x2040, $APP_NAME & ' - Notice', 'Cannot find "' & $sFindString & '"', 0, $g_hGUIFind)
                EndIf
                _GUICtrlEdit_SetSel($ed_Content, $iPos-1, $iPos-1+StringLen($sFindString))
            EndIf

            _GUICtrlEdit_Scroll($ed_Content, $SB_SCROLLCARET)
        Case $bt_FindReplaceAll
            Local $sContent = GUICtrlRead($ed_Content)
            Local $sFindString = GUICtrlRead($in_FindFind)
            If Not $sContent Or Not $sFindString Then Return

            Local $sReplaceContent, $iCaseSense = 0
            If BitAND(GUICtrlRead($ch_FindCase), $GUI_CHECKED) Then $iCaseSense = 1

            Local $sReplaceString = GUICtrlRead($in_FindReplace)
            If BitAND(GUICtrlRead($ch_FindEscape), $GUI_CHECKED) Then $sReplaceString = StringFormat(StringReplace($sReplaceString, '%', '%%'))

            If BitAND(GUICtrlRead($ch_FindRegEx), $GUI_CHECKED) Then
                $sReplaceContent = StringRegExpReplace($sContent, $sFindString, $sReplaceString)
            Else
                If BitAND(GUICtrlRead($ch_FindEscape), $GUI_CHECKED) Then $sFindString = StringFormat(StringReplace($sFindString, '%', '%%'))

                Local $sReplaceContent = StringReplace($sContent, $sFindString, $sReplaceString, 0, $iCaseSense)
            EndIf
            Local $iReplacements = @extended

            If $iReplacements = 0 Then
                MsgBox(0x2040, $APP_NAME & ' - Notice', '"' & $sFindString & '" not found.', 0, $g_hGUIFind)
            Else
                _GUICtrlEdit_SetSel($ed_Content, 0, -1)
                _GUICtrlEdit_ReplaceSel($ed_Content, $sReplaceContent, True)
                _GUICtrlEdit_SetSel($ed_Content, 0, -1)
                MsgBox(0x2040, $APP_NAME & ' - Notice', $iReplacements & ' replacements made.', 0, $g_hGUIFind)
            EndIf
        Case $mi_EditFind
            GUISetState(@SW_SHOW, $g_hGUIFind)
            ControlFocus($g_hGUIFind, '', $in_FindFind)
        Case $bt_FindClose, $GUI_EVENT_CLOSE
            GUISetState(@SW_HIDE, $g_hGUIFind)
            WinActivate($g_hGUIMain)
        Case $ch_FindRegEx
            If BitAND(GUICtrlRead($ch_FindRegEx), $GUI_CHECKED) Then
                GUICtrlSetState($ch_FindCase, $GUI_DISABLE)
            Else
                GUICtrlSetState($ch_FindCase, $GUI_ENABLE)
            EndIf
    EndSwitch
EndFunc

Func _CompileOptHandler()
EndFunc

Func _SnippetsHandler()
    Switch @GUI_CtrlId
        Case $mi_SnippetAdd
            Local $sContent, $aEditSel = _GUICtrlEdit_GetSel($ed_Content)
            If $aEditSel[0] <> $aEditSel[1] Then
                $sContent = StringMid(GUICtrlRead($ed_Content), $aEditSel[0] + 1, $aEditSel[1] - $aEditSel[0])
            EndIf
            If $sContent <> '' Then
                GUISetState(@SW_DISABLE, $g_hGUIMain)
                Opt('GUIOnEventMode', 0)
                Opt('GUICloseOnESC', 1)
                Local $hGUISnippetDialog = GUICreate($APP_NAME, 300, 135, Default, Default, BitOR($WS_CAPTION, $WS_SYSMENU), Default, $g_hGUIMain)
                GUICtrlCreateLabel('Selection will be added as new snippet.' & @LF & _
                    'Enter a name for the snippet you are saving.' & @LF & _
                    '* NOTE: If you use the name of an existing snippet it will be overwritten.', 10, 10, 280, 55)
                Local $cb_SnippetName = GUICtrlCreateCombo('', 10, 70, 280, 100)
                For $for = 1 to $g_aSnippetsData[0][0]
                    GUICtrlSetData($cb_SnippetName, $g_aSnippetsData[$for][0])
                Next

                Local $bt_OK = GUICtrlCreateButton('OK', 135, 100, 75, 25)
                    GUICtrlSetState(-1, $GUI_DEFBUTTON)
                Local $bt_Cancel = GUICtrlCreateButton('Cancel', 215, 100, 75, 25)
                GUISetState(@SW_SHOW, $hGUISnippetDialog)

                While 1
                    Local $iGUIMsg = GUIGetMsg()
                    Switch $iGUIMsg
                        Case $bt_OK
                            If GUICtrlRead($cb_SnippetName) Then
                                Local $sSnippetContent = _StringToFormat($sContent)
                                IniWrite($g_sIniFile, 'Snippets', GUICtrlRead($cb_SnippetName), $sSnippetContent)
                                _SnippetLoad()
                                ExitLoop
                            EndIf
                        Case $bt_Cancel, $GUI_EVENT_CLOSE
                            ExitLoop
                    EndSwitch
                WEnd
                GUIDelete($hGUISnippetDialog)
                Opt('GUICloseOnESC', 0)
                Opt('GUIOnEventMode', 1)
                GUISetState(@SW_ENABLE, $g_hGUIMain)
                WinActivate($g_hGUIMain)

            Else
                MsgBox(0x2030, $APP_NAME & ' - Notice', 'Please select the text you wish to add to snippets and try again.', 0, $g_hGUIMain)
            EndIf
        Case $mi_SnippetRemove
            GUISetState(@SW_DISABLE, $g_hGUIMain)
            Opt('GUIOnEventMode', 0)
            Opt('GUICloseOnESC', 1)
            Local $hGUISnippetDialog = GUICreate($APP_NAME, 300, 115, Default, Default, BitOR($WS_CAPTION, $WS_SYSMENU), Default, $g_hGUIMain)
            GUICtrlCreateLabel('Select the name of the snippet you wish to remove.' & @LF & '* NOTE: This operation cannot be undone.', 10, 10, 280, 35)
            Local $cb_SnippetName = GUICtrlCreateCombo('', 10, 50, 280, 100)
            For $for = 1 to $g_aSnippetsData[0][0]
                GUICtrlSetData($cb_SnippetName, $g_aSnippetsData[$for][0])
            Next

            Local $bt_OK = GUICtrlCreateButton('OK', 135, 80, 75, 25)
                GUICtrlSetState(-1, $GUI_DEFBUTTON)
            Local $bt_Cancel = GUICtrlCreateButton('Cancel', 215, 80, 75, 25)
            GUISetState(@SW_SHOW, $hGUISnippetDialog)

            While 1
                Local $iGUIMsg = GUIGetMsg()
                Switch $iGUIMsg
                    Case $bt_OK
                        If GUICtrlRead($cb_SnippetName) Then
                            IniDelete($g_sIniFile, 'Snippets', GUICtrlRead($cb_SnippetName))
                            _SnippetLoad()
                            ExitLoop
                        EndIf
                    Case $bt_Cancel, $GUI_EVENT_CLOSE
                        ExitLoop
                EndSwitch
            WEnd
            GUIDelete($hGUISnippetDialog)
            Opt('GUICloseOnESC', 0)
            Opt('GUIOnEventMode', 1)
            GUISetState(@SW_ENABLE, $g_hGUIMain)
            WinActivate($g_hGUIMain)
        Case $mi_SnippetRefresh
            _SnippetLoad()
        Case $mi_SnippetExport
            _SnippetLoad()
            Local $sFileName = _FileSaveDialog_WinAPI('Save as...', 'AutoIt3 script file (*.au3)(*.au3)|Text file (*.txt)(*.txt)|All Files (*.*)(*.*)', @WorkingDir, '', 'au3', 1, $OFN_OVERWRITEPROMPT, 0, $g_hGUIMain)
            If @error Then Return

            Local $sSnippetExport
            For $for = 1 to $g_aSnippetsData[0][0]
                $sSnippetExport &= '#region - Snippet: ' & $g_aSnippetsData[$for][0] & @CRLF & $g_aSnippetsData[$for][1] & @CRLF & '#endregion - Snippet: ' & $g_aSnippetsData[$for][0] & @CRLF & @CRLF & @CRLF & @CRLF
            Next

            If Not _FileSave($sFileName, StringStripWS($sSnippetExport, 3)) Then
                MsgBox(0x2030, $APP_NAME & ' - Notice', 'Cannot write to ' & $sFileName & @LF & 'Please make sure the file/path is not read only.', 0, $g_hGUIMain)
            EndIf

        Case $adm_SnippetKey[0] To $adm_SnippetKey[9]
            If BitAND(GUICtrlRead($me_Snippets), $GUI_DISABLE) Then Return
            For $for = 1 to $g_aSnippetsData[0][0]
                If @GUI_CtrlId = $adm_SnippetKey[Mod($for, 10)] Then
                    _GUICtrlEdit_ReplaceSel($ed_Content, $g_aSnippetsData[$for][1], True)
                    ExitLoop
                EndIf
            Next
        Case $g_aSnippetsMenuItems[1] to $g_aSnippetsMenuItems[$g_aSnippetsData[0][0]]
            For $for = 1 to $g_aSnippetsData[0][0]
                If @GUI_CtrlId = $g_aSnippetsMenuItems[$for] Then
                    _GUICtrlEdit_ReplaceSel($ed_Content, $g_aSnippetsData[$for][1], True)
                    ExitLoop
                EndIf
            Next
    EndSwitch
EndFunc
#endregion
;endregion - Main Handlers ----------------------------------------------------------------------------

#region - GUI Event Functions ----------------------------------------------------------------------------
Func _ScriptRun()
    If $g_iScriptPID Then
        If MsgBox(0x42024, $APP_NAME & ' - Confirm', 'Force the running script to close?', 0, $g_hGUIMain) = 6 Then
            ProcessClose($g_iScriptPID)
            If @error Then
                Local $aErrorVals[5] = [ '', 'OpenProcess failed.', 'AdjustTokenPrivileges failed.', 'TerminateProcess failed.', 'Cannot verify if process exists.' ]
                _GUICtrlEdit_AppendText($ed_Console, '>Script failed to terminate: ' & $aErrorVals[@error])
                Return 0
            Else
                _GUICtrlEdit_AppendText($ed_Console, '>Script terminated.')
                Return 1
            EndIf
        EndIf
        Return 0
    Else
        Local $sContent = GUICtrlRead($ed_Content)
        If $sContent <> '' Then
            $g_iRunTimer = TimerInit()
            GUICtrlSetData($ed_Console, '')

            Local $sRunFile
            If Not $g_sLoadedFile Or _GUICtrlEdit_GetModify($ed_Content) Then
                If $g_sLoadedFile Then
                    Local $aPathSplit = _PathSplitWrap($g_sLoadedFile)
                    $g_sLocalTempFile = _TempFile($aPathSplit[1] & $aPathSplit[2], $aPathSplit[3] & '~')
                Else
                    $g_sLocalTempFile = _TempFile(@TempDir, 'quickscript~')
                EndIf

                If Not _FileSave($g_sLocalTempFile, $sContent) Then Return MsgBox(0x2030, $APP_NAME & ' - Warning', 'Could not create temp file. (' & $g_sLocalTempFile & ')', 0, $g_hGUIMain)
                FileSetAttrib($g_sLocalTempFile, '+H')
                $sRunFile = $g_sLocalTempFile
            Else
                $sRunFile = $g_sLoadedFile
            EndIf

            Local $sParamsTemp, $sCmdPath, $sWorkDir, $iPID
            If @GUI_CtrlId = $mi_ScriptRunParams Then
                $sParamsTemp = InputBox('Parameters', 'Enter command line parameters to pass to your script:', $g_sRunParams, '', 400, 120, Default, Default, 0, $g_hGUIMain)
                If @error Then Return
                $g_sRunParams = $sParamsTemp
            EndIf

            $sCmdPath = '"' & @AutoItExe & '" /ErrorStdOut /AutoIt3ExecuteScript "' & $sRunFile & '" ' & $sParamsTemp
            $sWorkDir = StringRegExpReplace($sRunFile, '^(.*[/\\])[^\\/:\*\?"<>\|\t]*$', '\1')
            $iPID = Run($sCmdPath, $sWorkDir, @SW_HIDE, $STDERR_MERGED)
            If _ScriptRunTracker($g_iScriptPID, $iPID) Then
                If $sRunFile = $g_sLocalTempFile Or $sRunFile = $g_sGlobalTempFile Then
                    _GUICtrlEdit_AppendText($ed_Console, '>Script not saved. Using temp file.' & @CRLF)
                EndIf
                _GUICtrlEdit_AppendText($ed_Console, '>' & $sCmdPath & @CRLF)
                IniWrite($g_sIniFile, 'Config', 'LastRanFile', $sRunFile)
            Else
                _ToggleConsole($g_bShowConsole, True)
                _GUICtrlEdit_AppendText($ed_Console, '>Script execution failed.' & @CRLF & _
                    '> - Error:         ' & @error & @CRLF & _
                    '> - Command line:  ' & $sCmdPath & @CRLF & _
                    '> - Working dir:   ' & $sWorkDir)
            EndIf
        EndIf
    EndIf
EndFunc

Func _ScriptSave()
    Local $sFileName, $sContent = GUICtrlRead($ed_Content), $sStartDir = @WorkingDir, $sStartFile
    If $g_sLoadedFile And @GUI_CtrlId = $mi_FileSave Then
        $sFileName = $g_sLoadedFile
    Else
        If $g_sLoadedFile Then
            Local $aPathSplit = _PathSplitWrap($g_sLoadedFile)
            $sStartDir = $aPathSplit[1] & $aPathSplit[2]
            $sStartFile = $aPathSplit[3]
        EndIf

        Local $iFilterIndex = 1
        If @GUI_CtrlId = $mi_ScriptCompile Then $iFilterIndex = 2
        $sFileName = _FileSaveDialog_WinAPI('Save as...', 'AutoIt3 script file (*.au3)(*.au3)|Executable (*.exe)(*.exe)|Screen Saver (*.scr)(*.scr)|Encoded script file (*.a3x)(*.a3x)|All Files (*.*)(*.*)', $sStartDir, $sStartFile, 'au3', $iFilterIndex, $OFN_OVERWRITEPROMPT, 0, $g_hGUIMain)
        If @error Then Return

        Local $sFileExt = StringRight($sFileName, 3)
        If $sFileExt = 'exe' Or $sFileExt = 'scr' Or $sFileExt = 'a3x' Then
            Local $sScriptFile, $bTempFile
            GUISetState(@SW_DISABLE, $g_hGUIMain)
            Do
                If $g_sLoadedFile And Not _GUICtrlEdit_GetModify($ed_Content) Then
                    $sScriptFile = $g_sLoadedFile
                Else
                    If Not $sContent Then
                        MsgBox(0x2030, $APP_NAME & ' - Notice', 'No script to compile.', 0, $g_hGUIMain)
                        ExitLoop
                    Else
                        $sScriptFile = _TempFile(_PathSplitWrap($sFileName, 1+2))
                        $bTempFile = True
                        If Not _FileSave($sScriptFile, $sContent) Then
                            MsgBox(0x2010, $APP_NAME & ' - Error', 'Could not create temp file:' & @LF & $sScriptFile & @LF & 'Please try saving manually before compiling.', 0, $g_hGUIMain)
                            ExitLoop
                        EndIf
                    EndIf
                EndIf

                If $sFileExt = 'a3x' Then
                    _ScriptCompile($sScriptFile, $sFileName)
                Else
                    _ScriptCompileOptions($sScriptFile, $sFileName)
                EndIf
                If $bTempFile Then FileDelete($sScriptFile)
            Until 1
            GUISetState(@SW_ENABLE, $g_hGUIMain)
            WinActivate($g_hGUIMain)
            _AppSetTitle()
            Return
        EndIf
    EndIf

    If _FileSave($sFileName, $sContent) Then
        _SetLoadedFile($sFileName)
        Return 1
    Else
        MsgBox(0x2030, $APP_NAME & ' - Notice', 'Cannot write to ' & $sFileName & @LF & 'Please make sure the file/path is not read only.', 0, $g_hGUIMain)
        Return SetError(2, 0, 0)
    EndIf
EndFunc

Func _ScriptCompileOptions($sScriptFile, $sTargetFile)
    Opt('GUIOnEventMode', 0)
    Opt('GUICloseOnESC', 1)

    GUISetState(@SW_SHOW, $g_hGUICompile)
    Local $bCancel, $iComp, $bNoPack, $bX64, $bConsole, $sIcon
    While 1
        Local $aGUIMsg = GUIGetMsg(1)
        If $aGUIMsg[1] = $g_hGUICompile Then
            Switch $aGUIMsg[0]
                Case $bt_CompileIcon
                    $sIcon = FileOpenDialog('Choose icon', '', 'Icon files (*.ico)', 1, '', $g_hGUICompile)
                    If Not @error Then
                        GUICtrlSetData($in_CompileIcon, $sIcon)
                    EndIf
                Case $bt_CompileOK
                    $iComp = ControlCommand($g_hGUICompile, '', $cb_CompileCompress, 'FindString', _
                        ControlCommand($g_hGUICompile, '', $cb_CompileCompress, 'GetCurrentSelection'))
                    $bNoPack = BitAND(GUICtrlRead($ch_CompilePack), $GUI_CHECKED)
                    $bX64 = BitAND(GUICtrlRead($ch_Compile64), $GUI_CHECKED)
                    $bConsole = BitAND(GUICtrlRead($ch_CompileConsole), $GUI_CHECKED)
                    $sIcon = GUICtrlRead($in_CompileIcon)
                    If Not FileExists($sIcon) Then $sIcon = ''
                    ExitLoop
                Case $bt_CompileCancel, $GUI_EVENT_CLOSE
                    $bCancel = True
                    ExitLoop
            EndSwitch
        EndIf
    WEnd
    GUISetState(@SW_HIDE, $g_hGUICompile)
    Opt('GUIOnEventMode', 1)
    Opt('GUICloseOnESC', 0)

    If $bCancel Then
        Return 0
    Else
        _ScriptCompile($sScriptFile, $sTargetFile, $iComp, $bNoPack, $bX64, $bConsole, $sIcon)
    EndIf

EndFunc

Func _CompilerExport()
    Local $sExportFolder = FileSelectFolder('Compiler Export Directory', '', 1+2+4, @ScriptDir, $g_hGUIMain)
    If @error Then Return

    _CompilerGetFiles($sExportFolder)
    If @error Then
        MsgBox(0x2010, $APP_NAME & ' - Error', 'There was an error trying to extract the files, try another directory.', 0, $g_hGUIMain)
    Else
        If MsgBox(0x2044, $APP_NAME & ' - Success', 'The compiler files have been extracted. View files now?', 0, $g_hGUIMain) = 6 Then
            Run(@WindowsDir & '\explorer.exe "' & $sExportFolder & '"')
        EndIf
    EndIf
EndFunc

Func _FontSettings()
    Local $iItalic, $iUnderline, $iStrike
    Local $aFontSett, $sFontSett
    If @GUI_CtrlId = $mi_OptionsContentFont Then
        $aFontSett = $g_aContentFont
    Else
        $aFontSett = $g_aConsoleFont
    EndIf

    $iItalic = BitAND($aFontSett[$FONT_ATTS], 2)
    $iUnderline = BitAND($aFontSett[$FONT_ATTS], 4)
    $iStrike = BitAND($aFontSett[$FONT_ATTS], 8)
    $aFontSett = _ChooseFont($aFontSett[$FONT_NAME], $aFontSett[$FONT_SIZE], 0, _
        $aFontSett[$FONT_WEIGHT], $iItalic, $iUnderline, $iStrike, $g_hGUIMain)
    If Not IsArray($aFontSett) Then Return 0

    $sFontSett = $aFontSett[2] & '|' & $aFontSett[3] & '|' & $aFontSett[4] & '|' & $aFontSett[1]

    If @GUI_CtrlId = $mi_OptionsContentFont Then
        IniWrite($g_sIniFile, 'Config', 'ContentFont', $sFontSett)
        $g_aContentFont = StringSplit($sFontSett, '|')
        GUICtrlSetFont($ed_Lines, $g_aContentFont[$FONT_SIZE], $g_aContentFont[$FONT_WEIGHT], $g_aContentFont[$FONT_ATTS], $g_aContentFont[$FONT_NAME])
        GUICtrlSetFont($ed_Content, $g_aContentFont[$FONT_SIZE], $g_aContentFont[$FONT_WEIGHT], $g_aContentFont[$FONT_ATTS], $g_aContentFont[$FONT_NAME])
        _GUICtrlEdit_SetTabStops($ed_Content, $g_aTabStops4Letter)
        _GUICtrlEdit_SetMargins($ed_Content, $EC_LEFTMARGIN, 10)
    Else
        IniWrite($g_sIniFile, 'Config', 'ConsoleFont', $sFontSett)
        $g_aConsoleFont = StringSplit($sFontSett, '|')
        GUICtrlSetFont($ed_Console, $g_aConsoleFont[$FONT_SIZE], $g_aConsoleFont[$FONT_WEIGHT], $g_aConsoleFont[$FONT_ATTS], $g_aConsoleFont[$FONT_NAME])
        _GUICtrlEdit_SetTabStops($ed_Console, $g_aTabStops4Letter)
        _GUICtrlEdit_SetMargins($ed_Console, $EC_LEFTMARGIN, 10)
    EndIf
EndFunc

Func _HelpMenu()
    If @GUI_CtrlId = $mi_HelpAbout Then
        Local $sCompileMsg = 'You are running an uncompiled version of ' & $APP_NAME & ' v' & $APP_VERSION & @LF & 'with AutoIt version ' & $AUTOIT_VERSION & '.'
        If @Compiled Then
            $sCompileMsg = 'You are running a compiled version of ' & $APP_NAME & ' v' & $APP_VERSION & '.' & @LF & 'It was compiled with AutoIt version ' & $AUTOIT_VERSION & '.'
        EndIf
        MsgBox(0x2040, 'About ' & $APP_NAME, 'A simple, portable AutoIt3 editor/interpreter/compiler.' & @LF & _
            $sCompileMsg & @LF & @LF & _
            'Written by Rob Saunders <rob@therks.com>' & @LF & _
            'Written with the AutoIt3 language <www.autoit3.com>' & @LF & @LF & _
            'Choose Help > View ReadMe for more details.', 0, $g_hGUIMain)
    ElseIf @GUI_CtrlId = $mi_HelpDocs Then
        ShellExecute('http://www.autoitscript.com/autoit3/docs/')
    Else
        If @GUI_CtrlId = $mi_HelpReadMe Then
            ShellExecute($g_sReadMePath)
        Else
            ShellExecute($g_sSourcePath)
        EndIf
    EndIf
EndFunc

Func _CtrlBackspace()
    Local Enum $SEL_LEFT

    Local $hFocusCtrl = _WinAPI_GetFocus()
    Local $sFocusClass = _WinAPI_GetClassName($hFocusCtrl)
    If $sFocusClass <> 'Edit' Then Return

    Local $sContent = _GUICtrlEdit_GetText($hFocusCtrl)
    Local $aSelection = _GUICtrlEdit_GetSelByAnchor($hFocusCtrl)

    Local $iWordJump = _WordSearchJump($sContent, $aSelection[1], $SEL_LEFT, $g_sWordChars)
    Local $iDifference = $aSelection[1] - $iWordJump

    _GUICtrlEdit_BeginUpdate($hFocusCtrl)
    _GUICtrlEdit_SetSel($hFocusCtrl, $aSelection[1], $iWordJump)
    _GUICtrlEdit_ReplaceSel($hFocusCtrl, '', True)
    _GUICtrlEdit_SetSel($hFocusCtrl, $aSelection[0] - $iDifference, $iWordJump)
    _GUICtrlEdit_EndUpdate($hFocusCtrl)
EndFunc

Func _MoveCaretByWord()
    Local Enum $SEL_LEFT, $SEL_RIGHT

    Local $hFocusCtrl = _WinAPI_GetFocus()
    Local $sFocusClass = _WinAPI_GetClassName($hFocusCtrl)
    If $sFocusClass <> 'Edit' Then Return

    Local $sContent = _GUICtrlEdit_GetText($hFocusCtrl)
    Local $iSelectJump, $aSelection = _GUICtrlEdit_GetSelByAnchor($hFocusCtrl)

    Switch @GUI_CtrlId
        Case $dm_AccelWordLeft
            $iSelectJump = _WordSearchJump($sContent, $aSelection[1], $SEL_LEFT, $g_sWordChars)
            _GUICtrlEdit_SetSel($hFocusCtrl, $iSelectJump, $iSelectJump)
        Case $dm_AccelWordRight
            $iSelectJump = _WordSearchJump($sContent, $aSelection[1], $SEL_RIGHT, $g_sWordChars)
            _GUICtrlEdit_SetSel($hFocusCtrl, $iSelectJump, $iSelectJump)
        Case $dm_AccelWordShiftLeft
            $iSelectJump = _WordSearchJump($sContent, $aSelection[1], $SEL_LEFT, $g_sWordChars)
            _GUICtrlEdit_SetSel($hFocusCtrl, $aSelection[0], $iSelectJump)
        Case $dm_AccelWordShiftRight
            $iSelectJump = _WordSearchJump($sContent, $aSelection[1], $SEL_RIGHT, $g_sWordChars)
            _GUICtrlEdit_SetSel($hFocusCtrl, $aSelection[0], $iSelectJump)
    EndSwitch

    _GUICtrlEdit_Scroll($hFocusCtrl, $SB_SCROLLCARET)
EndFunc
#endregion
;endregion - GUI Event Functions ----------------------------------------------------------------------------

#region - Main Functions ----------------------------------------------------------------------------
Func _ScriptRunTracker(ByRef $iPID, $iSetPID = 0)
    If Not $iPID Then
        If $iSetPID Then
            $iPID = $iSetPID
            GUICtrlSetState($me_File, $GUI_DISABLE)
            GUICtrlSetState($me_Edit, $GUI_DISABLE)
            GUICtrlSetState($me_Snippets, $GUI_DISABLE)
            GUICtrlSetState($me_Options, $GUI_DISABLE)
            GUICtrlSetState($mi_ScriptCompile, $GUI_DISABLE)

            GUICtrlSetState($mi_ScriptRun, $GUI_DISABLE)
            GUICtrlSetState($mi_ScriptRunParams, $GUI_DISABLE)
            GUICtrlSetState($mi_ScriptStop, $GUI_ENABLE)
            GUICtrlSetState($mi_ScriptDetach, $GUI_ENABLE)

            GUICtrlSetStyle($ed_Content, BitOR($GUI_SS_DEFAULT_EDIT, $ES_NOHIDESEL, $ES_READONLY))
        EndIf
    Else
        Local $sStdoutRead = StdoutRead($iPID)
        If Not @error Then
            If @extended Then
                _ToggleConsole($g_bShowConsole, True)
;~              _GUICtrlEdit_AppendText($ed_Console, StringRegExpReplace($sStdoutRead, '([^\r])\n', '\1' & @CRLF))
                _GUICtrlEdit_AppendText($ed_Console, StringAddCR(StringReplace(StringReplace($sStdoutRead, @CRLF, @LF), @CR, @LF)))
            EndIf
            If Not ProcessExists($iPID) Then StdioClose($iPID)

            If $iSetPID = -1 Then
                StdioClose($iPID)
                _GUICtrlEdit_AppendText($ed_Console, '>Script process detached.')
            EndIf
        Else
            $iPID = 0
            _GUICtrlEdit_AppendText($ed_Console, @CRLF & '>Run time: ' & Round(TimerDiff($g_iRunTimer) / 1000, 3) & 's')
            GUICtrlSetState($me_File, $GUI_ENABLE)
            GUICtrlSetState($me_Edit, $GUI_ENABLE)
            GUICtrlSetState($me_Snippets, $GUI_ENABLE)
            GUICtrlSetState($me_Options, $GUI_ENABLE)
            GUICtrlSetState($mi_ScriptCompile, $GUI_ENABLE)

            GUICtrlSetState($mi_ScriptRun, $GUI_ENABLE)
            GUICtrlSetState($mi_ScriptRunParams, $GUI_ENABLE)
            GUICtrlSetState($mi_ScriptStop, $GUI_DISABLE)
            GUICtrlSetState($mi_ScriptDetach, $GUI_DISABLE)

            GUICtrlSetStyle($ed_Content, BitOR($GUI_SS_DEFAULT_EDIT, $ES_NOHIDESEL))

            ControlFocus($g_hGUIFrameTop, '', $ed_Content)
            If $g_sLocalTempFile And FileExists($g_sLocalTempFile) Then
                FileDelete($g_sLocalTempFile)
                $g_sLocalTempFile = ''
            EndIf
        EndIf
    EndIf

    Return $iPID
EndFunc

Func _SnippetLoad()
    Global $g_aSnippetsData = IniReadSection($g_sIniFile, 'Snippets')
    If @error Then
        Global $g_aSnippetsData[1][1] = [ [ 0 ] ]
        GUICtrlSetState($me_SnippetInsert, $GUI_DISABLE)
        GUICtrlSetState($mi_SnippetRemove, $GUI_DISABLE)
    Else
        GUICtrlSetState($me_SnippetInsert, $GUI_ENABLE)
        GUICtrlSetState($mi_SnippetRemove, $GUI_ENABLE)
    EndIf

    If $g_aSnippetsMenuItems[0] > 0 Then
        For $for = 1 to $g_aSnippetsMenuItems[0]
            GUICtrlDelete($g_aSnippetsMenuItems[$for])
        Next
    EndIf
    Global $g_aSnippetsMenuItems[$g_aSnippetsData[0][0] + 1] = [ $g_aSnippetsData[0][0] ]
    Local $sHotKeyTip
    For $for = 1 to $g_aSnippetsData[0][0]
        $sHotKeyTip = ''
        If $for <= 10 Then
            $sHotKeyTip = @TAB & 'Ctrl+' & Mod($for, 10)
        EndIf
        $g_aSnippetsData[$for][1] = StringFormat(StringReplace($g_aSnippetsData[$for][1], '%', '%%'))
        $g_aSnippetsData[$for][1] = StringAddCR(StringStripCR($g_aSnippetsData[$for][1]))
        $g_aSnippetsMenuItems[$for] = GUICtrlCreateMenuItem($g_aSnippetsData[$for][0] & $sHotKeyTip, $me_SnippetInsert)
        GUICtrlSetOnEvent($g_aSnippetsMenuItems[$for], '_SnippetsHandler')
    Next
EndFunc

Func _WordSearchJump(ByRef $sText, $iPosition, $iDirection = 0, $g_sWordChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
    Local $iInString, $bOnWord, $bOnWS

    If $iDirection Then $iPosition += 1
    Local $sChar, $sCharType = __WordSearchJump__GetCharType(StringMid($sText, $iPosition, 1), $g_sWordChars)

    If $iDirection Then
        For $for = $iPosition to StringLen($sText)
            $sChar = __WordSearchJump__GetCharType(StringMid($sText, $for, 1), $g_sWordChars)
            If $sChar <> $sCharType Then
                If $sChar = 'SPC' Then
                    Do
                        $for += 1
                        $sChar = __WordSearchJump__GetCharType(StringMid($sText, $for, 1), $g_sWordChars)
                    Until @error Or $sChar <> 'SPC'
                EndIf
                ExitLoop
            EndIf
        Next
        Return $for-1
    Else
        For $for = $iPosition to 1 Step -1
            $sChar = __WordSearchJump__GetCharType(StringMid($sText, $for, 1), $g_sWordChars)
            If $sChar <> $sCharType Then
                If $sCharType = 'SPC' Then
                    $sCharType = __WordSearchJump__GetCharType(StringMid($sText, $for, 1), $g_sWordChars)
                    Do
                        $for -= 1
                        $sChar = __WordSearchJump__GetCharType(StringMid($sText, $for, 1), $g_sWordChars)
                    Until @error Or $sChar <> $sCharType
                EndIf
                ExitLoop
            EndIf
        Next
        Return $for
    EndIf
EndFunc

Func __WordSearchJump__GetCharType($sChar, ByRef $g_sWordChars)
    If $sChar = '' Then Return SetError(1)
    Local $sCharType = 'PNC' ; Punctuation
    If StringRegExp($sChar, '\h') Then $sCharType = 'SPC' ; Space
    If StringRegExp($sChar, '\v') Then $sCharType = 'BRK' ; Line Break (Vertical space)
    If StringInStr($g_sWordChars, $sChar, 1) Then $sCharType = 'WRD' ; Word
    Return $sCharType
EndFunc

Func _ToggleConsole(ByRef $g_bShowConsole, $bForce = Default)
    Local $aClient = WinGetClientSize($g_hGUIMain)

    If $bForce = Default Then
        $g_bShowConsole = Not $g_bShowConsole
    Else
        $g_bShowConsole = $bForce
    EndIf

    If $g_bShowConsole Then
        $g_bIgnore_WM_MOVE = False
        Local $aSizerPos = ControlGetPos($g_hGUIMain, '', $lb_SizerFrame)
        GUISetState(@SW_SHOWNA, $g_hGUIFrameBot)
        GUISetState(@SW_SHOWNA, $g_hGUIFrameSize)
        GUICtrlSetPos($lb_ContentFrame, 0, 0, $aClient[0], $aSizerPos[1])
        GUICtrlSetState($mi_ViewConsole, $GUI_CHECKED)
    Else
        $g_bIgnore_WM_MOVE = True
        GUICtrlSetPos($lb_ContentFrame, 0, 0, $aClient[0], $aClient[1] - 20)
        GUISetState(@SW_HIDE, $g_hGUIFrameBot)
        GUISetState(@SW_HIDE, $g_hGUIFrameSize)
        ControlFocus($g_hGUIMain, '', $ed_Content)
        GUICtrlSetState($mi_ViewConsole, $GUI_UNCHECKED)

        $g_bAlwaysShowConsole = False
        GUICtrlSetState($mi_ViewConsoleAlways, $GUI_UNCHECKED)
    EndIf
EndFunc

Func _ToggleLines(ByRef $g_bShowLines, $bForce = Default)
    Local $aClient = WinGetClientSize($g_hGUIMain)

    If $bForce = Default Then
        $g_bShowLines = Not $g_bShowLines
    Else
        $g_bShowLines = $bForce
    EndIf

    If $g_bShowLines Then
        Local $aSizerPos = ControlGetPos($g_hGUIFrameTop, '', $ed_Content)
        GUICtrlSetPos($ed_Content, 50, 0, $aClient[0]-50, Default)
        GUICtrlSetState($ed_Lines, $GUI_SHOW)
        GUICtrlSetState($mi_ViewLines, $GUI_CHECKED)
    Else
        GUICtrlSetState($ed_Lines, $GUI_HIDE)
        Local $aSizerPos = ControlGetPos($g_hGUIFrameTop, '', $ed_Content)
        GUICtrlSetPos($ed_Content, 0, 0, $aClient[0], Default)
        GUICtrlSetState($mi_ViewLines, $GUI_UNCHECKED)
    EndIf
EndFunc

Func _GoTo($iLine, $iCol = 0)
    $iCol -= 1
    If $iCol < 1 Then $iCol = 0
    ControlFocus($g_hGUIMain, '', $ed_Content)
    Local $iLineCount = _GUICtrlEdit_GetLineCount($ed_Content)
    If $iLine > $iLineCount Then $iLine = $iLineCount

    Local $iLineLen = _GUICtrlEdit_LineLength($ed_Content, $iLine-1)

    If $iCol > $iLineLen Then $iCol = $iLineLen
    Local $iGoTo = _GUICtrlEdit_LineIndex($ed_Content, $iLine-1) + $iCol
    _GUICtrlEdit_SetSel($ed_Content, $iGoTo, $iGoTo)
    _GUICtrlEdit_Scroll($ed_Content, $SB_SCROLLCARET)
EndFunc

Func _LoadFileContents($sFile)
    Local $hFile = FileOpen($sFile, 0)
    If $hFile <> -1 Then
        Local $sContent = FileRead($hFile)
        FileClose($hFile)
        GUICtrlSetData($ed_Content, $sContent)
        _SetLoadedFile($sFile)
        Return 1
    Else
        MsgBox(0x2030, $APP_NAME & ' - Notice', 'Unable to load file:' & @LF & $sFile, 0, $g_hGUIMain)
        Return SetError(1, 0, 0)
    EndIf
EndFunc

Func _SetLoadedFile($sFile)
    Global $g_sLoadedFile = $sFile
    If $g_sLocalTempFile And FileExists($g_sLocalTempFile) Then
        FileDelete($g_sLocalTempFile)
        Global $g_sLocalTempFile = ''
    EndIf
    IniWrite($g_sIniFile, 'Config', 'LastFile', $g_sLoadedFile)

    _GUICtrlEdit_SetModify($ed_Content, False)
    _AppSetTitle()
EndFunc

Func _AppSetTitle($sTitle = Default)
    If $sTitle = Default Then
        $sTitle = $APP_TITLE

        If Not $g_sLoadedFile Then
            $sTitle &= ' - Untitled'
        Else
            $sTitle &= ' - ' & $g_sLoadedFile
        EndIf

        If _GUICtrlEdit_GetModify($ed_Content) Then
            $sTitle &= ' *'
        EndIf
    EndIf

    Local $sCheckTitle = WinGetTitle($g_hGUIMain)
    If Not ($sCheckTitle == $sTitle) Then WinSetTitle($g_hGUIMain, '', $sTitle)
EndFunc

Func _SaveChangesPrompt()
    If _GUICtrlEdit_GetModify($ed_Content) Then
        Local $sAskSaveText = '"' & $g_sLoadedFile & '"'
        If Not $g_sLoadedFile Then $sAskSaveText = '(Untitled)'

        Local $iExtended
        $g_iMsgBox = MsgBox(0x2223, $APP_NAME & ' - Confirm', 'Save changes to ' & $sAskSaveText & '?', 0, $g_hGUIMain)
        If $g_iMsgBox = 6 Then $iExtended = 1 ; Yes
        If $g_iMsgBox = 7 Then $iExtended = 0 ; No
        If $g_iMsgBox = 2 Then $iExtended = -1 ; Cancel
        Return SetExtended($iExtended, 1)
    Else
        Return 0
    EndIf
EndFunc

Func _OnAutoItExit()
    IniWrite($g_sIniFile, 'Config', 'ShowLines', $g_bShowLines)
    IniWrite($g_sIniFile, 'Config', 'ShowConsole', $g_bAlwaysShowConsole)

    IniWrite($g_sIniFile, 'Config', 'TabSize', $g_iTabSize)
    If IsArray($g_aSaveWinPos) And UBound($g_aSaveWinPos) >= 3 Then
        IniWrite($g_sIniFile, 'Config', 'LastWinPos', $g_aSaveWinPos[0] & '|' & $g_aSaveWinPos[1] & '|' & $g_aSaveWinPos[2] & '|' & $g_aSaveWinPos[3])
    EndIf
    IniWrite($g_sIniFile, 'Config', 'FindMem', GUICtrlRead($in_FindFind))
    IniWrite($g_sIniFile, 'Config', 'ReplaceMem', GUICtrlRead($in_FindReplace))

    GUIDelete($g_hGUIMain)
    GUIDelete($g_hGUIFrameTop)
    GUIDelete($g_hGUIFrameSize)
    GUIDelete($g_hGUIFrameBot)
    IniWrite($g_sIniFile, 'Config', 'FirstRun', False)

    FileDelete($g_sLocalTempFile)
    FileDelete($g_sSourcePath)
    FileDelete($g_sReadMePath)
EndFunc

Func _MakeReadMe($sSourcePath, $sReadMePath)
    Local $bPrint, $sLine, $hFile = FileOpen($sSourcePath, 0), $hWrite = FileOpen($sReadMePath, 2)
    If $hFile <> -1 And $hWrite <> -1 Then
        Do
            $sLine = FileReadLine($hFile)
            If StringInStr($sLine, '=====README=====') Then
                If $bPrint = 1 Then ExitLoop
                $bPrint = 1
                ContinueLoop
            ElseIf $bPrint Then
                FileWrite($hWrite, StringReplace($sLine, @TAB, '    ') & @CRLF)
            EndIf
        Until False
        FileClose($hWrite)
        FileClose($hFile)
        Return True
    Else
        Return False
    EndIf
EndFunc

Func _PreviousInstance()
    Opt('WinTitleMatchMode', 3)
    WinActivate(HWnd(ControlGetText($SINGLETON, '', 1))) ; Look for the AutoIt window with $SINGLETON as title
    ConsoleWrite(ControlGetText($SINGLETON, '', 1) & @CRLF)
    If $g_CmdLine[0] And FileExists($g_CmdLine[1]) Then ControlSetText($SINGLETON, '', 1, $g_CmdLine[1])
    Exit 2
EndFunc

#endregion
;endregion - Main Functions ----------------------------------------------------------------------------

#region - Compiler Functions ----------------------------------------------------------------------------
Func _CompilerFilesCheckCopy()
    If @Compiled Then Return

    Local $aCopyFiles[] = [ 'Aut2exe.exe', 'upx.exe' ]
    Local $sCompilerPath = _PathSplitWrap(@AutoItExe, 1+2) & 'Aut2Exe\'
    Local $sV1, $sV2
    ConsoleWrite('>_CompilerFilesCheckCopy()' & @CRLF)
    If FileExists($sCompilerPath) Then
        For $i = 0 To UBound($aCopyFiles)-1
            If FileExists($sCompilerPath & $aCopyFiles[$i]) Then
                If FileExists(@ScriptDir & '\CompilerFiles\' & $aCopyFiles[$i]) Then
                    $sV1 = FileGetVersion($sCompilerPath & $aCopyFiles[$i])
                    $sV2 = FileGetVersion(@ScriptDir & '\CompilerFiles\' & $aCopyFiles[$i])
                    If _VersionCompare($sV1, $sV2) = 1 Then
                        ConsoleWrite('+ Copying ' & $aCopyFiles[$i] & '. Versions: ' & $sV1 & ' > ' & $sV2 & @CRLF)
                        FileCopy($sCompilerPath & $aCopyFiles[$i], @ScriptDir & '\CompilerFiles\' & $aCopyFiles[$i], 1+8)
                    Else
                        If $sV1 == $sV2 Then
                            ConsoleWrite('>' & $aCopyFiles[$i] & ' file versions match: ' & $sV1 & @CRLF)
                        Else
                            ConsoleWrite('>' & $aCopyFiles[$i] & ' local file is more recent. Versions: ' & $sV1 & ' < ' & $sV2 & @CRLF)
                        EndIf
                    EndIf
                Else
                    ConsoleWrite('>Copying ' & $aCopyFiles[$i] & '. File did not exist.' & @CRLF)
                    FileCopy($sCompilerPath & $aCopyFiles[$i], @ScriptDir & '\CompilerFiles\' & $aCopyFiles[$i], 8)
                EndIf
            Else
                ConsoleWrite('- File not found: ' & $sCompilerPath & $aCopyFiles[$i] & @CRLF)
            EndIf
        Next
    Else
        ConsoleWrite('- Folder not found: ' & $sCompilerPath & @CRLF)
    EndIf
EndFunc

Func _CompilerGetFiles($sFolder = Default)
    Local $aFiles[$COMPILER_UBOUND], $sFileOut, $bComplete

    If $sFolder = Default Then
        $sFolder = _TempFile(@TempDir, '~', '')
        If Not DirCreate($sFolder) Then Return SetError(1, 0, '')
        $aFiles[$COMPILER_FOLDER] = $sFolder ; TempDir flag

        $sFileOut = $sFolder & '\!DO NOT PLACE FILES HERE - THIS IS A TEMPORARY FOLDER!.txt'
        FileWrite($sFileOut, 'You have been warned.')
        $aFiles[$COMPILER_FOLDERWARN] = $sFileOut
    EndIf

    Do
        $sFileOut = $sFolder & '\Aut2exe.exe'
        If Not FileInstall('CompilerFiles\Aut2exe.exe', $sFileOut, 1) Then ExitLoop
        $aFiles[$COMPILER_EXE] = $sFileOut

        $sFileOut = $sFolder & '\upx.exe'
        If Not FileInstall('CompilerFiles\upx.exe', $sFileOut, 1) Then ExitLoop
        $aFiles[$COMPILER_UPX] = $sFileOut

        $bComplete = True
    Until 1

    If Not $bComplete Then
        _CompilerCleanup($aFiles)
        Return SetError(1, 0, '')
    EndIf
    Return $aFiles
EndFunc

Func _CompilerCleanup(ByRef $aFiles)
    If Not UBound($aFiles) = $COMPILER_UBOUND Then Return
    For $for = $COMPILER_FOLDER+1 To $COMPILER_UBOUND-1
        If $aFiles[$for] Then FileDelete($aFiles[$for])
    Next
    If $aFiles[$COMPILER_FOLDER] Then DirRemove($aFiles[$COMPILER_FOLDER])
EndFunc

Func _ScriptCompile($sScriptFile, $sTargetFile, $iComp = 0, $bNoPack = 0, $bX64 = 0, $bConsole = 0, $sIcon = '')
    _AppSetTitle('Compiling script...')
    GUICtrlSetData($lb_CompileStatus, 'Extracting compiler files...')
    GUISetState(@SW_SHOW, $g_hGUICompileStatus)

    Local $sAut2ExePath, $sUPXPath, $aCompilerFiles
    Do
        If @Compiled Then
            $aCompilerFiles = _CompilerGetFiles()
            If @error Then
                MsgBox(0x42030, $APP_NAME & ' - Notice', 'Unable to extract compiler files.', 0, $g_hGUICompileStatus)
                ExitLoop
            EndIf
            $sAut2ExePath = $aCompilerFiles[$COMPILER_EXE]
            $sUPXPath = $aCompilerFiles[$COMPILER_UPX]
        Else
            $sAut2ExePath = _PathSplitWrap(@AutoItExe, 1+2) & 'Aut2Exe\Aut2Exe.exe'
            If Not FileExists($sAut2ExePath) Then
                MsgBox(0x42030, $APP_NAME & ' - Notice', 'Unable to find compiler. File does not exist at expected location:' & @LF & $sAut2ExePath, 0, $g_hGUICompileStatus)
                ExitLoop
            EndIf
            $sUPXPath = _PathSplitWrap(@AutoItExe, 1+2) & 'Aut2Exe\upx.exe'
            If Not FileExists($sUPXPath) Then
                MsgBox(0x42030, $APP_NAME & ' - Notice', 'Unable to find UPX.exe. File does not exist at expected location:' & @LF & $sUPXPath, 0, $g_hGUICompileStatus)
                ExitLoop
            EndIf
        EndIf

        Local $sCmdOptions = '/comp ' & $iComp & ' '
        If $sIcon Then $sCmdOptions &= '/icon "' & $sIcon & '" '
        If $bNoPack Then $sCmdOptions &= '/nopack '
        If $bConsole Then $sCmdOptions &= '/console '
        If $bX64 Then $sCmdOptions &= '/x64'

        Local $sCompileCmd = StringFormat('"%s" /in "%s" /out "%s" %s', $sAut2ExePath, $sScriptFile, $sTargetFile, $sCmdOptions)
        Local $iCompilePID = Run($sCompileCmd)
        Local $iCompileTimer = TimerInit(), $bCompileSuccess = True

        If $iCompilePID Then
            While ProcessExists($iCompilePID)
                GUICtrlSetData($lb_CompileStatus, 'Compiling... Time elapsed: ' & Round(TimerDiff($iCompileTimer) / 1000, 2) & 's')

                If WinExists('Aut2Exe Error') Then
                    If WinGetProcess('[LAST]') = $iCompilePID Then
                        $bCompileSuccess = False
                        ExitLoop
                    EndIf
                EndIf
                Sleep(50)
            WEnd
            If $bCompileSuccess Then
                If Not $bNoPack Then
                    ; Manually packing in case Aut2exe "forgets"
                    Local $iCompilePID = Run(StringFormat('"%s" -9 "%s"', $sUPXPath, $sScriptFile))
                    While ProcessExists($iCompilePID)
                        GUICtrlSetData($lb_CompileStatus, 'Packing... Time elapsed: ' & Round(TimerDiff($iCompileTimer) / 1000, 2) & 's')
                        Sleep(50)
                    WEnd
                EndIf

                If MsgBox(0x42144, $APP_NAME & ' - Compile', 'Compile completed. View file?', 0, $g_hGUICompileStatus) = 6 Then
                    Run(@WindowsDir & '\explorer.exe /select,"' & $sTargetFile & '"')
                EndIf
            EndIf
        Else
            MsgBox(0x42010, $APP_NAME & ' - Error', 'Error starting compiler.' & @LF & 'Command line: ' & $sCompileCmd, 0, $g_hGUIMain)
        EndIf

        GUICtrlSetData($lb_CompileStatus, 'Cleaning up compiler files...')

    Until 1
    _CompilerCleanup($aCompilerFiles)

    GUISetState(@SW_HIDE, $g_hGUICompileStatus)
EndFunc

#endregion
;endregion - Compiler Functions ----------------------------------------------------------------------------

#region - Utility Functions ----------------------------------------------------------------------------
Func _GUICtrlEdit_GetSelByAnchor($hWnd)
    Local $aActive, $aSelection = _GUICtrlEdit_GetSel($hWnd)
    If $aSelection[0] = $aSelection[1] Then Return $aSelection
    _GUICtrlEdit_SetSel($hWnd, -1, 0)
    $aActive = _GUICtrlEdit_GetSel($hWnd)
    If $aActive[0] = $aSelection[0] Then
        $aSelection[0] = $aSelection[1]
        $aSelection[1] = $aActive[0]
    EndIf
    _GUICtrlEdit_SetSel($hWnd, $aSelection[0], $aSelection[1])
    Return $aSelection
EndFunc

Func _StringEnvEval($sString)
    Local $iOpt = Opt('ExpandEnvStrings', 1)
    Local $sOut = $sString
    Opt('ExpandEnvStrings', $iOpt)
    Return $sOut
EndFunc

Func _PathSplitWrap($sFilePath, $iBits = 0)
    Local $n, $aParts = _PathSplit($sFilePath, $n, $n, $n, $n)
    If Not $iBits Then
        Return $aParts
    Else
        Local $sReturn
        For $for = 1 To 4
            If BitAND($iBits, 2^($for-1)) Then $sReturn &= $aParts[$for]
        Next
        Return $sReturn
    EndIf
EndFunc

Func _IniReadWrap($sFile, $sSection, $sKey, $sDefault = '', $bPreserveQuotes = False)
    If $bPreserveQuotes Then
        Local $aIniSection = IniReadSection($sFile, $sSection)
        If Not @error Then
            For $for = 1 To $aIniSection[0][0]
                If $aIniSection[$for][0] = $sKey Then
                    Return $aIniSection[$for][1]
                EndIf
            Next
        EndIf
    Else
        Local $sIniRead = IniRead($sFile, $sSection, $sKey, @LF)
        If $sIniRead <> @LF Then Return $sIniRead
    EndIf
    Return SetError(1, 0, $sDefault)
EndFunc

Func _StringToFormat($sString)
    $sString = StringReplace($sString, '\', '\')
    $sString = StringReplace($sString, @CR, '')
    $sString = StringReplace($sString, @LF, '\n')
    $sString = StringReplace($sString, @TAB, '\t')
    Return $sString
EndFunc

Func _FileSave($sFile, $sContent = '')
    Local $hFile = FileOpen($sFile, 2+8)
    If $hFile <> -1 Then
        FileWrite($hFile, $sContent)
        FileClose($hFile)
        Return True
    EndIf
    Return False
EndFunc

Func _FileIsWritable($sFile, $bCreate = False)
    Local $hFile
    If Not FileExists($sFile) Then
        If $bCreate Then
            $hFile = FileOpen($sFile, 2+8)
            If $hFile <> -1 Then
                FileClose($hFile)
                Return SetExtended(1, True)
            Else
                Return SetError(1, 0, False)
            EndIf
        EndIf
        Return SetError(2, 0, False)
    Else
        $hFile = FileOpen($sFile, 1)
        If $hFile <> -1 Then
            FileClose($hFile)
            Return True
        EndIf
    EndIf
    Return SetError(3, 0, False)
EndFunc

Func _IniFilePreference()
    Local $sLocal = @ScriptDir & '\' & $APP_NAME & '.ini'
    Local $sUser = @AppDataDir & '\' & $APP_NAME & '.ini'
    If FileExists($sLocal) Then
        If Not IniWrite($sLocal, 'Config', 'ConfigTest', 1) Then
            $g_iMsgBox = MsgBox(0x31, $APP_NAME & ' - Warning', 'Portable mode unavailable: Unable to write to config file.' & @LF & _
                'To disable this message enable write permission to this folder: ' & @ScriptDir & @LF & _
                'Or delete this file: ' & $sLocal)
            If $g_iMsgBox = 2 Then Exit
            Return $sUser
        EndIf
        Return SetExtended(1, $sLocal)
    EndIf
    Return $sUser
EndFunc
#endregion
;endregion - Utility Functions ----------------------------------------------------------------------------

#region - Window Message Functions ----------------------------------------------------------------------------
Func WM_SIZE($hWnd, $iMsg, $iWParam, $iLParam)
    If $hWnd = $g_hGUIMain Then
        If Not BitAND(WinGetState($g_hGUIMain), 16 + 32) Then
            $g_aSaveWinPos = WinGetPos($g_hGUIMain)
        EndIf
    EndIf
EndFunc

Func WM_MOVE($hWnd, $iMsg, $iWParam, $iLParam)
    If $g_bIgnore_WM_MOVE Then Return $GUI_RUNDEFMSG

    If $hWnd = $g_hGUIMain Then
        If Not BitAND(WinGetState($g_hGUIMain), 16 + 32) Then
            $g_aSaveWinPos = WinGetPos($g_hGUIMain)
        EndIf
    ElseIf $hWnd = $g_hGUIFrameSize Then
        Local $aClient, $iYPos, $iTopEdge, $iBottomEdge
        $aClient = WinGetClientSize($g_hGUIMain)
        $iYPos = BitShift($iLParam, 16)
        $iTopEdge = $SIZER_TOPLIMIT
        $iBottomEdge = $aClient[1] - $SIZER_BOTTOMLIMIT
        If $iYPos <= $iTopEdge Then $iYPos = $iTopEdge
        If $iYPos >= $iBottomEdge Then $iYPos = $iBottomEdge

        WinMove($g_hGUIFrameSize, '', 0, $iYPos, $aClient[0], $SIZER_HEIGHT)
        GUICtrlSetPos($lb_SizerFrame, 0, $iYPos, $aClient[0], $SIZER_HEIGHT)
        GUICtrlSetPos($lb_ContentFrame, 0, 0, $aClient[0], $iYPos)
        GUICtrlSetPos($lb_ConsoleFrame, 0, $iYPos + $SIZER_HEIGHT, $aClient[0], $aClient[1] - $SIZER_HEIGHT - $STATBAR_HEIGHT - $iYPos)
    EndIf
EndFunc

Func WM_PAINT($hWnd = 0, $iMsg = 0)
    If $hWnd = $g_hGUIMain Then
        WM_PAINT_Helper($g_hGUIMain, $lb_ContentFrame, $g_hGUIFrameTop)
        If $g_bShowConsole Then
            WM_PAINT_Helper($g_hGUIMain, $lb_SizerFrame, $g_hGUIFrameSize)
            WM_PAINT_Helper($g_hGUIMain, $lb_ConsoleFrame, $g_hGUIFrameBot)
        EndIf
    EndIf
EndFunc

Func WM_PAINT_Helper($hCtrlWnd, $iCtrl, $hMoveWnd)
    Local $aControl = ControlGetPos($hCtrlWnd, '', $iCtrl)
    WinMove($hMoveWnd, '', $aControl[0], $aControl[1], $aControl[2], $aControl[3])
EndFunc

Func WM_GETMINMAXINFO($hWnd, $iMsg, $iWParam, $iLParam)
    Local $tMinMaxInfo = DllStructCreate('int;int;int;int;int;int;int;int;int;int', $iLParam)
    If $hWnd = $g_hGUIMain Then
        DllStructSetData($tMinMaxInfo, 7, $MINMAX_SIZE[0]); min width
        DllStructSetData($tMinMaxInfo, 8, $MINMAX_SIZE[1]); min height
        DllStructSetData($tMinMaxInfo, 9, $MINMAX_SIZE[2]); max width
        DllStructSetData($tMinMaxInfo, 10, $MINMAX_SIZE[3]); max height
        Return
    EndIf
EndFunc

Func WM_DROPFILES($hWnd, $iMsg, $iWParam, $iLParam)
    ; Modified from _WinAPI_DragQueryFileEx from WinAPIEx.au3 by Yashied
    Local $aReturn, $tData, $sFileOpen

    $aReturn = DllCall('shell32.dll', 'int', 'DragQueryFileW', 'ptr', $iWParam, 'uint', -1, 'ptr', 0, 'uint', 0)
    If (@error) Or (Not $aReturn[0]) Then Return

    For $i = 0 To $aReturn[0] - 1
        $tData = DllStructCreate('wchar[1024]')
        $aReturn = DllCall('shell32.dll', 'int', 'DragQueryFileW', 'ptr', $iWParam, 'uint', $i, 'ptr', DllStructGetPtr($tData), 'uint', 1024)
        If Not $aReturn[0] Then Return
        $sFileOpen = DllStructGetData($tData, 1)

        If StringInStr(FileGetAttrib($sFileOpen), 'D') Then ContinueLoop

        If $g_iScriptPID And Not _ScriptRun() Then Return

        If _SaveChangesPrompt() Then
            If @extended = -1 Then Return
            If @extended = 1 Then
                If Not _ScriptSave() Then Return
            EndIf
        EndIf

        _LoadFileContents($sFileOpen)
        $tData = 0
        Return
    Next
EndFunc


Func WM_COMMAND($hWnd, $iMsg, $iWParam, $iLParam)
    Local $iCtrl = BitAND($iWParam, 0xffff)
    If $iCtrl = $in_GoToLine Then
        Local $iLine = Int(GUICtrlRead($iCtrl))
        If $iLine > 0 Then
            Local $iLineCount = _GUICtrlEdit_GetLineCount($ed_Content)
            If $iLine > $iLineCount Then $iLine = $iLineCount
            GUICtrlSetData($in_GoToLine, $iLine)

            GUICtrlSetData($lb_GoToLastColLabel, 'Column:')
            GUICtrlSetData($lb_GoToLastCol, _GUICtrlEdit_LineLength($ed_Content, $iLine-1)+1)
        Else
            GUICtrlSetData($lb_GoToLastColLabel, '')
            GUICtrlSetData($lb_GoToLastCol, '')
        EndIf
    EndIf
EndFunc
#endregion
;endregion - Window Message Functions ----------------------------------------------------------------------------

#region - _FileSaveDialog_WinAPI ----------------------------------------------------------------------------
;   Modified from _WinAPI_GetSaveFileName() to act more like built-in FileSaveDialog().
;   - $iStart var to go by last '(' char instead of first.
;   - Returns string instead of array.
;   - If $sDefaultFile contains full path then $sInitialDir is derived from that.
;   - Checks DllCall return (user cancel?). if false, returns blank and errors.
Func _FileSaveDialog_WinAPI($sTitle = "", $sFilter = "All files (*.*)(*.*)", $sInitalDir = ".", $sDefaultFile = "", $sDefaultExt = "", $iFilterIndex = 1, $iFlags = 0, $iFlagsEx = 0, $hwndOwner = 0)
    Local Const $tagOPENFILENAME = "dword StructSize;hwnd hwndOwner;handle hInstance;ptr lpstrFilter;ptr lpstrCustomFilter;" & _
            "dword nMaxCustFilter;dword nFilterIndex;ptr lpstrFile;dword nMaxFile;ptr lpstrFileTitle;dword nMaxFileTitle;" & _
            "ptr lpstrInitialDir;ptr lpstrTitle;dword Flags;word nFileOffset;word nFileExtension;ptr lpstrDefExt;lparam lCustData;" & _
            "ptr lpfnHook;ptr lpTemplateName;ptr pvReserved;dword dwReserved;dword FlagsEx"
    Local $iPathLen = 4096 ; Max chars in returned string
    Local $tOFN = DllStructCreate($tagOPENFILENAME)

    ; Filter string to array conversion
    Local $asFLines = StringSplit($sFilter, "|")
    Local $asFilter[$asFLines[0] * 2 + 1]
    Local $iStart, $iFinal, $stFilter
    $asFilter[0] = $asFLines[0] * 2
    For $i = 1 To $asFLines[0]
        $iStart = StringInStr($asFLines[$i], "(", 0, -1)
        $iFinal = StringInStr($asFLines[$i], ")", 0, -1)
        $asFilter[$i * 2 - 1] = StringStripWS(StringLeft($asFLines[$i], $iStart - 1), 3)
        $asFilter[$i * 2] = StringStripWS(StringTrimRight(StringTrimLeft($asFLines[$i], $iStart), StringLen($asFLines[$i]) - $iFinal + 1), 3)
        $stFilter &= "wchar[" & StringLen($asFilter[$i * 2 - 1]) + 1 & "];wchar[" & StringLen($asFilter[$i * 2]) + 1 & "];"
    Next

    Local $tTitle = DllStructCreate("wchar Title[" & StringLen($sTitle) + 1 & "]")
    Local $tInitialDir = DllStructCreate("wchar InitDir[" & StringLen($sInitalDir) + 1 & "]")
    Local $tFilter = DllStructCreate($stFilter & "wchar")
    Local $tPath = DllStructCreate("wchar Path[" & $iPathLen & "]")
    Local $tExtn = DllStructCreate("wchar Extension[" & StringLen($sDefaultExt) + 1 & "]")
    For $i = 1 To $asFilter[0]
        DllStructSetData($tFilter, $i, $asFilter[$i])
    Next

    ; Set Data of API structures
    DllStructSetData($tTitle, "Title", $sTitle)
    DllStructSetData($tInitialDir, "InitDir", $sInitalDir)
    DllStructSetData($tPath, "Path", $sDefaultFile)
    DllStructSetData($tExtn, "Extension", $sDefaultExt)

    DllStructSetData($tOFN, "StructSize", DllStructGetSize($tOFN))
    DllStructSetData($tOFN, "hwndOwner", $hwndOwner)
    DllStructSetData($tOFN, "lpstrFilter", DllStructGetPtr($tFilter))
    DllStructSetData($tOFN, "nFilterIndex", $iFilterIndex)
    DllStructSetData($tOFN, "lpstrFile", DllStructGetPtr($tPath))
    DllStructSetData($tOFN, "nMaxFile", $iPathLen)
    DllStructSetData($tOFN, "lpstrInitialDir", DllStructGetPtr($tInitialDir))
    DllStructSetData($tOFN, "lpstrTitle", DllStructGetPtr($tTitle))
    DllStructSetData($tOFN, "Flags", $iFlags)
    DllStructSetData($tOFN, "lpstrDefExt", DllStructGetPtr($tExtn))
    DllStructSetData($tOFN, "FlagsEx", $iFlagsEx)
    Local $aResult = DllCall("comdlg32.dll", "bool", "GetSaveFileNameW", "ptr", DllStructGetPtr($tOFN))
    If @error Then Return SetError(@error, @extended, '')
    If Not $aResult[0] Then Return SetError(-1, 0, '')

    Return DllStructGetData($tPath, "Path")
EndFunc
#endregion
;endregion - _FileSaveDialog_WinAPI ----------------------------------------------------------------------------

#endregion - Document
This entry was posted in AutoIt and tagged , , , . Bookmark the permalink.

Leave a Reply