This article explains in detail the organization of the code of an AutoIt project built with AGS framework. You are advised to have already read the article: 1. Getting started with AGS.


Code Organization of an AGS project

Source code of an AGS project

All AutoiT source code for the application is stored in the ./src directory. In the latter there are directories and special files.

Project root folder
+---src                        # AutoIt source
    |   BUSINESS.au3           # Entry point for business and logic code
    |   GLOBALS.au3            # Entry point for constants and global variables of application
    |   GUI.au3                # Entry point for graphic user interface (GUI)
    |   SERVICES.au3           # Entry point for services applications
    |
    +---business               # Folder for store all business annd logic code
    |
    +---services               # Folder for store all services application
    |       Dialogbox.au3      # Handler of dialog box in which the user is prompted
    |       ParametersIni.au3  # Handler of configuration file parameters.ini
    |
    \---views                  # Folder for store all views application
            View_About.au3
            View_Footer.au3
            View_Settings.au3
            View_Welcome.au3

Overview of AGS architecture

Overview of AGS architecture

The main entry program

This is the single point of entry for the application, and the location where the application starts. This file is placed at the root of the AGS project and in this one we start by including all the other dependencies that it needs:

  • AutoIt libraries
  • third-party libraries stored in the ./vendor directory;
  • declaration of constants and global variables of the application;
  • the service manager of the application;
  • the user interface manager.
;; myApplication.au3 ;;

;-------------------------------------------------------------------------------
; Include all built-in AutoIt library requires
;-------------------------------------------------------------------------------
#include <IE.au3>
#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>
#include <WinAPIDlg.au3>


;-------------------------------------------------------------------------------
; Include all third-party code
;
; By convention the directory `./vendor/` is the place where to conventionally
; store the code developed by third parties in a project.
;
; AGS components are a set of AutoIt libraries, that you can use in our own
; applications. You can choose to enable or disable its loading with comments.
; By convention the directory `./vendor/@autoit-gui-skeleton` is the place where
; to conventionally store AGS components or AGS wrapper. Theses dependencies
; are handled with the tools Yarn which works in Node.js ecosystem.
;-------------------------------------------------------------------------------
#include "vendor/@autoit-gui-skeleton/ags-component-check-for-updates/ags-component-check-for-updates.au3"
#include "vendor/@autoit-gui-skeleton/ags-component-http-request/ags-component-http-request.au3"
#include "vendor/@autoit-gui-skeleton/ags-wrapper-json/JSON.au3"


;-------------------------------------------------------------------------------
; Include constants and global variables
;
; All constants and global variables are set in one place './src/GLOBALS.au3',
; With the exception to global variables of graphic elements which are set in
; each specific view file. Don't forget that constants can't longer change their
; value over time, unlike global variables.
;
; By convention, all global variables must be written in capital letter and
; separated by underscore - for example : Global Const $APP_EMAIL_CONTACT
;-------------------------------------------------------------------------------
#include './src/GLOBALS.au3'


;-------------------------------------------------------------------------------
; Include the main program that manages all the business code
;
; This is the entry point to business and logic code. This file can include
; another script store into './src/models/' folder, according to the needs of
; the application.
;-------------------------------------------------------------------------------
#include './src/BUSINESS.au3'


;-------------------------------------------------------------------------------
; Include the main program that manages all services
;
; This is the entry point to include all services. This file can include
; another service store into './src/services/' folder.
;-------------------------------------------------------------------------------
#include './src/SERVICES.au3'


;-------------------------------------------------------------------------------
; Include the main handler GUI
;
; It contains the _main_GUI() method which is only called by the main entry
; program. This method is designed to create the graphical user interface (GUI)
; and manage all user interactions and events.
;-------------------------------------------------------------------------------
#include './src/GUI.au3'


; Start the application
_main_GUI()

The application starts by calling the _main_GUI() method of the main GUI manager.

Centralize the declaration of global variables

All constants and global variables are defined in one place in the ./src/GLOBALS.au3 file, in order to centralize the declaration of all global variables. With the exception of all the global variables of the graphic elements, which they are defined in each specific view file. Don’t forget that constants can no longer change value over time, unlike global variables. If a global variable changes its value, it can not be persisted , unless to do it in the configuration file ./config/parameters.ini.

By convention, all global variables must be capitalized and separated by an underscore.

The common constants of AGS projects are:

  • $ APP_FOLDER_ROOT: Alias ​​to access the root directory of the project.
  • $ APP_FOLDER_ASSETS: Alias ​​to access the project assets directory.
  • $ APP_PARAMETERS_INI: Alias ​​to access the application settings file. Settings can persist value changes from user or event interactions. Note that at loading, this is where AGS checks that the . / Config / parameters.ini configuration file exists.
  • $ APP_NAME: The name of the application.
  • $ APP_VERSION: The version number of the application with respect to semantic versionning.
  • $ APP_WEBSITE: The promotion site / documentation associated with the application.
  • $ APP_EMAIL_CONTACT: The contact email for the application.
  • $ APP_ID: Identifier consisting of the owner and the name of the project. Must not contain special characters. ([A-z, 1-9])
  • $ APP_LIFE_PERIOD: Informs since when the application exists.
  • $ APP_COPYRIGHT: The copyright of the application.
  • $ APP_WIDTH: Sets the width of the main window of the application
  • $ APP_HEIGHT: Set the height of the main window of the application
  • $ APP_GUI_TITLE_COLOR: Sets the color of the app titles
  • $ APP_GUI_LINK_COLOR: Sets the color of the app links

There are also global variables specific to AGS components that control their operation. Some examples of global variables specific to AGS components:

  • $ APP_REMOTE_RELEASES_JSON: Sets the URL of the RELEASES.json file to use to check for updates to the application.
  • $ APP_GAMP_TRACKING_ID: Set up Google Analytics tracking id
  • $ APP_GAMP_ENABLE: To enable / disable tracking via Google Analytics Mesurement Protocol
  • $ APP_GAMP_DEBUG: To enable / disable console component debug output

And finally a section specific to global variables called “custom”.

;; ./src/GLOBALS.au3 ;;

#include-once

;-------------------------------------------------------------------------------
; Application helper alias
;-------------------------------------------------------------------------------
Global Const $APP_FOLDER_ROOT = @ScriptDir & "/../"
Global Const $APP_FOLDER_ASSETS = @ScriptDir & "/assets"

;-------------------------------------------------------------------------------
; Application parameters
;-------------------------------------------------------------------------------
Global Const $APP_PARAMETERS_INI = @ScriptDir & "/config/parameters.ini"
Local $fileExists = FileExists($APP_PARAMETERS_INI)
If Not $fileExists Then
	MsgBox(16, "Error with load parameters.ini", "Unable to find the file './config/parameters.ini'! " & @CRLF & "This application can not work, you must create this file. You wan use the file './config/parameters.ini.dist' to create it.")
EndIf

;-------------------------------------------------------------------------------
; Application main constants
;-------------------------------------------------------------------------------
Global Const $APP_NAME = "MyApplication"
Global Const $APP_VERSION = "0.9.0"
Global Const $APP_WEBSITE = "https://myApplication-website.org"
Global Const $APP_EMAIL_CONTACT = "myApplication@website.org"
Global Const $APP_ID = "v20100v.MyApplication"
Global Const $APP_LIFE_PERIOD = "2018-" & @YEAR
Global Const $APP_COPYRIGHT = "© " & $APP_LIFE_PERIOD & ", v20100v"

;-------------------------------------------------------------------------------
; Application GUI constants
;-------------------------------------------------------------------------------
Global Const $APP_WIDTH = 800
Global Const $APP_HEIGHT = 600
Global Const $APP_GUI_TITLE_COLOR = 0x85C4ED
Global Const $APP_GUI_LINK_COLOR = 0x5487FB

;-------------------------------------------------------------------------------
; AGS-compontent-check-for-updates constants
;-------------------------------------------------------------------------------
; Specifiy the repository JSON use to check for updates. This json file must persist in a remote server available via
; internet, and without restriction. If you use Github as a control version, you can use it to host this file. In this
; case use this bellow URL.
Global Const $APP_REMOTE_RELEASES_JSON = "https://raw.githubusercontent.com/autoit-gui-skeleton/AGS-component-check-for-updates/master/example/ApplicationWithCheckForUpdates/RELEASES.json"

;-------------------------------------------------------------------------------
; Custom application global variable
; Here is an example to defined custom global variables
;-------------------------------------------------------------------------------
Global $OPEN_FILE = False
Global $OPEN_FILE_PATH = -1
Global $OPEN_FILE_NAME = -1

The main manager of services

The ./src/SERVICES.au3 file is the entry point for all services that are stored in the./src/services/ directory. In this file we simply find the instructions to include the services. And each service is defined in a specific file, with a single scope of responsibility, which simplifies reading and maintenance.

In the case of services that become available between different applications, you should package it with the AutoIt dependency manager in AGS. This eliminates the need to manually update the service consumed by different applications. With the dependency manager, the simple yarn update statement at the root of the project is enough to update all the dependencies.

;; ./src/SERVICES.au3
#include-once

; Includes services
#include './services/Dialogbox.au3'
#include './services/ParametersIni.au3'

For example, in AGS, we have the ParametersIni.au3 service which provides a method to interoperate with the./config/parameters.ini application configuration file. It allows to save the changes chosen by a user from the graphical interface.

;; ./src/services/ParametersIni.au3

;-------------------------------------------------------------------------------
; Save values choose by user in 'Setting' views, and launch with 'save' button
;
; @params void
; @return void
;-------------------------------------------------------------------------------
Func _save_parameters_ini()

	; Save proxy settings
	IniWrite($APP_PARAMETERS_INI, "AGS_HTTP_REQUEST", "PROXY", GUICtrlRead($input_HTTP_Proxy))
	IniWrite($APP_PARAMETERS_INI, "AGS_HTTP_REQUEST", "RESOLVE_TIMEOUT", GUICtrlRead($input_HTTP_Resolve_Timeout))
	IniWrite($APP_PARAMETERS_INI, "AGS_HTTP_REQUEST", "CONNECT_TIMEOUT", GUICtrlRead($input_HTTP_Connect_Timeout))
	IniWrite($APP_PARAMETERS_INI, "AGS_HTTP_REQUEST", "SEND_TIMEOUT", GUICtrlRead($input_HTTP_Send_Timeout))
	IniWrite($APP_PARAMETERS_INI, "AGS_HTTP_REQUEST", "RECEIVE_TIMEOUT", GUICtrlRead($input_HTTP_Receive_Timeout))

	; Startup settings
	If (GUICtrlRead($checkbox_STARTUP_CHECK_UPDATE) = $GUI_CHECKED) Then
		IniWrite($APP_PARAMETERS_INI, "AGS_CHECK_FOR_UPDATES", "LAUNCH_CHECK_FOR_UPDATE_ON_STARTUP", "1")
	Else
		IniWrite($APP_PARAMETERS_INI, "AGS_CHECK_FOR_UPDATES", "LAUNCH_CHECK_FOR_UPDATE_ON_STARTUP", "0")
	EndIf
EndFunc

Another example with the service ./src/services/Dialogbox.au3 for the management of dialog box in the application.

;; ./src/services/Dialogbox.au3 ;;

;====================================================================================
; Show a dialog box to user, in order that he chooses a file in the Windows Explorer
;
; @params : void
; @return : $array_result[0] = file path
;           $array_result[1] = file name
;====================================================================================
Func _dialogbox_open()
   Local $info_fichier = _WinAPI_GetOpenFileName("Open file", "*.*", _ 
                         @WorkingDir, "", "", 2, _ 
                         BitOR($OFN_ALLOWMULTISELECT, $OFN_EXPLORER), _
                         $OFN_EX_NOPLACESBAR)
                         
   Local $array_result[2]

   If @error Then
      $array_result[0] = -1
      $array_result[1] = -1
   Else
      
      ; $PATHFILE_OF_OPEN_FILE_IN_APP
      $array_result[0] = $info_fichier[1]&"\"&$info_fichier[2] 
      
      ; $NAME_OF_OPEN_FILE_IN_APP
      $array_result[1] = $info_fichier[2] 
   EndIf

   Return $array_result
EndFunc

Control the graphic user interface (GUI)

The main GUI manager

The ./src/GUI.au3 file is the entry point for all view managers, that are saved in the./views directory. We will call it main manager of the GUI. The code for each view is defined each time in a specific file and stored in this ./views directory.

The main manager GUI contains especially the _main_GUI() method, which allows to start the application. This method is only called from the main entry program of the application, and it was designed to create the user interface (GUI) and manage all user interactions and events in the application.

;; myApplication_GUI.au3 ;;

#include-once

; Includes all views definition
#include './views/View_Footer.au3'
#include './views/View_Welcome.au3'
#include './views/View_About.au3'

;====================================================================================
; Main graphic user interface
;
; @param void
; @return void
;====================================================================================
Func _main_GUI()
   Global $main_GUI = GUICreate($APP_NAME, $APP_WIDTH, $APP_HEIGHT, -1, -1)

   _GUI_Init_Menu()

   _GUI_Init_Footer()       ; By default all elements of this view are visible
   _GUI_Init_View_Welcome() ; By default all elements of this view are hidden
   _GUI_Init_View_About()   ; By default all elements of this view are hidden

   ; Set configuration application : icon, background color
   _GUI_Configuration()

   ; Show Welcome view on startup
   _GUI_ShowHide_View_Welcome($GUI_SHOW)
   GUISetState(@SW_SHOW)

   ; Handle all user interactions and events
   _GUI_HandleEvents()

   GUIDelete()
   Exit
EndFunc

(...)

Few comments:

  • All uppercase variables ($APP_NAME, $APP_WIDTH, $APP_HEIGHT) are declared in the global scope of the application. Their definition is done in the file myApplication_GLOBAL.au3;
  • _GUI_Init_Menu() is used to create a menu control in the main GUI;
  • _GUI_Init_Footer() is used to create footer elements in the main GUI. Its definition is made in a separate special file. All footer elements are visible in all views by default, so we do not need to manage its visibility.
  • _GUI_Init_View_Welcome() is used to create GUI elements for a “Welcome” view name. All items declared in this method are hidden by default. To display the “Welcome” view, that is, to make it visible, simply call the method with this parameter _GUI_ShowHide_View_Welcome($GUI_SHOW). And to hide them, just call _GUI_ShowHide_View_Welcome($GUI_HIDE);
  • _GUI_HandleEvents() handles all user interactions and events by parsing the return message with the GUIGetMsg() method. The event return with the GUIGetMsg method is the control ID of the control that sends the message. This method calls another specific handler event per view, for example _GUI_HandleEvents_View_Welcome($msg);

Declare code for all views in dedicated files

Each view is managed in a specific file.

For example, for managing the creation of the graphic elements of the “Welcome” view, we use the _GUI_Init_View_Welcome() method.

;; ./view/View_Welcome.au3 ;;

Func _GUI_Init_View_Welcome()
   ; Create GUI elements here for "Welcome view" in global scope
   Global $label_title_View_Welcome = GUICtrlCreateLabel("Welcome", 20, 30, 400)
EndFunc

For the management of the display of the elements of the “Welcome” view, we use the _GUI_ShowHide_View_Welcome($action) method

;; ./view/View_Welcome.au3 ;;

Func _GUI_ShowHide_View_Welcome($action)
   Switch $action
      Case $GUI_SHOW
         ; Define here all elements to show when user come into this view
         _GUI_Hide_all_view() ; Hide all elements defined in all method _GUI_ShowHide_View_xxx
         GUICtrlSetState($label_title_View_Welcome, $GUI_SHOW)
         GUICtrlSetState($label_welcome, $GUI_SHOW)

      Case $GUI_HIDE
         ; Define here all elements to hide when user leave this view
         GUICtrlSetState($label_title_View_Welcome, $GUI_HIDE)
         GUICtrlSetState($label_welcome, $GUI_HIDE)
    EndSwitch
EndFunc

For event handling in the “Welcome” view, use the _GUI_HandleEvents_View_Welcome($msg) method. This method is called in the _GUI_HandleEvents() main handler method.

;; ./view/View_Welcome.au3 ;;

Func _GUI_HandleEvents_View_Welcome($msg)
   Switch $msg

      ; Trigger for click on $image_banner
      Case $label_welcome
         ConsoleWrite('Click on "$label_welcome"' & @CRLF)

      ; Add another trigger in view 'Welcome' here
   EndSwitch
EndFunc

Main events manager

The main user and application event handler is named _GUI_HandleEvents(). It is the latter who will call all the other event managers specific to each view. They are named by convention _GUI_HandleEvents_View_Xxx($msg).

;; myApplication_GUI.au3 ;;

Func _GUI_HandleEvents()
   Local $msg
   While 1
    ; event return with GUIGetMsg method, i.e. the control ID of the control sending the message
    $msg = GUIGetMsg()
      Switch $msg
         ; Trigger on close dialog box
         Case $GUI_EVENT_CLOSE
            ExitLoop

         ; Trigger on click on item menu 'File > Exit'
         Case $menuitem_Exit
            ExitLoop
      EndSwitch

      _GUI_HandleEvents_View_Welcome($msg)
      _GUI_HandleEvents_View_About($msg)
      _GUI_HandleEvents_Menu_File($msg)
      _GUI_HandleEvents_Menu_About($msg)
   WEnd
EndFunc

How to navigate into the application and switch view?

To switch from a start view to another arrival view, you first have to hide all the graphic elements, then in a second time to display only those of the arrival view. So, how to hide all the graphic elements? Just with a _GUI_Hide_all_view() method that will call the view manager of each view. These are conventionally named _GUI_ShowHide_View_Xxx.

;; myApplication_GUI.au3 ;;

Func _GUI_Hide_all_view()
   _GUI_ShowHide_View_Welcome($GUI_HIDE)
   _GUI_ShowHide_View_About($GUI_HIDE)
EndFunc

For example to switch from the Welcome view to the view About, we start by hiding all the graphic elements of the Welcome view. The graphic elements of the footer are always visible. And then we display the graphic elements of the About view.

AGS GUI example

Code source

GUI View Welcome handler

#cs ----------------------------------------------------------------------------
GUI View Welcome handler
AutoIt Version : 3.3.14.5
Author         : v20100v <7567933+v20100v@users.noreply.github.com>
Package        : autoit-gui-skeleton
Version        : 1.0
#ce ----------------------------------------------------------------------------


#include-once


;====================================================================================
; Create element for the 'Welcome' view
;
; @param void
; @return void
;====================================================================================
Func _GUI_Init_View_Welcome()
	; GUI elements have to register in global scope
	GUISetFont(20, 800, 0, "Arial Narrow")
	Global $label_title_View_Welcome = GUICtrlCreateLabel("Welcome", 20, 30, 400)
	GUICtrlSetColor($label_title_View_Welcome, $APP_GUI_TITLE_COLOR)
	GUICtrlSetBkColor($label_title_View_Welcome, $GUI_BKCOLOR_TRANSPARENT)

	GUISetFont(10, 400, 0, "Segoe UI")
	Global $label_welcome = GUICtrlCreateLabel( _
			"On startup " & $APP_NAME & ", we show this Welcome view. " & _
			"We add an event click on this label in order to show how to define " & @CRLF & _
			"a trigger on a view." _
			, 20, 80)
	GUICtrlSetCursor($label_welcome, 0)
EndFunc


;====================================================================================
; Handler for display element on 'Welcome' view
;
; @param {int} $action, use GUIConstantsEx $GUI_SHOW or $GUI_HIDE
; @return void
;====================================================================================
Func _GUI_ShowHide_View_Welcome($action)
	Switch $action
		Case $GUI_SHOW
			; Define here all elements to show when user come into this view
			_GUI_Hide_all_view()
			GUICtrlSetState($label_title_View_Welcome, $GUI_SHOW)
			GUICtrlSetState($label_welcome, $GUI_SHOW)

		Case $GUI_HIDE
			; Define here all elements to hide when user leave this view
			GUICtrlSetState($label_title_View_Welcome, $GUI_HIDE)
			GUICtrlSetState($label_welcome, $GUI_HIDE)
	EndSwitch
EndFunc


;====================================================================================
; Handler for events in 'Welcome' view
;
; @param $msg, the control ID of the control sending the message
; @return @void
;====================================================================================
Func _GUI_HandleEvents_View_Welcome($msg)
	Switch $msg

		; Trigger for click on $image_banner
		Case $label_welcome
			ConsoleWrite('Click on "$label_welcome"' & @CRLF)

			; Add another trigger in view 'Welcome' here
	EndSwitch
EndFunc


Relating reading

1. Getting started with AGS
3. Creating installation packages for AutoIt applications - Windows setup