c.haslam

Modularity: Local outside any function: modularity

34 posts in this topic

#1 ·  Posted (edited)

As I understand it: there is no distinction, when a variable is declared outside any function, between declaring it Global and declaring it Local.

This is unfortunate when:

  • a project has several dialogs: declaration of control variables can conflict.
  • a project has one complex dialog

In the latter case, I have one here with a dialog function that is 269 lines!

I could declare all the control variables as Global, but globals should be aoided where possible.

I think good practice would be to put each dialog in its own file (unless it is a really simple one).

Life would be easier if there were a distinction in how variables are declared outside functions:

  • Global would mean the variable is known to all .au3 files in the project
  • Local would mean that the variable is known only within the file in which it is declared.

So control variables could then be declared as known to all functions in the file (module) by declaring them as Local outside any function. Other languages have this feature.

I am working on a project with one not-very-complex dialog. I would like to be able to split its 269 lines into several functions, e.g. the creation of the dialog, enabling/disabling controls based on a control, and updating the values of the controls due to user actions (in this case, a listview). I already have factored out into functions parts that do not involve control variables: verifications of user entries and actions when the user clicks on OK (or equivalents).

Would this be script-breaking change? Probably, but only for those who don't follow the best coding practices: as AutoIt is now, one should not be declaring variables as Local outside functions, because one gets Global anyway. There is nothing Local about a variable declared outside functions.

I will be interested to learn what others think. If this is an old topic, I apologize. If I have it wrong, do tell me.

 

Edited by c.haslam

...chris

Share this post


Link to post
Share on other sites



It's old in the sense that it has been discussed many times, but if the subject keeps coming up then, who cares.

I really have never had problems with variable scope, and I find it a little confusing as to what you are explaining to be honest, in terms of difficulty you might be having designing your script.

Local keyword variables are refactored (for want of a better word) internally because like you say, they are not local, and because autoit is loosely typed, it deals with that fact.

Besides proper encapsulation and other OOP things, everything can be catered for with AutoIt.


AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

I'd say if you need file scope in a script, you're doing it wrong and need to look at how you're naming your variables in the first place.

Variable names should be distinctive to the need of what they're doing. If you are calculating an average, then name your variable $average_calculation or something along those lines, don't name it $avg or some other obscure name. That way there's less chance of a collision between variables. In the UDFs that come with AutoIt, the global variables are named using what function they're being used for, array.au3 variables are named using Array in their name, listview variables contain Listview in their names, etc.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

c.haslam,

 

Global would mean the variable is known to all .au3 files in the project

Local would mean that the variable is known only within the file in which it is declared.

One fairly major problem with this idea is that there are no separate "files" in AutoIt - including a file does exactly what it says, add the content of that file into the main script at the point of the #include line. So there are no ".au3 files in the project" - there is just the one single script. And so obviously there can be no "file scope" as there are no files within which the scope can be set. ;)

You might not agree with this design decisions, but that was Jon's choice when he wrote AutoIt (and I think it is too late to change now) - if you want something different then write your own language! :D

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

There are many angels to take reducing script size and maintaining scope.  I once made a function to read GUI Control data from file and reiterate it.
 
Looked like this:

#include-once
#include <WindowsConstants.au3>
#include <Constants.au3>
#include <ButtonConstants.au3>
#include <ListboxConstants.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>

#include <GUIConstantsEx.au3>
#Include <GuiButton.au3>
#Include <GuiListView.au3>
#include <Guilistbox.au3>
#include <Guicombobox.au3>
#Include <GuiComboBoxEx.au3>
#include <SliderConstants.au3>
global $controldatamax= 15; max data per loaded gui control
;loaddialogdata loads gui controls into a already created gui, used to insert tab page information into guis from text file
func loaddialogdata($inputfile, ByRef $control, ByRef $controls)
    ;$controls= (filecountlines($inputfile)-1)/($controldatamax+1)
    $file= fileopen($inputfile)
    dim $controldata[$controldatamax]
    $jump= 0
    if $file> -1 then
        $del= filereadline($file);removes label text description
        if @error<> 0 then return
        do
            for $i= 0 to $controldatamax-2;read in control data
                $controldata[$i]= filereadline($file);data
            next
            $tempstr= ""
            while 1; read field 14 the tooltip ex edit field
                $tempstr= filereadline($file)
                if @error<> 0 then
                    $jump= 1
                    exitloop
                elseif stringinstr($tempstr, "control", 0, 1, 1, 7)= 1 then
                    exitloop
                endif
                $control[$controls][1]= $control[$controls][1]&$tempstr&@crlf
            wend
            switch $controldata[0]
            case 0;label
                $control[$controls][0]= guictrlcreatelabel($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6])
                if $controldata[7]= 1 then
                    GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
                elseif $controldata[7]= 0 then

                else
                    GUICtrlSetBkColor(-1, $controldata[7])
                endif
                guictrlsetfont($control[$controls][0], $controldata[1], $controldata[9])
                if $controldata[8]<> "" and  $controldata[8]<> 0 then GUICtrlSetColor($control[$controls][0], $controldata[8])
                guictrlsettip($control[$controls][0], $controldata[10])
            case 1;button
                ;guisetfont($controldata[1], $controldata[9])
                if $controldata[11]= 1 then
                    $control[$controls][0]= guictrlcreatebutton($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6], bitor($BS_MULTILINE, 0x0080))
                else
                    $control[$controls][0]= guictrlcreatebutton($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6], 0x0080)
                endif
                if $controldata[7]<> "" then GUICtrlSetImage($control[$controls][0], @scriptdir&"\System\Graphics\"&$controldata[7])
                guictrlsetfont($control[$controls][0], $controldata[1], $controldata[9])
                guictrlsettip($control[$controls][0], $controldata[10])
            case 2;inputbox
                ;guisetfont($controldata[1], $controldata[9])
                if $controldata[7]= 1 then; inputbox only takes number data
                    $control[$controls][0]= guictrlcreateinput($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6], $ES_NUMBER)
                else; inputbox any string type data
                    $control[$controls][0]= guictrlcreateinput($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6])
                endif
                if $controldata[11]= 1 then GuiCtrlSendMsg($control[$controls][0], $EM_SETREADONLY, 1, 0);read-only
                guictrlsetfont($control[$controls][0], $controldata[1], $controldata[9])
                guictrlsettip($control[$controls][0], $controldata[10])
            case 3;graphic
                $control[$controls][0]= guictrlcreategraphic($controldata[1], $controldata[2], $controldata[3], $controldata[4])
                guictrlsetbkcolor(-1, $controldata[5])
                if $controldata[6]= 1 then guictrlsetstate($control[$controls][0], $gui_disable)
                if $controldata[7]= 1 then guictrlsetstate($control[$controls][0], $gui_ontop)
            case 4;combo
                ;guisetfont($controldata[1], $controldata[8])
                $control[$controls][0]= guictrlcreatecombo($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6], $CBS_DROPDOWNLIST)
                guictrlsetfont($control[$controls][0], $controldata[1], $controldata[8])
                guictrlsettip($control[$controls][0], $controldata[9])
            case 5;edit
                if $controldata[12]= 1 then
                    $control[$controls][0]= guictrlcreateedit($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6], $WS_VSCROLL)
                else
                    $control[$controls][0]= guictrlcreateedit($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6])
                endif
                if $controldata[10]= 1 then guictrlsendmsg($control[$controls][0], $EM_SETREADONLY, 1, 0);read-only
                if $controldata[11]= 1 then guictrlsetstate($control[$controls][0], $gui_disable)
                guictrlsetfont($control[$controls][0], $controldata[1], $controldata[8])
            case 6;checkbox
                ;guisetfont($controldata[1])
                $control[$controls][0]= GUICtrlCreateCheckbox($controldata[2], $controldata[3], $controldata[4], $controldata[8], $controldata[9])
                guictrlsettip($control[$controls][0], $controldata[7])
                guictrlsetfont($control[$controls][0], $controldata[1])
            case 7;listbox
                ;guisetfont($controldata[1])
                $control[$controls][0]= guictrlcreatelist($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6], BitOR($LBS_NOTifY, $LBS_SORT, $WS_HSCROLL, $WS_VSCROLL))
                guictrlsetfont($control[$controls][0], $controldata[1])
            case 8;radio button
                ;guisetfont($controldata[1])
                $control[$controls][0]= GUICtrlCreateRadio($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6])
                guictrlsetfont($control[$controls][0], $controldata[1])
            case 9;start group
                guistartgroup()
            case 10;slider
                if $controldata[7]= 1 then
                    if $controldata[8]= 1 then;default tooltip
                        $control[$controls][0]= guictrlcreateslider($controldata[1], $controldata[2], $controldata[3], $controldata[4], bitor($TBS_VERT, $TBS_TOOLTIPS))
                    else
                        $control[$controls][0]= guictrlcreateslider($controldata[1], $controldata[2], $controldata[3], $controldata[4], $TBS_VERT)
                    endif
                else
                    if $controldata[8]= 1 then;default tooltip
                        $control[$controls][0]= guictrlcreateslider($controldata[1], $controldata[2], $controldata[3], $controldata[4], $TBS_TOOLTIPS)
                    else
                        $control[$controls][0]= guictrlcreateslider($controldata[1], $controldata[2], $controldata[3], $controldata[4])
                    endif
                endif
                if $controldata[10]<> "" then guictrlsetbkcolor($control[$controls][0], $controldata[10]);bg color
                guictrlsetlimit($control[$controls][0], $controldata[6], $controldata[5]);min, max
                if $controldata[8]<> 1 then guictrlsettip($control[$controls][0], $controldata[8]);tooltip
                guictrlsetdata($control[$controls][0], $controldata[9]);start data
            endswitch
            $controls= $controls+1
            if $jump= 1 then return
        until @error<>0
        fileclose($file)
        guisetfont(10)
    endif;endif $file= greater than error
    ;return $hdialog
EndFunc;loaddialogdata()

func loaddialogdataex($inputfile, $controlex, ByRef $control, ByRef $controls)
    $file= fileopen($inputfile)
    dim $controldata[$controldatamax]
    $jump= 0
    if $file> -1 then
        guiseticon(@scriptdir&"\"&filereadline($file));read/set icon
        $del= filereadline($file);removes label text description
        if @error<> 0 then return
        do
            for $i= 0 to $controldatamax-2;read in control data
                $controldata[$i]= filereadline($file);data
            next
            $tempstr= ""
            while 1; read field 14 the tooltip ex edit field
                $tempstr= filereadline($file)
                if @error<> 0 then
                    $jump= 1
                    exitloop
                elseif stringinstr($tempstr, "control", 0, 1, 1, 7)= 1 then
                    exitloop
                endif
                $control[$controlex][$controls][1]= $control[$controlex][$controls][1]&$tempstr&@crlf
            wend
            switch $controldata[0]
            case 0;label
                guisetfont($controldata[1], $controldata[9])
                $control[$controlex][$controls][0]= guictrlcreatelabel($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6])
                if $controldata[7]= 1 then guictrlsetbkcolor(-1, $GUI_BKCOLOR_TRANSPARENT)
                guictrlsettip($control[$controlex][$controls][0], $controldata[10])
            case 1;button
                if $controldata[11]= 1 then
                    $control[$controlex][$controls][0]= guictrlcreatebutton($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6], bitor($BS_MULTILINE, 0x0080))
                else
                    $control[$controlex][$controls][0]= guictrlcreatebutton($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6], 0x0080)
                endif
                if $controldata[7]<> "" then guictrlsetimage($control[$controlex][$controls][0], @ScriptDir&"\System\Graphics\"&$controldata[7])
                guictrlsetfont($control[$controlex][$controls][0], $controldata[1], $controldata[9])
                guictrlsettip($control[$controlex][$controls][0], $controldata[10])
            case 2;inputbox
                guisetfont($controldata[1], $controldata[9])
                if $controldata[7]= 1 then
                    $control[$controlex][$controls][0]= guictrlcreateinput($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6], $ES_NUMBER)
                else
                    $control[$controlex][$controls][0]= guictrlcreateinput($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6])
                endif
                guictrlsettip($control[$controlex][$controls][0], $controldata[10])
            case 3;graphic
                $control[$controlex][$controls][0]= guictrlcreategraphic($controldata[1], $controldata[2], $controldata[3], $controldata[4])
                guictrlsetbkcolor(-1, $controldata[5])
                if $controldata[6]= 1 then guictrlsetstate($control[$controlex][$controls][0], $gui_disable)
                if $controldata[7]= 1 then guictrlsetstate($control[$controlex][$controls][0], $gui_ontop)
            case 4;combo
                guisetfont($controldata[1], $controldata[8])
                $control[$controlex][$controls][0]= guictrlcreatecombo($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6], $CBS_DROPDOWNLIST)
                guictrlsettip($control[$controlex][$controls][0], $controldata[9])
            case 5;edit
                ;guisetfont($controldata[1])
                ;$control[$controlex][$controls][0]= GUICtrlCreateEdit($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6])
                ;if $controldata[10]= 1 then guictrlsendmsg($control[$controlex][$controls][0], $EM_SETREADONLY, 1, 0);read-only

                if $controldata[12]= 1 then
                    $control[$controlex][$controls][0]= guictrlcreateedit($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6], $WS_VSCROLL)
                else
                    $control[$controlex][$controls][0]= guictrlcreateedit($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6])
                endif
                _WinAPI_SetWindowLong(GUICtrlGetHandle(-1), $GWL_STYLE, BitAND(_WinAPI_GetWindowLong(GUICtrlGetHandle(-1), $GWL_STYLE), BitNOT($WS_TABSTOP)))
                if $controldata[10]= 1 then guictrlsendmsg($control[$controls][0], $EM_SETREADONLY, 1, 0);read-only
                if $controldata[11]= 1 then guictrlsetstate($control[$controls][0], $gui_disable)
                guictrlsetfont($control[$controlex][$controls][0], $controldata[1], $controldata[8])
            case 6;checkbox
                guisetfont($controldata[1])
                $control[$controlex][$controls][0]= GUICtrlCreateCheckbox($controldata[2], $controldata[3], $controldata[4])
                ;guictrlsetbkcolor(-1, 0xECE9D8)
            case 7;listbox
                guisetfont($controldata[1])
                $control[$controlex][$controls][0]= guictrlcreatelist($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6], BitOR($LBS_NOTifY, $LBS_SORT, $WS_HSCROLL, $WS_VSCROLL))
            case 8;radio button
                guisetfont($controldata[1])
                $control[$controlex][$controls][0]= GUICtrlCreateRadio($controldata[2], $controldata[3], $controldata[4], $controldata[5], $controldata[6])
            case 9;start group
                guistartgroup()
            case 10;slider
                if $controldata[7]= 1 then;vertical
                    if $controldata[8]= 1 then;default tooltip
                        $control[$controlex][$controls][0]= guictrlcreateslider($controldata[1], $controldata[2], $controldata[3], $controldata[4], bitor($TBS_VERT, $TBS_TOOLTIPS, $TBS_BOTTOM))
                    else
                        $control[$controlex][$controls][0]= guictrlcreateslider($controldata[1], $controldata[2], $controldata[3], $controldata[4], $TBS_VERT, $TBS_BOTTOM)
                    endif
                else
                    if $controldata[8]= 1 then;default tooltip
                        $control[$controlex][$controls][0]= guictrlcreateslider($controldata[1], $controldata[2], $controldata[3], $controldata[4], bitor($TBS_VERT, $TBS_TOOLTIPS, $TBS_BOTTOM))
                    else
                        $control[$controlex][$controls][0]= guictrlcreateslider($controldata[1], $controldata[2], $controldata[3], $controldata[4], $TBS_BOTTOM)
                    endif
                endif
                if $controldata[10]<> "" then guictrlsetbkcolor($control[0], $controldata[10]);bg color
                guictrlsetlimit($control[$controlex][$controls][0], $controldata[6], $controldata[5]);min, max
                if $controldata[8]<> 1 then guictrlsettip($control[$controlex][$controls][0], $controldata[8]);tooltip
                guictrlsetdata($control[$controlex][$controls][0], $controldata[9]);start data
            endswitch
            $controls= $controls+1
            if $jump= 1 then return
        until @error<>0
        fileclose($file)
        guisetfont(10)
    endif;endif $file= greater than error
EndFunc; loaddialogdataex()

func filecountlines($path); counts the amount of lines in a file
    $count= 0
    $file= fileopen($path, 0)
    while(@error==0)
        filereadline($file)
        if(@error <> 0) then exitloop
        $count= $count+1
    wend
    fileclose($file)
    return $count
EndFunc; end filecountlines()

func loaddialogquick($path, byref $controls, $docking= 0)
    $controls= filecountlines($path)/$controldatamax
    if $controls< 1 then
        consolewrite("No controls loaded - loaddialogquick()")
        return 1
    endif;endif any controls
    dim $control[$controls][2]
    ;ConsoleWrite("CONTROLS: "&$controls)
    $controls= 0
    loaddialogdata($path, $control, $controls)
    return $control
EndFunc 

It'a a horrible function don't use it. I would be willing to look at your script and try to apply modularity.

Edited by Xandy

I am not a lawyer.  (-_-) Xandy About  (^o^) Discord - Xandy Programmer

Share this post


Link to post
Share on other sites

Xandy,

Thanks for the offer, but I have more recently taken the path of refactoring.

All,

I am very careful in how I name variables. For example, all globals (and only globals) begin with a g, booleans with a b, input boxes with inp, buttons with btn, etc.

In some scripts involving nultiple dialogs, I have used a prefix indicating the dialog, for each dialog.

I suggest that the time is approaching when AutoIt should consider offering projects. In my mind:

  • a project would be made of up associated scripts.
  • Each associated script could have #includes.
  • There would be a main script. It would #associate other scripts.
  • In an associated script, functions would be private by default. Func preceded by Public would make it possible for a function to be visible to the main script and to associated scripts.
  • Variables declared as Public in an associated script would be visible to all scripts.

Is this script-breaking? I think not.

Would it be a chunk of work for Jon? Probably, but he has gone to considerable effort, I expect, to add Static.

I have been delaying replying to give me time to digest your thoughts, and to let my thoughts mature a bit. There are no guarantees that my thinking may not change!

...chris


...chris

Share this post


Link to post
Share on other sites

Have you ever looked at an autoit script once it is ready for compiling? It's just ONE long file, there's no such thing as includes by that point, so it would be massively script breaking.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

To have the control IDs capsulated, you can use AutoItObject UDF, or a Map variable.

 

AutoItObject:

Declare a class for each form (dialog) and store control IDs as class member variables.

 

Map variable:

Declare a single global map variable for each form (dialog) and store control IDs as map members.

 

Something like this:

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <StringConstants.au3>

AutoItSetOption('GUIOnEventMode', 1)

Global $mMainForm[]
MainForm()

Func MainForm()
    $mMainForm['hWnd'] = GUICreate('Login', 290, 187)
    GUISetOnEvent($GUI_EVENT_CLOSE, Main_btnClose_Click)

    GUICtrlCreateLabel('Username:', 20, 20, -1, 15)
    $mMainForm['txtUsername'] = GUICtrlCreateInput('', 20, 38, 250, 23)
    GUICtrlSetLimit(-1, 16)
    GUICtrlSetOnEvent(-1, Main_txtUsername_TextChanged)
    GUICtrlSendMsg(-1, $EM_SETCUEBANNER, True, 'Username')

    GUICtrlCreateLabel('Password:', 20, 71, -1, 15)
    $mMainForm['txtPassword'] = GUICtrlCreateInput('', 20, 89, 250, 23, BitOR($GUI_SS_DEFAULT_INPUT, $ES_PASSWORD))
    GUICtrlSendMsg(-1, $EM_SETCUEBANNER, True, 'Password')

    $mMainForm['chkRememberMe'] = GUICtrlCreateCheckbox('Remember me', 20, 122, -1, 15)
    GUICtrlSetOnEvent(-1, Main_chkRememberMe_Click)

    GUICtrlCreateButton('Login', 195, 147, 75, 25, $BS_DEFPUSHBUTTON)
    GUICtrlSetOnEvent(-1, Main_btnLogin_Click)

    GUISetState(@SW_SHOW, $mMainForm['hWnd'])
EndFunc

Func Main_btnClose_Click()
    GUIDelete($mMainForm['hWnd'])
    Exit
EndFunc

Func Main_txtUsername_TextChanged()
    GUICtrlSetData($mMainForm['txtPassword'], '')
EndFunc

Func Main_btnLogin_Click()
    Local $sUsername = GUICtrlRead($mMainForm['txtUsername'])
    Local $sPassword = GUICtrlRead($mMainForm['txtPassword'])

    $sUsername = StringStripWS($sUsername, BitOR($STR_STRIPLEADING, $STR_STRIPTRAILING))
    $sPassword = StringStripWS($sPassword, BitOR($STR_STRIPLEADING, $STR_STRIPTRAILING))

    If $sUsername And $sPassword Then
        ; --- Nothing to do
    Else
        MsgBox(BitOR($MB_OK, $MB_ICONWARNING), 'Login', 'Please enter both username and password.', 0, $mMainForm['hWnd'])
        GUICtrlSetState($sUsername ? $mMainForm['txtPassword'] : $mMainForm['txtUsername'], $GUI_FOCUS)
        Return
    EndIf

    MsgBox(BitOR($MB_OK, $MB_ICONINFORMATION), 'Login', StringFormat('Welcome %s!\n\nYour password is: %s', $sUsername, $sPassword), 0, $mMainForm['hWnd'])
EndFunc

Func Main_chkRememberMe_Click()
    If GUICtrlRead($mMainForm['chkRememberMe']) = $GUI_CHECKED Then
        MsgBox(BitOR($MB_OK, $MB_ICONINFORMATION), 'Login', 'I will never forget you.', 0, $mMainForm['hWnd'])
    Else
        MsgBox(BitOR($MB_OK, $MB_ICONINFORMATION), 'Login', "I won't even remember you were here.", 0, $mMainForm['hWnd'])
    EndIf
EndFunc

While True
    Sleep(1000)
WEnd
Edited by FaridAgl
1 person likes this

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

BrewManH,

I am not suggesting that #include be eliminated. Each associated file would have #includes.

Edited by c.haslam

...chris

Share this post


Link to post
Share on other sites

FaridAgl,

Thank you for telling me about Map. It will solve my problem.


...chris

Share this post


Link to post
Share on other sites

BrewManH,

I am not suggesting that #include be eliminated. Each associated file would have #includes.

I never said you were, what I said was that a compiled AutoIt script doesn't have any includes, because everything in the include files are added to one long script file. There is no such thing as included files at that point. To make the change you suggested would completely break the way AutoIt works right now, so your presumption that it wouldn't be script breaking is 100% wrong.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

There is still a relatively simple possibility to get poor man's file scope by simply using Local in includes without adding extra keyword and without changing anything in the interpretor itself.

The idea is to make the compiler prefix every outer Local variables in a given include (those explicitely declared local outside functions) with the filename being processed. Of course that wouldn't preclude malicious users to violate the file scope barrier by explicitely referring to the mangled name, yet I think the benefit would be interesting compared to a relatively simple change to the compiler and associated tools.

A more robust name mangling for Locals could be to prefix those variable names by a string derived (e.g. by hashing or similar) from a randomized quantity (e.g. fine-grain timestamp at include open time). This way it will be much more difficult to subvert the file scope barrier.

There remains the question of variables created by Assign() and marginally within Execute(), Eval() and IsDeclared(). AFAICT there shouldn't be any consequences for standard includes, nor with any decently written user UDF.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

I don't see how this is relates to --comparatively much simpler-- on-the-fly local names mangling while gluing together main au3 and its includes.

Am I missing something?


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

A good discussion!


...chris

Share this post


Link to post
Share on other sites

I just F5'd while I was writing a reply. The short story is that you can already do this manually and so it adds very little benefit. We've done it manually for the past 10+ years. Look at the includes or built-in functions. That approach is still valid today.

There are other approaches towards an additional variable scope, among which is file scoping and namespaces. The former is a decent idea which fits well with AutoIt's dynamic nature, but of questionable benefit to AutoIt's main use case. The other is namespaces which is a firm step in the OO direction and should be followed up by other OO features or it has no real benefits, which IMO is a mistake but that's a much bigger debate.

The linked trac issue is also about file scoping because it goes really well with being able to dynamically include a file.

Share this post


Link to post
Share on other sites

I agree to most of that yet decent namespaces along with other OO features are IMO beyond what AutoIt is going to cover.

I was rather thinking aloud about a more lightweight machinery.

Granted file scope one can live without at the relatively low price of being careful about the name of things.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

When I want to encapsulate UDF/include scope variables, I create an initialization function in the UDF that returns an array containing all of the UDF relevant variables.  Then the first required variable in every function is a ByRef variable that expects that array.  Kind of a poor-mans OO when a real OO might be overkill.  Might seem klunky to some, but it has worked well, and eliminated the need for any of my UDFs to need Globals at all.

Works nice for GUI functions as well.  I set array element [0] to the GUI itself, then relevant variables follow.

2 people like this

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

@willichan.

Ever tried the same scenario using a map instead of array? Guess you'll like it.

Edited by FaridAgl
2 people like this

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now