<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.autoitscript.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Melba23</id>
	<title>AutoIt Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://www.autoitscript.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Melba23"/>
	<link rel="alternate" type="text/html" href="https://www.autoitscript.com/wiki/Special:Contributions/Melba23"/>
	<updated>2026-04-04T14:21:40Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Arrays&amp;diff=13260</id>
		<title>Arrays</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Arrays&amp;diff=13260"/>
		<updated>2015-11-23T08:56:34Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An &#039;&#039;&#039;array&#039;&#039;&#039; is a [[Data_Structures|data structure]] which stores elements (variables) aligned in a computer&#039;s memory.  Arrays are referenced by an [[identifier]] (variable name) and an index specifying a desired element.  The array concept seems complex but the concept can be easily grasped.  Why are arrays so important?  The array is a fundamental data structure found in most programming languages.  &lt;br /&gt;
&lt;br /&gt;
This tutorial targets people who are beginners.  To understand how arrays work, it is imperative to try out and modify the provided samples.  Make sure that each concept is understood before the next concept is attempted.  This tutorial assumes the use of the SciTE editor.  There is a minimal version of SciTE included in the latest stable release of AutoIt (version 3.2.0.1 and above).&lt;br /&gt;
&lt;br /&gt;
== Declaring Arrays in AutoIt ==&lt;br /&gt;
&lt;br /&gt;
An array is declared in the same manner as a variable in AutoIt.  The difference is that for an array, extra information on how many elements are to be included in the array must be specified.  This information is provided by adding brackets after the identifier and a number indicating how many elements the array will possess. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;autoit&#039;&amp;gt;&lt;br /&gt;
Global $arr[4] ; Will make space for 4 elements.&lt;br /&gt;
Local  $arr[1] ; Will make space for 1 element.&lt;br /&gt;
Dim    $arr[3] ; Will make space for 3 elements.  Note: Avoid using Dim.  Use Global or Local instead.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
In AutoIt, a variable may be converted to an array by either using the {{Help File|ReDim}} keyword or assigning a function which returns an array to the variable.  &lt;br /&gt;
&lt;br /&gt;
For example, the function {{Help File|StringSplit}} returns an array which will be assigned to $arr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;autoit&#039;&amp;gt;&lt;br /&gt;
Local $arr = StringSplit(&amp;quot;This is my string. I want to split it in sentences.&amp;quot;, &#039;.&#039;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now to make really certain we have an array from {{Help File|StringSplit}}, we should check it with the {{Help File|IsArray}} built-in function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;autoit&#039;&amp;gt;&lt;br /&gt;
If IsArray($arr) Then &lt;br /&gt;
     ; Do work on the array&lt;br /&gt;
EndIf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Assigning Data to Array Elements ==&lt;br /&gt;
&lt;br /&gt;
When we declare the array we make some room in memory for future data.  We want to assign some data to the items in the array.  Now here is the catch. The array always starts at index zero.  So, the first element in the array will be accessed by zero, the second element in the array is accessed at by one and so on.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;autoit&#039;&amp;gt;&lt;br /&gt;
 Local $arr[3] ; Make room for three elements&lt;br /&gt;
 ;Assign some data&lt;br /&gt;
 $arr[0] = &amp;quot;Element 1&amp;quot;&lt;br /&gt;
 $arr[1] = &amp;quot;Element 2&amp;quot;&lt;br /&gt;
 $arr[2] = &amp;quot;Element 3&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also assign all the data in one smack like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;autoit&#039;&amp;gt;&lt;br /&gt;
Local $arr[3] = [&amp;quot;element 1&amp;quot;, &amp;quot;element 2&amp;quot;, &amp;quot;element 3&amp;quot;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This zero-based indexing is quite common in most computer languages, but it can be a source of headaches to beginners until it becomes second nature to them.  For example, every time you want to loop through a range of elements and the range includes the last element, you have to subtract one from the number of items your array is holding, to get the index of the last item. I.E.,  An array with three elements has a last index of two.&lt;br /&gt;
&lt;br /&gt;
So if you don&#039;t take zero-based indexing into consideration in your code, you may ask for something outside the memory area set aside for the array. When you do, you get an error message (&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;Array variable has incorrect number of subscripts or subscript dimension range exceeded&amp;lt;/font&amp;gt;) and your script will cease execution.&lt;br /&gt;
&lt;br /&gt;
== Accessing Data in Arrays ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s walk all elements in the previous sample:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;autoit&#039;&amp;gt;&lt;br /&gt;
Local $arr[3] = [&amp;quot;element 1&amp;quot;, &amp;quot;element 2&amp;quot;, &amp;quot;element 3&amp;quot;] &lt;br /&gt;
&lt;br /&gt;
For $i = 0 to 3 - 1 ; We have an array with three elements but the last index is two.&lt;br /&gt;
    ConsoleWrite($arr[$i] &amp;amp; @LF)&lt;br /&gt;
Next&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Determine Array Size With UBound ===&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;3 - 1&amp;quot; construct used in the last sample looked strange.  It is not a good idea to hard-code size like that. So lets improve our sample a little. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;autoit&#039;&amp;gt;&lt;br /&gt;
Local $iMax = 3&lt;br /&gt;
&lt;br /&gt;
Local $arr[$iMax] = [&amp;quot;Element 1&amp;quot;, &amp;quot;Element 2&amp;quot;, &amp;quot;Element 3&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
For $i = 0 to $iMax - 1&lt;br /&gt;
    ConsoleWrite($arr[$i] &amp;amp; @LF)&lt;br /&gt;
Next&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that&#039;s a bit cleaner. It&#039;s also a lot easier to increase or decrease the size of the array. &amp;lt;br&amp;gt;&lt;br /&gt;
But say you don&#039;t know the size of the array upfront because it may come in a variable size when created dynamically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;autoit&#039;&amp;gt;&lt;br /&gt;
Local $iMax &lt;br /&gt;
&lt;br /&gt;
Local $data = &amp;quot;Element 1|Element 2|Element 3&amp;quot; &lt;br /&gt;
&lt;br /&gt;
; The string in data will be split into an array everywhere | is encountered &lt;br /&gt;
Local $arr = StringSplit($data, &amp;quot;|&amp;quot;) &lt;br /&gt;
&lt;br /&gt;
If IsArray($arr) Then&lt;br /&gt;
     $iMax = UBound($arr); get array size&lt;br /&gt;
&lt;br /&gt;
     ConsoleWrite(&amp;quot;Items in the array: &amp;quot; &amp;amp; $iMax &amp;amp; @LF)&lt;br /&gt;
&lt;br /&gt;
     For $i = 0 to $iMax - 1; subtract 1 from size to prevent an out of bounds error&lt;br /&gt;
         ConsoleWrite($arr[$i] &amp;amp; @LF)&lt;br /&gt;
     Next&lt;br /&gt;
EndIf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you run the above code you will see that $iMax is four and not three as you might have expected. The reason for this is that the developer of the {{Help File|StringSplit}} function thought it was a good idea to use the first item (item zero) to keep a count of valid items in the array. This makes sense in many situations as you now have an array containing data with an index starting at one. So our sample code can now be rewritten like this.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;autoit&#039;&amp;gt;&lt;br /&gt;
Local $iMax&lt;br /&gt;
&lt;br /&gt;
Local $data = &amp;quot;Element 1|Element 2|Element 3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
; The string in data will be split into an array everywhere | is encountered&lt;br /&gt;
Local $arr = StringSplit($data, &amp;quot;|&amp;quot;)  &lt;br /&gt;
&lt;br /&gt;
If IsArray($arr) Then &lt;br /&gt;
    For $i = 1 to $arr[0]&lt;br /&gt;
        ConsoleWrite($arr[$i] &amp;amp; @LF)&lt;br /&gt;
    Next&lt;br /&gt;
EndIf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is another good reason for keeping the count in $arr[0]. When you start to use arrays extensively, you will encounter situations where you have to create an array without knowing how many of the elements you will use. Resizing the array is a relatively expensive operation (in CPU cycles) in most languages.&lt;br /&gt;
&lt;br /&gt;
Now consider our example if our initial array has reserved space for ten items but we end up only using three. In this case iterating the array using {{Help File|UBound}} will force us to check for empty elements. While iterating with $arr[0] needs no other change than maintaining the correct count in $arr[0].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;autoit&#039;&amp;gt;&lt;br /&gt;
Local $iMax=10&lt;br /&gt;
&lt;br /&gt;
;NOTE: We have added the count in the first element&lt;br /&gt;
&lt;br /&gt;
Local $arr[$iMax] = [3, &amp;quot;Element 1&amp;quot;, &amp;quot;Element 2&amp;quot;, &amp;quot;Element 3&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
;NOTE: We use the count in $arr[0] to indicate the last item and we start from index=1&lt;br /&gt;
For $i = 1 to $arr[0]&lt;br /&gt;
    ConsoleWrite($arr[$i] &amp;amp; @LF)&lt;br /&gt;
Next&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Changing Array Sizes With ReDim ==&lt;br /&gt;
&lt;br /&gt;
As arrays are critical to algorithm implementations, and in AutoIt even more so as there is no other means of grouping data, we have to understand how to let it grow and shrink. This is where the keyword {{Help File|ReDim}} comes into the picture.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s make an example. We want our array to hold data lines but we don&#039;t know how many items we need. We make a guess, in this case five. Now, we use that array to hold data we get from a loop with a random number of iterations. If the array is too small it should automatically be increased. Before we dump the array to output, we should adjust it to the exact size it is supposed to be.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
Local Const $iMax = 5&lt;br /&gt;
&lt;br /&gt;
; NOTE: We have added the count in the first element&lt;br /&gt;
Local $arr[$iMax] = [0] ; Initiate the array and place a counter in the first element.&lt;br /&gt;
&lt;br /&gt;
; Generate a random number between 0 and 20&lt;br /&gt;
Local Const $iRandom = Random(0, 20, 1)&lt;br /&gt;
&lt;br /&gt;
For $i = 1 to $iRandom&lt;br /&gt;
    ; Check that the array is big enough&lt;br /&gt;
    If UBound($arr) = $i Then&lt;br /&gt;
        ; Resize the array when $i is equal to the element count in the array to prevent subscript error&lt;br /&gt;
        ReDim $arr[$arr[0] + $iMax]&lt;br /&gt;
    EndIf&lt;br /&gt;
&lt;br /&gt;
    $arr[$i] = &amp;quot;Item &amp;quot; &amp;amp; $i ; safely add data to new index element&lt;br /&gt;
&lt;br /&gt;
    $arr[0] = $i ; update the index count for future reference&lt;br /&gt;
Next&lt;br /&gt;
&lt;br /&gt;
; Adjust the array size. This time it is probably downward to the size of&lt;br /&gt;
; $arr[0] + 1 (remember the first item is $arr[0])&lt;br /&gt;
ReDim $arr[$arr[0] + 1] &lt;br /&gt;
&lt;br /&gt;
; Now dump the results&lt;br /&gt;
For $i = 1 to $arr[0]&lt;br /&gt;
    ConsoleWrite(&amp;quot;$arr[&amp;quot; &amp;amp; $i &amp;amp; &amp;quot;]:=&amp;quot; &amp;amp; $arr[$i] &amp;amp;  @LF)&lt;br /&gt;
Next&lt;br /&gt;
&lt;br /&gt;
; Visually check that the values are sound&lt;br /&gt;
ConsoleWrite(&amp;quot;Ubound($arr):=&amp;quot; &amp;amp; UBound($arr) &amp;amp; &amp;quot;, $arr[0]:=&amp;quot; &amp;amp; $arr[0] &amp;amp; &amp;quot;, $iRandom:=&amp;quot; &amp;amp; $iRandom &amp;amp; @LF)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note how the array now has first been adjusted to a multiple of $iMax and in the last part adjusted down to a size matching the data items.&lt;br /&gt;
&lt;br /&gt;
== Passing Arrays to Functions ==&lt;br /&gt;
&lt;br /&gt;
There is no special syntax required to pass an array as a function argument unlike a low level language such as C.&lt;br /&gt;
The following example demonstrates:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;AutoIt&amp;quot;&amp;gt;&lt;br /&gt;
Local Const $myArray[5] = [1, 2, 3, 4, 5]&lt;br /&gt;
&lt;br /&gt;
displayArray($myArray)&lt;br /&gt;
&lt;br /&gt;
Func displayArray(Const $array)&lt;br /&gt;
    Local Const $arrayLength = UBound($array)&lt;br /&gt;
&lt;br /&gt;
    For $i = 0 To $arrayLength - 1&lt;br /&gt;
        MsgBox($MB_OK, &amp;quot;displayArray&amp;quot;, $array[$i])&lt;br /&gt;
    Next&lt;br /&gt;
EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can not declare the variable to hold the array in the function declaration as an array. So, users could pass on a variable. So you have to check that the variable holds an array before you do array specific operations on it.&lt;br /&gt;
The following code example will cause an error:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;AutoIt&amp;quot;&amp;gt;&lt;br /&gt;
Local Const $myArray[5] = [1, 2, 3, 4, 5]&lt;br /&gt;
&lt;br /&gt;
displayArray($myArray)&lt;br /&gt;
&lt;br /&gt;
Func displayArray(Const $array[5])&lt;br /&gt;
    Local Const $arrayLength = UBound($array)&lt;br /&gt;
&lt;br /&gt;
    For $i = 0 To $arrayLength - 1&lt;br /&gt;
        MsgBox($MB_OK, &amp;quot;displayArray&amp;quot;, $array[$i])&lt;br /&gt;
    Next&lt;br /&gt;
EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During the tutorial you have probably noticed that there is a lot of code that is equal in each sample. I&#039;m especially thinking about the code we have used to output the array content. Let&#039;s make life easier and create a debug function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Func dbgArray(ByRef $arr, $msg=&amp;quot;&amp;quot;)&lt;br /&gt;
     If $msg &amp;lt;&amp;gt; &amp;quot;&amp;quot; Then &lt;br /&gt;
         ConsoleWrite(&amp;quot;*** &amp;quot; &amp;amp; $msg &amp;amp; &amp;quot; ***&amp;quot; &amp;amp; @LF)&lt;br /&gt;
     EndIf&lt;br /&gt;
&lt;br /&gt;
     For $i = 0 to UBound($arr) - 1&lt;br /&gt;
        ConsoleWrite(&amp;quot;$arr[&amp;quot; &amp;amp; $i &amp;amp; &amp;quot;]:=&amp;quot; &amp;amp; $arr[$i] &amp;amp;  @LF)&lt;br /&gt;
     Next&lt;br /&gt;
&lt;br /&gt;
     ConsoleWrite( &amp;quot;Ubound($arr)=:=&amp;quot; &amp;amp; UBound($arr) &amp;amp; &amp;quot;, $arr[0]:=&amp;quot; &amp;amp; $arr[0] &amp;amp; @LF)   &lt;br /&gt;
 EndFunc &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And let&#039;s make a little function to fill our arrays with something. Note how the ArrayFiller makes sure it works on an array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Func ArrayFiller(ByRef $arr)&lt;br /&gt;
     If IsArray($arr) Then &lt;br /&gt;
         ReDim $arr[3] ; Notice we might discard content in this operation&lt;br /&gt;
     Else&lt;br /&gt;
         Local $foo[3]&lt;br /&gt;
         $arr = $foo&lt;br /&gt;
     EndIf &lt;br /&gt;
&lt;br /&gt;
     ;Fill the array&lt;br /&gt;
     $arr[0] = 2&lt;br /&gt;
     $arr[1] = &amp;quot;Fill 1&amp;quot;&lt;br /&gt;
     $arr[2] = &amp;quot;Fill 2&amp;quot;&lt;br /&gt;
 EndFunc &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And finally some code using the new functions&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
   Local $arr1[1]&lt;br /&gt;
   ArrayFiller($arr1)&lt;br /&gt;
   dbgArray($arr1)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code is a test on what happens when we pass a regular variable.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
   Local $arr2&lt;br /&gt;
   ArrayFiller($arr2)&lt;br /&gt;
   dbgArray($arr2)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Returning Arrays From Functions ==&lt;br /&gt;
&lt;br /&gt;
As you could observe, in the previous samples, an array will be passed back and forth with the ByRef keyword infront of the variable holding the array in the function declaration.&lt;br /&gt;
&lt;br /&gt;
We could also have used the Return keyword in a function.&lt;br /&gt;
Lets re-work the ArrayFiller function to do this rather than using a variable ByRef.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Func ArrayFiller2()&lt;br /&gt;
   Local $arr = [3, &amp;quot;Fill 1&amp;quot;, &amp;quot;Fill 2&amp;quot;]&lt;br /&gt;
   Return $arr&lt;br /&gt;
 EndFunc &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And now we can use the function like this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Local $foo = ArrayFiller2()&lt;br /&gt;
 dbgArray($foo)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Comparing Arrays ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;You can not compare complete arrays:&#039;&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
Local $Array1[3] = [1, 2, 3]&lt;br /&gt;
Local $Array2[3] = [1, 2, 3]&lt;br /&gt;
Local $Array3[4] = [1, 2, 3, 4]&lt;br /&gt;
&lt;br /&gt;
If $Array1 == $Array2 Then ConsoleWrite(&amp;quot;1.) $Array1 is equal to $Array2! which might be correct in some sense.&amp;quot; &amp;amp; @LF); while they contain the same data, the comparison does not work.&lt;br /&gt;
&lt;br /&gt;
If $Array1 == $Array3 Then ConsoleWrite(&amp;quot;2.) $Array1 is equal to $Array3! which is incorrect.&amp;quot; &amp;amp; @LF); even though they&#039;re different in size, it&#039;s incorrectly determined that they&#039;re equal.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I have the impression that such comparisons compare the memory address of the arrays instead of the array elements values. And the addresses are always different for different arrays.  You have to instead, compare all elements one after the other. It might be a good idea to first compare array sizes if that can vary for both the compared arrays!&lt;br /&gt;
&lt;br /&gt;
== Multi Dimensional Arrays ==&lt;br /&gt;
&lt;br /&gt;
Now what is a good explanation of a multi-dimensional array?&lt;br /&gt;
It could be a table where you access one item in the table at a time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
Local  $arr[3][3] = [[1, 2, 3], [2, 3, 4], [3, 4, 5]]&lt;br /&gt;
&lt;br /&gt;
For $i = 0 to UBound( $arr, 1) - 1&lt;br /&gt;
    For $j = 0 to UBound($arr, 2) - 1&lt;br /&gt;
        ConsoleWrite(&amp;quot;$arr[&amp;quot; &amp;amp; $i &amp;amp; &amp;quot;][&amp;quot; &amp;amp; $j &amp;amp; &amp;quot;]:=&amp;quot; &amp;amp; $arr[$i][$j] &amp;amp; @LF)&lt;br /&gt;
    Next &lt;br /&gt;
&lt;br /&gt;
    ConsoleWrite(@LF)&lt;br /&gt;
Next &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can add a number of dimensions not to exceed sixty-four as stated in the help file section [http://www.autoitscript.com/autoit3/docs/appendix/LimitsDefaults.htm AutoIt3 limits/Defaults].&lt;br /&gt;
&lt;br /&gt;
Here is a four dimensional example. You tell me how that initializer is for readability.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt; &lt;br /&gt;
; NOTE: The following is supposed to be all on one line&lt;br /&gt;
; but we use the &amp;quot;_&amp;quot; character to split it into multiple lines for readability&lt;br /&gt;
&lt;br /&gt;
Local $arr[3][3][3][3] = _&lt;br /&gt;
		[ _&lt;br /&gt;
		[ _&lt;br /&gt;
		[[1, 2, 3], [2, 3, 4], [3, 4, 5]], _&lt;br /&gt;
		[[1, 2, 3], [2, 3, 4], [3, 4, 5]], _&lt;br /&gt;
		[[1, 2, 3], [2, 3, 4], [3, 4, 5]] _&lt;br /&gt;
		], _&lt;br /&gt;
		[ _&lt;br /&gt;
		[[1, 2, 3], [2, 3, 4], [3, 4, 5]], _&lt;br /&gt;
		[[1, 2, 3], [2, 3, 4], [3, 4, 5]], _&lt;br /&gt;
		[[1, 2, 3], [2, 3, 4], [3, 4, 5]] _&lt;br /&gt;
		], _&lt;br /&gt;
		[ _&lt;br /&gt;
		[[1, 2, 3], [2, 3, 4], [3, 4, 5]], _&lt;br /&gt;
		[[1, 2, 3], [2, 3, 4], [3, 4, 5]], _&lt;br /&gt;
		[[1, 2, 3], [2, 3, 4], [3, 4, 5]] _&lt;br /&gt;
		] _&lt;br /&gt;
		]&lt;br /&gt;
&lt;br /&gt;
For $i = 0 To UBound($arr, 1) - 1&lt;br /&gt;
	For $j = 0 To UBound($arr, 2) - 1&lt;br /&gt;
		For $k = 0 To UBound($arr, 3) - 1&lt;br /&gt;
			For $l = 0 To UBound($arr, 4) - 1&lt;br /&gt;
				ConsoleWrite(&amp;quot;$arr[&amp;quot; &amp;amp; $i &amp;amp; &amp;quot;][&amp;quot; &amp;amp; $j &amp;amp; &amp;quot;][&amp;quot; &amp;amp; $k &amp;amp; &amp;quot;][&amp;quot; &amp;amp; $l &amp;amp; &amp;quot;]:=&amp;quot; &amp;amp; $arr[$i][$j][$k][$l] &amp;amp; @LF)&lt;br /&gt;
			Next&lt;br /&gt;
		Next&lt;br /&gt;
	Next&lt;br /&gt;
Next&lt;br /&gt;
&lt;br /&gt;
ConsoleWrite(@LF)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Arrays in Arrays ==&lt;br /&gt;
&lt;br /&gt;
You may save an array in an array element (item). Remember that there may be issues if you pass an array containing arrays into a function and the embedded array is changed inside that function. So, as a general rule, try not to embed arrays within arrays unless you absolutely need to and are prepared to do rigorous testing to make sure your code will always work as expected.&lt;br /&gt;
&lt;br /&gt;
You can access the elements of these embedded arrays directly (note the additional () required):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
Local $aContainerArray[2]&lt;br /&gt;
Local $aInternalArray_0[2] = [&amp;quot;Internal-0-0&amp;quot;,&amp;quot;Internal-0-1&amp;quot;]&lt;br /&gt;
Local $aInternalArray_1[2] = [&amp;quot;Internal-1-0&amp;quot;,&amp;quot;Internal-1-1&amp;quot;]&lt;br /&gt;
$aContainerArray[0] = $aInternalArray_0&lt;br /&gt;
$aContainerArray[1] = $aInternalArray_1&lt;br /&gt;
&lt;br /&gt;
ConsoleWrite(&amp;quot;1 element of InternalArray_0: &amp;quot; &amp;amp; ($aContainerArray[0])[1] &amp;amp; @CRLF)&lt;br /&gt;
ConsoleWrite(&amp;quot;0 element of InternalArray_1: &amp;quot; &amp;amp; ($aContainerArray[1])[0] &amp;amp; @CRLF)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== More Information ==&lt;br /&gt;
&lt;br /&gt;
AutoIt features a large list of [http://www.autoitscript.com/autoit3/docs/libfunctions.htm User Defined Functions (UDF)], among which is a module supplying extra array functions. You can find a reference on those functions in AutoIt&#039;s Help file as the last main chapter named [http://www.autoitscript.com/autoit3/docs/libfunctions.htm User Defined Functions Reference].&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=User_Defined_Functions&amp;diff=13040</id>
		<title>User Defined Functions</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=User_Defined_Functions&amp;diff=13040"/>
		<updated>2015-05-19T15:42:28Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is a listing of libraries of &#039;&#039;&#039;user defined functions&#039;&#039;&#039; (UDF). These libraries have been written to allow easy integration into your own scripts and are a very valuable resource for any programmer.&lt;br /&gt;
This list is probably not complete, but constantly supplemented.&lt;br /&gt;
If you do not find a solution here, ask a new question on the [http://www.autoitscript.com/forum/forum/2-general-help-and-support/ forum].&lt;br /&gt;
&lt;br /&gt;
== Automation ==&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=106163 Active Directory (by water)] - Extensive library to control and manipulate the Windows active directory. Link to the [[Active_Directory_UDF_-_General|documentation]] pages.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=150231 GTK+  (by prazetto)] - GTK+ Framework | Widgets.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=153520 IUIAutomation MS framework (by junkew)] - IUIAutomation MS framework to automate chrome, FF, IE etc.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=87956 Java (by seangriffin)] - Creates an access bridge between your application and a Java application. Allowing you to automate some Java applications.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=86574 SAP (by seangriffin)] - SAP business management automation.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=149540 SAPWizard (by ozmike)] - SAPWizard UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=80201 Service (by arcker)] - Build your own service with AutoIt code.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=91018 WiFi (by MattyD)] - Low level control over your wireless LAN.&lt;br /&gt;
&lt;br /&gt;
===Browsers===&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=154439 Chrome (by seangriffin)] - The same as above for Google Chrome. Automate the most common tasks in Chrome with the Chrome UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=95595 Firefox (by Stilgar)] - A little less support for automation than IE, but still very good.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=166542 HTMLDocumentEvents (by SmOke_N)] - Track IE document events.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=166304 IEJS (by SmOke_N)] - IEJS - IE Javascript options, an IE.au3 personal extension.&lt;br /&gt;
* Internet Explorer (by DaleHohm et al.) - Everything about Internet explorer can be automated with the IE library supplied with a standard AutoIt install.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=149203 NavInfo (by Nessie)] - With this UDF you can check if a specified browser/software is installed and which version is being used.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=61090 Opera (by MrCreatoR,)] - The same as above for Opera. Automate the most common tasks in Opera with the Opera UDF.&lt;br /&gt;
&lt;br /&gt;
===Microsoft Office Automation===&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=32144 Microsoft Office Access (by randallc)] - Automate Microsoft Access.&lt;br /&gt;
* Microsoft Office Excel (by water et al.) - This UDF is included in AutoIt. Link to the [[Excel_UDF|documentation]] pages.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=135312 Microsoft Office Excel Charts (by water, GreenCan)] - Creating charts using Microsoft Excel.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=126305 Microsoft Office Outlook (by water )] - Automate Microsoft Outlook. Link to the [[OutlookEX_UDF_-_General|documentation]] pages.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=50254 Microsoft PowerPoint (by Toady)] - Automate Microsoft PowerPoint.&lt;br /&gt;
* Microsoft Office Word (by water et al.) - This UDF is included in AutoIt. Link to the [[Word_UDF|documentation]] pages.&lt;br /&gt;
&lt;br /&gt;
===OpenOffice Automation===&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=151530 OOo/LibO Calc (by GMK)] - OpenOfficeCalc UDF.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
* [[CommAPI]] - Serial and parallel communication (COM port, RS-232, LPT port) - without installing DLL&#039;s (using Windows API calls).&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=77731 Device Management (by ... )] - Device Management API.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=97487 DirectShow (by ... )] - DirectShow UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=164700 DirectSound (by ... )] - DirectSound UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=164701 Direct2D (by ... )] - Direct2D UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=138989 FritzBox (by ... )] - _FB_Tools - manage your FritzBox from Autoit.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=121084 I/O Port Functions (by ... )] - This is a simple I/O (Input/Output) UDF for interacting with ports. (I/O Port Functions - x64 Parallel Port IO, Keyboard, etc + Restore PC Speaker Beep).&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=154350 Monitor Configuration (by ... )] - Monitor Configuration UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=155469 Mouse (by ... )] - AutoIt powered mouse events.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=147325 MouseTrapEvent (by ... )] - MouseTrapEvent UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=149083 NetInfo (by ... )] - UDF for test internet download speed and upload speed.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=155539 Network configuration (by ... )] - Network configuration UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=20121 Screen Resolution (by ... )] - Screen Resolution Changing UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=128546 Serial Port/COM (by ... )] - Serial Port /COM Port UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=27755 SMARTDRIVE (by ... )] - SMART drive Analysis.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=15864 SPI Hardware Interface (by ... )] - This script is made to comunicate with the MAX335 chip  using the SPI protocol via the LPT(printer) port.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=68866 Webcam (by LIMITER)] - Webcam UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=70857 Webcam (by ludocus)] - Webcam UDF.&lt;br /&gt;
&lt;br /&gt;
== Information gathering ==&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=29404 Computer information (by JSThePatriot)] - A general purpose library to get various details about a Windows machine.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=54039 WinPcap (by JRSmile)] - Wrapper for the windows packet capture library WinPcap.&lt;br /&gt;
* [http://opensource.grisambre.net/pcapau3/ WinPcap (by Nicolas Ricquemaque)] - A library to access the main functionalities offered by the WinPcap driver.&lt;br /&gt;
&lt;br /&gt;
== Databases and web connections ==&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=105875 ADODB (by spudw2k)] - ADODB Example.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=145142 DBF (by funkey)] - dBase database read and write with DLL.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=116072 EzMySql (by ... )] - EzMySql - Use MySql Databases with autoit.&lt;br /&gt;
* [http://www.autoitscript.com/forum/topic/94920-solved-passing-parameters-using-dllcall-to-a-c-dll/#entry684751 FireBird (by ... )] - FireBird, Interbase dll udf.&lt;br /&gt;
* [http://stackoverflow.com/questions/21991475/autoit-firebird-sql-combo-return-data-as-csv-instead-of-xml FireBird (by ... )] - Additional link to FireBird UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=127101 MS SQL (by ... )] - MSSQL.au3.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=51952 MS SQL (by ... )] - _SQL.au3. ADODB Connection.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=20814 MySQL (by ... )] - MySQL relational database management system UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=85617 MySQL (by ... )] - MySQL UDFs (without ODBC).&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=17099 SQLite (by ... )] - SQLite is a library that implements a self-contained, embeddable, zero-configuration SQL database engine.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=19848 XML DOM Wrapper (by ... )] - Supports CRUD operations on XML. Including XSL and XPath.&lt;br /&gt;
&lt;br /&gt;
== Internet protocol suite ==&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=137456 cURL (by ... )] - cURL UDF - a UDF for transferring data with URL syntax.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=40243 IMAP (by ... )] - IMAP.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=108422 IMAP4 (by ... )]  - IMAP4 UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=43515 IRC (by ... )] - A lightweight library for communicating with IRC servers.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=159285 IRC (by ... )] IRC UDF - Updated Version of Chips&#039; IRC UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=104150 JSON (by ... )] - RFC4627 compliant JSON encode/decode.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=148114 JSON (by ... )] - JSMN - A Non-Strict JSON UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=156794 JSON (by ... )] - Bridge to Native Windows JSON plus OO extension for AutoIt.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=22838 POP3 (by ... )] - POP3 library for retrieving email messages. Not compatible with Gmail because it uses SSL.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=167339 _POP3_Ex (by ... )] POP3 UDF According to the 1939 RFC, modified version with Quoted Printable decoder.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=64051 POP3 SSL (by ... )] - A POP3 library that&#039;s compatible with Gmail. It uses an external executable that must be supplied with your script.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=154530 Prowl (by ... )]  - Prowl UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=138095 SFTP (by ... )] - UDF to support SFTP protocol using PSFTP.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=23860 SMTP (by ... )]  - Smtp Mailer That Supports Html And Attachments.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=81687 SNMP (by ... )] - SNMP_UDF for SNMPv1 and SNMPv2c.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=70759 SNMP - MIB protocol (by ... )] (Reading toner status from SNMP device with WMI).&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=166579 SSH (by ... )]  - This UDF allows to use the SSH protocol very easily in your code.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=57022 UPnP Protocol (by ... )]  - UPnP : Read and Control your devices in side out.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=84133 WinHTTP (by ... )] - Enables scripts to access the HTTP protocol for creating GET and POST requests and submitting them with conforming standards, cookies not supported.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=77503 WinInet (by ... )] - Enables scripts to access standard Internet protocols, such as FTP, Gopher and HTTP. Also supports creating GET and POST requests and submitting them with conforming standards, cookies supported.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=169774 TCPServer (by ... )]  - multi client, event-based, able to bind console app to socket.&lt;br /&gt;
&lt;br /&gt;
== Data compression ==&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=85094 7z, zip, gzip, bzip2, tar (by ... )] - More extensive library than the one above. Uses a external DLL that must be provided with the script.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=87441 LZMA (by trancexx )] - LZMA (Native Windows).&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=112273 LZMA Compression (by ... )] - LZMA Compression UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=166634 MessagePack (by ... )] - MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. But it&#039;s faster and smaller.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=138838 Package (by ... )] - Package UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=129529 pZip (by ... )] - PureZIP_L library UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=76176 UnRAR (by ... )] - UnRAR.au3.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=44524 Zip plugin (by ... )] - Zip plugin.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=73425 ZIP (by ... )] - ZIP.au3 UDF in pure AutoIt.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=116565 zip (by ... )] - Create ZIP files and unpack ZIP files.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=135565 ZIP (by ... )] - ZIP STRUCTS UDF (from scratch).&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=128962 zLib (by ... )] - zLib (Deflate/Inflate/GZIP) UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=17727 XZip (by eltorro)] - another UDF for &amp;quot;XStandard XZIP Component&amp;quot;.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=161847 XZip (by mLipok)] - UDF for &amp;quot;XStandard XZIP Component&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Encryption and hash ==&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=78745 AES Rijndael (by ... )] - Very fast AES UDF. Support ECB/CBC/CFB/OFB block cipher mode.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=76976 MD5,SHA1,CRC32,RC4,BASE64,XXTEA (by ... )] - Several encryption and hash functions.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=107784 TrueCrypt (by ... )] - TrueCrypt UDFs.&lt;br /&gt;
&lt;br /&gt;
== Media ==&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=95357 FreeImage library (by ... )] - Various operations on images, such as rotate, resize, flip.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=127263 HtmlHelp (by ... )] - HtmlHelp UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=50608 OCR (by ... )] - Real OCR in AU3 - MODI with MS Office 2003.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=89542 OCR (by ... )] - Tesseract (Screen OCR) UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=51054 Printer controller (by ... )] - Print text in any font, size and colour at any position on the page, draw lines, curves, elipses, pies in any colour, and print images.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=73993 Printing (by ... )] - Printing from AutoIt.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=161831 RTF_Printer (by ... )] - RTF_Printer.au3 - Printing RichEdit in the background.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=94834 Simple DirectMedia Layer (by ... )] - Adds support for joysticks, CDs, 2D graphics, timers. See [http://www.libsdl.org/ SDL website] for more information.&lt;br /&gt;
===Sound===&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=83481 BASS Function Library (by ... )] - Sound and Music via wrappers for Bass, BassEnc, Bass FX, BassSFX, BassAsio and BassCd DLLs.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=37072 MIDI (by ... )] - MIDI UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=114742 SAPIListBox (by ... )] - SAPIListBox (Speech Recognition) UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=100439 TTS (by ... )] - Text-to-Speech UDF.&lt;br /&gt;
&lt;br /&gt;
===Graphics and image===&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=27362 Bitmap Library (by ... )] - Bitmap Library.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=70506 IrrLicht (by ... )] - A 3D graphics engine suitable for creating games.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=113881 au3Irrlicht2 (by ... )] - Another UDF bringing Irrlicht and au3 together. Historically some kind of a follower of the UDF above, technically with a complete different approach.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=13096 ImageGetInfo (by ... )] - This is an UDF for reading info from JPEG, TIFF, BMP, PNG and GIF - size, color depth, resolution.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=151011 OpenGL (by ... )] - OpenGL without external libraries etc. For JPEG files UDF also retreive various Exif information.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=148129 OpenGL (2.0) (by ... )] - new set of UDFs for OpenGL + AutoIt.&lt;br /&gt;
&lt;br /&gt;
===Players===&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=114143 VLC (by ... )] - VLC (Media Player) UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=91316 VLC Media Player (by ... )] - VLC Media Player.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=27352 WMP (by ... )] - Windows Media Player UDF.&lt;br /&gt;
&lt;br /&gt;
== GUI Additions ==&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=32494 XSkin (by ... )] - A large library that allows skinning of your GUI and to apply custom skins.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=132864 Uskin (by ... )] - A library that allows a user to skin their application GUI using the Windows &#039;&#039;.MSstyles&#039;&#039; files.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=20967 Modern tray menu (by ... )] - Allows the creation of modern, fancy GUI and tray menus with icons and colors.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=71811 SetOnEvent (by ... )] - Provides an easy way for an event to call functions with parameters.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=119505 GUIFrame (by Melba23 &amp;amp; Kip)] - Divide a GUI into adjustable frames.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=113723 Easy Scrollbars (by Melba23)] - Easily create scrollable sections in your GUI.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=105582 GUICtrlOnChangeRegister (by ... )] - Call a function when an edits content is changed.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=96258 ContextHelp.au3 (by ... )] - Management of context help ([http://www.autoitscript.com/forum/index.php?showtopic=72152-contexthelp/ original]).&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=145149 GUIExtender (by Melba23)] - Expand and contract sections of your GUI ([http://www.autoitscript.com/forum/index.php?showtopic=117909 original]).&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=109096 ExtMsgBox (by Melba23)] - A very customisable replacement for MsgBox.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=108445 Toast (by Melba23)] - Small message GUIs which pop out of the Systray.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=144207 GUI Panel (by ... )] - Manage child GUIs as panel ctrls.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=161750 Pie chart (by ... )] - Pie chart.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=97241 3D Pie chart (by ... )] - 3D Pie chart.&lt;br /&gt;
&lt;br /&gt;
=== Controls ===&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=79412 Graph control (by ... )] - Easily create and show bar chart and line charts.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=105682 GUICtrlCreateFinder (by ... )] - Allows you to create a window finder control like the one seen in AutoIt Window Info.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=111438 GUIPager (by ... )] - Create and control native pager controls.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=90598 Hotkey input control (by ... )] - Hotkeys Input Control UDF Library (Non-native).&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=107965 GUIHotkey (by ... )] - UDF for using native hotkey controls.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=143711 Marquees (by Melba23)] - Make tickertape info bars.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=96464 Colorpicker (by ... )] - Create a button for the user to select a color.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=126958 Syslink (by ... )] - Provides a convenient way to embed hypertext links in a window.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=74649 Progressbar with GDIplus (by ... )] - You even can use full textured images.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=105814 Table (by ... )] - Table UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=20967 GUI/Tray Menu (by Holger, LarsJ, AZJIO)] - GUI/Tray Menu with icons and colors.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=128242 Ribbon (by ... )] - UDF for Windows Ribbon framework.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=166594 GUITreeViewEx (by Melba23)] - Check/clear parent and child checkboxes in a TreeView.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=146406 Calendar (by ... )] - Calendar UDF.&lt;br /&gt;
&lt;br /&gt;
== Maths ==&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=83091 Primes (by ... )] - Many functions dealing with prime number generation and calculations.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=83529 Big number (by ... )] - Make calculations with extremely large numbers that AutoIt normally is not able to support.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=81189 Number base conversion (by ... )] - From, to and between positive bases less than 63 (decimals supported).&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=106551 Decimal To fraction (by ... )] - Converts any decimal number to a fraction. Example: 1.2 to 6/5.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=82722 Trigonometry math functions (by ... )] - _ATan2(), _Cosh(), _Frexp(), _Hypot(), _Ldexp(), _Logb(), _Sinh(), _Tanh().&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=108803 Polynomials (by ... )] - Functions for using polynomials.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=117156 NumToWord (by ... )] - Convert numerals to a human readable string.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=98160 Root function (by ... )] - Working out real roots of numbers.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=102686 Advanced rounding (by ... )] - Support for different measures of accuracy and 8 ways to resolve tie breaks.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=94770 Roman Numerals (by Mat)] - Integer to roman numerals.&lt;br /&gt;
* [http://www.autoitscript.com/forum/topic/123398-snippet-dump/page-3#entry1005157 Roman Numerals (by czardas)] - Roman Numerals.&lt;br /&gt;
* [http://www.autoitscript.com/forum/topic/94770-integer-to-roman-numerals/#entry1043544 Roman Numerals (by AZJIO)] - Roman Numerals.&lt;br /&gt;
&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=163899 StringAPL (by ... )] - inline APL interpreter.&lt;br /&gt;
&lt;br /&gt;
== Misc ==&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=90492 Hotkey.au3 (by ... )] - Management of Hotkeys UDF, with several advantages over HotkeySet().&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=97826 Animated tray icons (by ... )] - Make animated tray icons easily.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=101733 NoFocusLines (by Melba23)] - Remove the dotted focus lines from buttons, sliders, radios and checkboxes which spoil the look of your GUI.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=114034 StringSize (by Melba23)] - Automatically size controls to fit the text you want to put in them.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=162033 Spell Checker (by ... )] - Spell Checker UDF - Hunspell.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=125251 TVExplorer (by ... )] - TVExplorer UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=162366 BinaryCall (by ... )] - BinaryCall UDF - Write Subroutines In C, Call In AutoIt.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=161628 LFN (by ... )] - LFN UDF - overcome MAX_PATH limit of 256 chars.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=81267 Clipboard History/Sotrage (by ... )] - UDF to save and restore the entire clipboard contents.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=51103 Resources (by ... )] - Resources UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=162499 ResourcesEx (by ... )] - ResourcesEx UDF (up to date with the current AutoIt language syntax v3.3.12.0).&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=149176 NotifyIcon (by ... )] - NotifyIcon UDF (formerly TrayIconEx) - Create, delete and manage self notify icons.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=131037 Binary (by ... )] - Binary UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=99106 _DLLStructDisplay (by ... )] - Show Struct in ListView.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=55994 DDEML (by ... )] - With DDEML UDF one can use an AutoIt script as a DDE client or server.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=157689 _FileGetMimeType (by ... )] - _FileGetMimeType UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=157241 FindMimeFromData (by ... )] - FindMimeFromData using urlmon.dll.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=63318 PixelGetColor (by ... )] - Get or Read Pixel from Memory UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/topic/117033-file-locking-with-cooperative-semaphores File locking with cooperative semaphores (by ... )] - Simple file locking without a server.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=142977 SQLite Array Functions (by ... )] - SQLite Array Functions - a faster method for unique arrays and sorting methods.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=164444 Synology filestation (by ... )] - UDF for users of Synology NAS server.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=163577 Atom Table (by ... )] - Basically, a bunch of strings can be stored locally (at program level) or globally (at O/S level) with unique numerical identifiers. This UDF lets you add, find, delete, and query these atoms.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=121833 Copy (by ... )] - This small library allows simple and reliable way to copy or move files and directories without suspending your script. Moreover, you can get the current state (number of copied bytes, system error code, and other status information) while copying.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=86672 AutoIt Inline Assembly (by ... )] - &lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=111613 FASM (by ... )] - The Embedded Flat Assembler (FASM) UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=77463 MemoryDll (by ... )] - Embed DLLs in script and call functions from memory.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=167024 RDC (by ... )] - ReadDirectoryChanges Wrapper.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=170087 barcode-generators (by willichan )] - Creates a Code128A/B/C or Creates a Code39 or Code39Extended optimized barcode from supplied data.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=169610 CmdLine (by Jefrey )] - Collection of functions to parse command line arguments.&lt;br /&gt;
&lt;br /&gt;
== PDF ==&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=42776 PDFCreator (by ... )] - Automation of PDFCreator allows you to create and manipulate PDF files.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=160875 Debenu Quick PDF Library (by ... )] - A collection of functions for Debenu Quick PDF Library.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=118827 MPDF (by ... )] - Create PDF from your application.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=164469 Debenu PDF Viewer SDK (by ... )] - A collection of functions to display PDF files in your applications using Debenu PDF Viewer SDK.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=75832 FoxIt Reader (by ... )] - PDF Reader in AU3.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=32261 _StringToPDF (by ... )] - Write a string to a PDF file and specify font size, type etc.&lt;br /&gt;
&lt;br /&gt;
== Windows ==&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=145158 Firewall (by ... )] - Windows Firewall UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=158377 UAC (by ... )] - User Account Control (UAC) UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=50880 ACL (by ... )] - Set ACL on windows Objects.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=124508 Startup (by ... )] - Create Startup entries in the Startup Folder or Registry.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=74118 Local account (by ... )] - Local account UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=81880 Windows Services (by ... )] - Windows Services UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=111018 ITaskBarList (by ... )] - ITaskBarList UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=113560 FileSystemMonitor (by ... )] - FileSystemMonitor UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=161193 Magnifier Functions (by ... )] - Magnifier Functions - Windows Vista+ Magnifier Manipulation.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=163178 WRMF (by ... )] - WRMF - Windows Registry Monitor Call Function.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=75250 Registry (by ... )] - Windows Registry UDFs.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=50551 Registry (by ... )] - RegWriteAllUsers / RegDeleteAllUsers.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=134628 System restore (by ... )] - System restore UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=83355 Task Scheduler (by ... )] - Task Scheduler UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=135994 Taskplanner/Taskscheduler COM (by ... )] - an UDF for using the Windows Taskplaner / Task Scheduler&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=28436 Windows Events (by ... )] - Create your own Windows events.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=161193 Magnifier Functions (by ... )] - This UDF exposes most of the useful Magnifier API functions available since Windows Vista.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=127075 WIMGAPI (by ... )] - A UDF for manipulating Windows Image Files (.wim) without ImageX.exe.&lt;br /&gt;
&lt;br /&gt;
== Security ==&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=150819 VirusTotal (by ... )] - VirusTotal API 2.0 UDF.&lt;br /&gt;
&lt;br /&gt;
== Social Media and other Website API ==&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=116600 Twitter (by ... )] - Twitter UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=70675 iTunes (by ... )] - iTunes UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=101802 iTunes (by ... )] - another iTunes UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=149247 Yahoo Weather (by ... )] - YWeather UDF - Yahoo Weather API.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=115437 Google Maps (by ... )] - Google Maps UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=150473 Google API (by ... )] - JSON queries for Google API.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=131343 PasteBin (by ... )] - PasteBin (powered by PasteBin).&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=150838 PasteBin (by ... )] - Pastebin UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=114801 eBay (by ... )] - eBay UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=141340 Gmail (by ... )] - Remote Gmail (UDF).&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=150985 No-IP (by ... )] - With this UDF you can simply update your no-ip hostname(s) and retrive the ip address of an no-ip address.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=112775 Youtube Uploader (by ... )] - AYTU - AutoIt Youtube Uploader.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=98504 Google Functions (by ... )] - Google Functions.&lt;br /&gt;
* [http://www.autoitscript.com/forum/files/file/290-dropbox-authenticator/ Dropbox authenticator (by ... )] - Dropbox authenticator.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=166547 TVmaze.com API (by ... )] - TVmaze.com API UDF (TV-Series).&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=113234 Teamspeak 3 (by ... )] - Teamspeak 3 UDF.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=166205 TeamViewer API (by ... )] - UDF for TeamViewer API - a modest beginning.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=158106 Easypost (by ... )] - Print USPS Postage Labels.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=121767 Skype (by ... )] - Skype4COM provides an ActiveX interface to the Skype API.&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=169333 CrowdinAPI (by ... )] - This is UDF for connect with [https://crowdin.com/page/api crowdin.net website API] a couple of function, which allows you to create projects in Crowdin, add and update files, download translations or integrate localization with your development process.&lt;br /&gt;
&lt;br /&gt;
== Android ==&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=160936 Android (by ... )] - Android UDF.&lt;br /&gt;
&lt;br /&gt;
[[Category:UDF]]&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Moving_and_Resizing_PopUp_GUIs&amp;diff=12951</id>
		<title>Moving and Resizing PopUp GUIs</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Moving_and_Resizing_PopUp_GUIs&amp;diff=12951"/>
		<updated>2015-04-18T11:40:31Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorials]]&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
Many Autoit coders would like to use the &#039;&#039;$WS_POPUP&#039;&#039; style for a GUI but do not when they find that they can no longer move or resize the GUI because it has no title bar or borders to grab.  Here are four ways to move a &#039;&#039;$WS_POPUP&#039;&#039; GUI with the mouse as well as a way to resize it.&lt;br /&gt;
&lt;br /&gt;
Note:  I have garnered these methods from various places on the forum and I am afraid I do not remember all the original authors of the code in this tutorial.  If you see your uncredited code here, please add your own credit line.&lt;br /&gt;
&lt;br /&gt;
=Moving a $WS_POPUP GUI=&lt;br /&gt;
&lt;br /&gt;
The four methods have, as you would expect, advantages and diadvantages.  Some are easier to use than others - some have side-effects on the GUI, others do not.  Try them all and then decide which is best for your particular script. For all examples, the green area shows where dragging is possible and the red area (if there is one) where it is not; clicking the button will bring up a message box; and pressing &amp;quot;&#039;&#039;Escape&#039;&#039;&amp;quot; always exits the script.&lt;br /&gt;
&lt;br /&gt;
==Method 1: $GUI_WS_EX_PARENTDRAG==&lt;br /&gt;
&lt;br /&gt;
This method uses a label on the GUI to act as a drag anchor.  It is easy to set up, but as the label must be active, you can run into overlap problems with other controls - just try clicking on the top half of the button or see what happens when you try to drag the GUI when the button does not fire.  If you disable the label, you will see that the button works normally but you can no longer drag the GUI.  So although this is the simplest method, it is the least satisfactory - although it can be useful in certain cases.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GuiconstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;WindowsConstants.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 HotKeySet(&amp;quot;{ESC}&amp;quot;, &amp;quot;On_Exit&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;X&amp;quot;, 100, 100, -1, -1, $WS_POPUP)&lt;br /&gt;
 GUISetBkColor(0xFF0000, $hGUI)&lt;br /&gt;
 $hLabel = GUICtrlCreateLabel(&amp;quot;&amp;quot;, 0, 0, 100, 50, -1, $GUI_WS_EX_PARENTDRAG)&lt;br /&gt;
 GUICtrlSetBkColor(-1, 0x00FF00)&lt;br /&gt;
 ;GUICtrlSetState(-1, $GUI_DISABLE)&lt;br /&gt;
 $hButton = GUICtrlCreateButton(&amp;quot;Test&amp;quot;, 10, 35, 80, 30)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $hButton&lt;br /&gt;
             On_Button()&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func On_Button()&lt;br /&gt;
     MsgBox(0, &amp;quot;Hi&amp;quot;, &amp;quot;Button Pressed&amp;quot;)&lt;br /&gt;
 EndFunc   ;==&amp;gt;On_Button&lt;br /&gt;
 &lt;br /&gt;
 Func On_Exit()&lt;br /&gt;
     Exit&lt;br /&gt;
 EndFunc   ;==&amp;gt;On_Exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Method 2: Sending the $SC_DRAGMOVE message==&lt;br /&gt;
&lt;br /&gt;
Here we send a message when the primary mouse button is pressed to tell Windows to drag the GUI with the mouse.  Note that the button works without problem.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 ; Original code - martin&lt;br /&gt;
 #include &amp;lt;GuiconstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;WindowsConstants.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;SendMessage.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Global Const $SC_DRAGMOVE = 0xF012&lt;br /&gt;
 &lt;br /&gt;
 HotKeySet(&amp;quot;{ESC}&amp;quot;, &amp;quot;On_Exit&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;X&amp;quot;, 100, 100, -1, -1, $WS_POPUP)&lt;br /&gt;
 GUISetBkColor(0x00FF00, $hGUI)&lt;br /&gt;
 $hButton = GUICtrlCreateButton(&amp;quot;Test&amp;quot;, 10, 35, 80, 30)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_PRIMARYDOWN&lt;br /&gt;
             _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)&lt;br /&gt;
         Case $hButton&lt;br /&gt;
             On_Button()&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func On_Button()&lt;br /&gt;
     MsgBox(0, &amp;quot;Hi&amp;quot;, &amp;quot;Button Pressed&amp;quot;)&lt;br /&gt;
 EndFunc   ;==&amp;gt;On_Button&lt;br /&gt;
 &lt;br /&gt;
 Func On_Exit()&lt;br /&gt;
     Exit&lt;br /&gt;
 EndFunc   ;==&amp;gt;On_Exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Method 3: Sending the &#039;&#039;$WM_NCLBUTTONDOWN&#039;&#039; message==&lt;br /&gt;
&lt;br /&gt;
In this example, we also detect when the primary mouse button is down.  We then fool Windows into believing that the cursor is not in the client area of the GUI but is actually in the title bar - Windows reacts as we hoped by dragging the GUI.  Again the button works without problem as Windows realises it is a control.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GuiconstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;WindowsConstants.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;SendMessage.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 HotKeySet(&amp;quot;{ESC}&amp;quot;, &amp;quot;On_Exit&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;X&amp;quot;, 100, 100, -1, -1, $WS_POPUP)&lt;br /&gt;
 GUISetBkColor(0x00FF00, $hGUI)&lt;br /&gt;
 $hButton = GUICtrlCreateButton(&amp;quot;Test&amp;quot;, 10, 35, 80, 30)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_PRIMARYDOWN&lt;br /&gt;
             On_Drag()&lt;br /&gt;
         Case $hButton&lt;br /&gt;
             On_Button()&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func On_Drag()&lt;br /&gt;
     Local $aCurInfo = GUIGetCursorInfo($hGUI)&lt;br /&gt;
     If $aCurInfo[4] = 0 Then ; Mouse not over a control&lt;br /&gt;
         DllCall(&amp;quot;user32.dll&amp;quot;, &amp;quot;int&amp;quot;, &amp;quot;ReleaseCapture&amp;quot;)&lt;br /&gt;
         _SendMessage($hGUI, $WM_NCLBUTTONDOWN, $HTCAPTION, 0)&lt;br /&gt;
     EndIf&lt;br /&gt;
 EndFunc   ;==&amp;gt;On_Drag&lt;br /&gt;
 &lt;br /&gt;
 Func On_Exit()&lt;br /&gt;
     Exit&lt;br /&gt;
 EndFunc   ;==&amp;gt;On_Exit&lt;br /&gt;
 &lt;br /&gt;
 Func On_Button()&lt;br /&gt;
      MsgBox(0, &amp;quot;Hi&amp;quot;, &amp;quot;Button Pressed&amp;quot;)&lt;br /&gt;
 EndFunc   ;==&amp;gt;On_Button&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&#039;&#039;Note&#039;&#039;:  The remainder of this tutorial assumes knowledge of the &#039;&#039;GUIRegisterMsg&#039;&#039; command.  If you are not clear on the use of this command, please read the [[Tutorial GUIRegisterMsg|GUIRegisterMsg]] tutorial before continuing.&lt;br /&gt;
&lt;br /&gt;
==Method 4: Handling the $WM_NCHITTEST message==&lt;br /&gt;
&lt;br /&gt;
This final method intercepts the &#039;&#039;$WM_NCHITTEST&#039;&#039; message, which basically tells Windows what part of the GUI is under the mouse when a button is pressed.  If the mouse is over the title bar, then Windows will drag the GUI.  In this script we tell Windows that the top half of the GUI is a title bar and so would Windows please drag as normal.  The coloured label is just there to differentiate between the 2 areas and has been disabled so as not to interfere with the button - which works normally as Windows realises it is a control and not part of the GUI.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GuiconstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;WindowsConstants.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;SendMessage.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 HotKeySet(&amp;quot;{ESC}&amp;quot;, &amp;quot;On_Exit&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;X&amp;quot;, 100, 100, -1, -1, $WS_POPUP)&lt;br /&gt;
 GUISetBkColor(0x00FF00, $hGUI)&lt;br /&gt;
 GUICtrlCreateLabel(&amp;quot;&amp;quot;, 0, 50, 100, 50)&lt;br /&gt;
 GUICtrlSetBkColor(-1, 0xFF0000)&lt;br /&gt;
 GUICtrlSetState(-1, $GUI_DISABLE)&lt;br /&gt;
 $hButton = GUICtrlCreateButton(&amp;quot;Test&amp;quot;, 10, 35, 80, 30)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 GUIRegisterMsg($WM_NCHITTEST, &amp;quot;_MY_NCHITTEST&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $hButton&lt;br /&gt;
             On_Button()&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 ; Original code - Prog@ndy&lt;br /&gt;
 Func _MY_NCHITTEST($hWnd, $uMsg, $wParam, $lParam)&lt;br /&gt;
     Switch $hWnd&lt;br /&gt;
         Case $hGUI&lt;br /&gt;
             Local $aPos = WinGetPos($hWnd) ; Check if mouse is over top 50 pixels&lt;br /&gt;
             If Abs(BitAND(BitShift($lParam, 16), 0xFFFF) - $aPos[1]) &amp;lt; 50 Then Return $HTCAPTION&lt;br /&gt;
     EndSwitch&lt;br /&gt;
     Return $GUI_RUNDEFMSG&lt;br /&gt;
 EndFunc   ;==&amp;gt;_MY_NCHITTEST&lt;br /&gt;
 &lt;br /&gt;
 Func On_Button()&lt;br /&gt;
     MsgBox(0, &amp;quot;Hi&amp;quot;, &amp;quot;Button Pressed&amp;quot;)&lt;br /&gt;
 EndFunc   ;==&amp;gt;On_Button&lt;br /&gt;
 &lt;br /&gt;
 Func On_Exit()&lt;br /&gt;
     Exit&lt;br /&gt;
 EndFunc   ;==&amp;gt;On_Exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Resizing a $WS_POPUP GUI=&lt;br /&gt;
&lt;br /&gt;
To resize a GUI without borders, we have to fool Windows into thinking that the borders actually exist.  We do this by telling Windows to change the cursor to the &amp;quot;&#039;&#039;resize&#039;&#039;&amp;quot; type if the mouse is placed over the margin of the GUI.  Then when primary mouse button is pressed, we check if the cursor has been changed and, if it has, tell Windows to resize the GUI.&lt;br /&gt;
&lt;br /&gt;
The various message handlers interact as follows:&lt;br /&gt;
&lt;br /&gt;
When we receive a &#039;&#039;$WM_MOUSEMOVE&#039;&#039; message, we check if the mouse is over a border by calling the &#039;&#039;_Check_Border&#039;&#039; function, which returns a code to indicate which cursor type is required, and then using that return to set the correct cursor type within the &#039;&#039; _SetCursor&#039;&#039; function.&lt;br /&gt;
&lt;br /&gt;
Then if a &#039;&#039;$WM_LBUTTONDOWN&#039;&#039; message is received we again check the &#039;&#039;_Check_Border&#039;&#039; function and, if we are over a border, tell Windows to resize the GUI as the mouse is dragged.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 ; Original code - martin&lt;br /&gt;
 #include &amp;lt;GuiConstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;Windowsconstants.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;SendMessage.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 HotKeySet(&amp;quot;{ESC}&amp;quot;, &amp;quot;On_Exit&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Set distance from edge of window where resizing is possible&lt;br /&gt;
 Global Const $iMargin = 4&lt;br /&gt;
 &lt;br /&gt;
 ; Create GUI&lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Y&amp;quot;, 100, 100, -1, -1, $WS_POPUP)&lt;br /&gt;
 GUISetBkColor(0xFF0000)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; Register message handlers&lt;br /&gt;
 GUIRegisterMsg($WM_LBUTTONDOWN, &amp;quot;_WM_LBUTTONDOWN&amp;quot;)     ; For resize&lt;br /&gt;
 GUIRegisterMsg($WM_MOUSEMOVE, &amp;quot;_SetCursor&amp;quot;)            ; For cursor type change&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Sleep(10)&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 ; Check cursor type and resize/drag window as required&lt;br /&gt;
 Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)&lt;br /&gt;
     Local $iCursorType = _GetBorder()&lt;br /&gt;
     If $iCursorType &amp;gt; 0 Then ; Cursor is set to resizing style&lt;br /&gt;
         $iResizeType = 0xF000 + $iCursorType&lt;br /&gt;
         _SendMessage($hGUI, $WM_SYSCOMMAND, $iResizeType, 0)&lt;br /&gt;
     EndIf&lt;br /&gt;
 EndFunc ;==&amp;gt;WM_LBUTTONDOWN&lt;br /&gt;
 &lt;br /&gt;
 ; Set cursor to correct resizing form if mouse is over a border&lt;br /&gt;
 Func _SetCursor()&lt;br /&gt;
     Local $iCursorID&lt;br /&gt;
     Switch _GetBorder()&lt;br /&gt;
         Case 0&lt;br /&gt;
             $iCursorID = 2&lt;br /&gt;
         Case 1, 2&lt;br /&gt;
             $iCursorID = 13&lt;br /&gt;
         Case 3, 6&lt;br /&gt;
             $iCursorID = 11&lt;br /&gt;
         Case 5, 7&lt;br /&gt;
             $iCursorID = 10&lt;br /&gt;
         Case 4, 8&lt;br /&gt;
             $iCursorID = 12&lt;br /&gt;
     EndSwitch&lt;br /&gt;
     GUISetCursor($iCursorID, 1)&lt;br /&gt;
 EndFunc ;==&amp;gt;SetCursor&lt;br /&gt;
 &lt;br /&gt;
 ; Determines if mouse cursor over a border&lt;br /&gt;
 Func _GetBorder()&lt;br /&gt;
     Local $aCurInfo = GUIGetCursorInfo()&lt;br /&gt;
     Local $aWinPos = WinGetPos($hGUI)&lt;br /&gt;
     Local $iSide = 0&lt;br /&gt;
     Local $iTopBot = 0&lt;br /&gt;
     If $aCurInfo[0] &amp;lt; $iMargin Then $iSide = 1&lt;br /&gt;
     If $aCurInfo[0] &amp;gt; $aWinPos[2] - $iMargin Then $iSide = 2&lt;br /&gt;
     If $aCurInfo[1] &amp;lt; $iMargin Then $iTopBot = 3&lt;br /&gt;
     If $aCurInfo[1] &amp;gt; $aWinPos[3] - $iMargin Then $iTopBot = 6&lt;br /&gt;
     Return $iSide + $iTopBot&lt;br /&gt;
 EndFunc ;==&amp;gt;_GetBorder&lt;br /&gt;
 &lt;br /&gt;
 Func On_Exit()&lt;br /&gt;
 	Exit&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Moving and resizing a $WS_POPUP GUI=&lt;br /&gt;
&lt;br /&gt;
Of the three serious methods for dragging a &#039;&#039;$WS_POPUP&#039;&#039; GUI, only two can be combined with the resize code.  The &#039;&#039;$WM_NCHITTEST&#039;&#039; message version is unsuitable as it prevents the detection of the simulated borders.  The other 2 methods both use the &#039;&#039;$GUI_EVENT_PRIMARYDOWN&#039;&#039; message within the &#039;&#039;GUIGetMsg&#039;&#039; loop to detect the primary mouse button being pressed, but we could also use the &#039;&#039;$WM_LBUTTONDOWN&#039;&#039; message we use when resizing the GUI to do the same thing.  All we need to do is to check the cursor position and so the required cursor type: if it is greater than 0 we have a resize cursor - if it is 0 then we have a normal cursor and should drag the whole GUI.&lt;br /&gt;
&lt;br /&gt;
As an &#039;&#039;added bonus&#039;&#039; because you have been kind enough to read until there, the following examples also show how to set the maximum and minimum size of a resizable GUI via the &#039;&#039;$WM_GETMINMAXINFO&#039;&#039; message.  We simply make sure we set our own limits every time Windows checks to see when it should stop resizing.&lt;br /&gt;
&lt;br /&gt;
So here are the 2 scripts - first using the &#039;&#039;$SC_DRAGMOVE&#039;&#039; message&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GuiConstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;Windowsconstants.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;SendMessage.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Global Const $SC_DRAGMOVE = 0xF012&lt;br /&gt;
 &lt;br /&gt;
 HotKeySet(&amp;quot;{ESC}&amp;quot;, &amp;quot;On_Exit&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Set distance from edge of window where resizing is possible&lt;br /&gt;
 Global Const $iMargin = 4&lt;br /&gt;
 ; Set max and min GUI sizes&lt;br /&gt;
 Global Const $iGUIMinX = 50, $iGUIMinY = 50, $iGUIMaxX = 300, $iGUIMaxY = 300&lt;br /&gt;
 &lt;br /&gt;
 ; Create GUI&lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Y&amp;quot;, 100, 100, -1, -1, $WS_POPUP)&lt;br /&gt;
 GUISetBkColor(0x00FF00)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; Register message handlers&lt;br /&gt;
 GUIRegisterMsg($WM_MOUSEMOVE, &amp;quot;_SetCursor&amp;quot;)            ; For cursor type change&lt;br /&gt;
 GUIRegisterMsg($WM_LBUTTONDOWN, &amp;quot;_WM_LBUTTONDOWN&amp;quot;)     ; For resize/drag&lt;br /&gt;
 GUIRegisterMsg($WM_GETMINMAXINFO, &amp;quot;_WM_GETMINMAXINFO&amp;quot;) ; For GUI size limits&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Sleep(10)&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 ; Set cursor to correct resizing form if mouse is over a border&lt;br /&gt;
 Func _SetCursor()&lt;br /&gt;
     Local $iCursorID&lt;br /&gt;
     Switch _Check_Border()&lt;br /&gt;
         Case 0&lt;br /&gt;
             $iCursorID = 2&lt;br /&gt;
         Case 1, 2&lt;br /&gt;
             $iCursorID = 13&lt;br /&gt;
         Case 3, 6&lt;br /&gt;
             $iCursorID = 11&lt;br /&gt;
         Case 5, 7&lt;br /&gt;
             $iCursorID = 10&lt;br /&gt;
         Case 4, 8&lt;br /&gt;
             $iCursorID = 12&lt;br /&gt;
     EndSwitch&lt;br /&gt;
     GUISetCursor($iCursorID, 1)&lt;br /&gt;
 EndFunc ;==&amp;gt;SetCursor&lt;br /&gt;
 &lt;br /&gt;
 ; Check cursor type and resize/drag window as required&lt;br /&gt;
 Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)&lt;br /&gt;
     Local $iCursorType = _Check_Border()&lt;br /&gt;
     If $iCursorType &amp;gt; 0 Then ; Cursor is set to resizing style so send appropriate resize message&lt;br /&gt;
         $iResizeType = 0xF000 + $iCursorType&lt;br /&gt;
         _SendMessage($hGUI, $WM_SYSCOMMAND, $iResizeType, 0)&lt;br /&gt;
     Else&lt;br /&gt;
         Local $aCurInfo = GUIGetCursorInfo($hGUI)&lt;br /&gt;
         If $aCurInfo[4] = 0 Then ; Mouse not over a control&lt;br /&gt;
             _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)&lt;br /&gt;
         EndIf&lt;br /&gt;
     EndIf&lt;br /&gt;
 EndFunc ;==&amp;gt;WM_LBUTTONDOWN&lt;br /&gt;
 &lt;br /&gt;
 ; Determines if mouse cursor over a border&lt;br /&gt;
 Func _Check_Border()&lt;br /&gt;
     Local $aCurInfo = GUIGetCursorInfo()&lt;br /&gt;
     If @error Then Return -1&lt;br /&gt;
     Local $aWinPos = WinGetPos($hGUI)&lt;br /&gt;
     Local $iSide = 0&lt;br /&gt;
     Local $iTopBot = 0&lt;br /&gt;
     If $aCurInfo[0] &amp;lt; $iMargin Then $iSide = 1&lt;br /&gt;
     If $aCurInfo[0] &amp;gt; $aWinPos[2] - $iMargin Then $iSide = 2&lt;br /&gt;
     If $aCurInfo[1] &amp;lt; $iMargin Then $iTopBot = 3&lt;br /&gt;
     If $aCurInfo[1] &amp;gt; $aWinPos[3] - $iMargin Then $iTopBot = 6&lt;br /&gt;
     Return $iSide + $iTopBot&lt;br /&gt;
 EndFunc ;==&amp;gt;_Check_Border&lt;br /&gt;
 &lt;br /&gt;
 ; Set min and max GUI sizes&lt;br /&gt;
 Func _WM_GETMINMAXINFO($hWnd, $iMsg, $wParam, $lParam)&lt;br /&gt;
     $tMinMaxInfo = DllStructCreate(&amp;quot;int;int;int;int;int;int;int;int;int;int&amp;quot;, $lParam)&lt;br /&gt;
     DllStructSetData($tMinMaxInfo,  7, $iGUIMinX)&lt;br /&gt;
     DllStructSetData($tMinMaxInfo,  8, $iGUIMinY)&lt;br /&gt;
     DllStructSetData($tMinMaxInfo,  9, $iGUIMaxX)&lt;br /&gt;
     DllStructSetData($tMinMaxInfo, 10, $iGUIMaxY)&lt;br /&gt;
     Return 0&lt;br /&gt;
 EndFunc   ;==&amp;gt;_WM_GETMINMAXINFO&lt;br /&gt;
 &lt;br /&gt;
 Func On_Exit()&lt;br /&gt;
     Exit&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
And now using the &#039;&#039;$WM_NCLBUTTONDOWN&#039;&#039; message&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GuiConstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;Windowsconstants.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;SendMessage.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 HotKeySet(&amp;quot;{ESC}&amp;quot;, &amp;quot;On_Exit&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Set distance from edge of window where resizing is possible&lt;br /&gt;
 Global Const $iMargin = 4&lt;br /&gt;
 ; Set max and min GUI sizes&lt;br /&gt;
 Global Const $iGUIMinX = 50, $iGUIMinY = 50, $iGUIMaxX = 300, $iGUIMaxY = 300&lt;br /&gt;
 &lt;br /&gt;
 ; Create GUI&lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Y&amp;quot;, 100, 100, -1, -1, $WS_POPUP)&lt;br /&gt;
 GUISetBkColor(0x00FF00)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; Register message handlers&lt;br /&gt;
 GUIRegisterMsg($WM_LBUTTONDOWN, &amp;quot;_WM_LBUTTONDOWN&amp;quot;)     ; For resize/drag&lt;br /&gt;
 GUIRegisterMsg($WM_MOUSEMOVE, &amp;quot;_SetCursor&amp;quot;)            ; For cursor type change&lt;br /&gt;
 GUIRegisterMsg($WM_GETMINMAXINFO, &amp;quot;_WM_GETMINMAXINFO&amp;quot;) ; For GUI size limits&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Sleep(10)&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 ; Check cursor type and resize/drag window as required&lt;br /&gt;
 Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)&lt;br /&gt;
     Local $iCursorType = _GetBorder()&lt;br /&gt;
     If $iCursorType &amp;gt; 0 Then ; Cursor is set to resizing style&lt;br /&gt;
         $iResizeType = 0xF000 + $iCursorType&lt;br /&gt;
         _SendMessage($hGUI, $WM_SYSCOMMAND, $iResizeType, 0)&lt;br /&gt;
     Else&lt;br /&gt;
         Local $aCurInfo = GUIGetCursorInfo($hGUI)&lt;br /&gt;
         If $aCurInfo[4] = 0 Then ; Mouse not over a control&lt;br /&gt;
             DllCall(&amp;quot;user32.dll&amp;quot;, &amp;quot;int&amp;quot;, &amp;quot;ReleaseCapture&amp;quot;)&lt;br /&gt;
             _SendMessage($hGUI, $WM_NCLBUTTONDOWN, $HTCAPTION, 0)&lt;br /&gt;
         EndIf&lt;br /&gt;
    EndIf&lt;br /&gt;
 EndFunc ;==&amp;gt;WM_LBUTTONDOWN&lt;br /&gt;
 &lt;br /&gt;
 ; Set cursor to correct resizing form if mouse is over a border&lt;br /&gt;
 Func _SetCursor()&lt;br /&gt;
     Local $iCursorID&lt;br /&gt;
     Switch _GetBorder()&lt;br /&gt;
         Case 0&lt;br /&gt;
             $iCursorID = 2&lt;br /&gt;
         Case 1, 2&lt;br /&gt;
             $iCursorID = 13&lt;br /&gt;
         Case 3, 6&lt;br /&gt;
             $iCursorID = 11&lt;br /&gt;
         Case 5, 7&lt;br /&gt;
             $iCursorID = 10&lt;br /&gt;
         Case 4, 8&lt;br /&gt;
             $iCursorID = 12&lt;br /&gt;
     EndSwitch&lt;br /&gt;
     GUISetCursor($iCursorID, 1)&lt;br /&gt;
 EndFunc ;==&amp;gt;SetCursor&lt;br /&gt;
 &lt;br /&gt;
 ; Determines if mouse cursor over a border&lt;br /&gt;
 Func _GetBorder()&lt;br /&gt;
     Local $aCurInfo = GUIGetCursorInfo()&lt;br /&gt;
     If @error Then Return -1&lt;br /&gt;
     Local $aWinPos = WinGetPos($hGUI)&lt;br /&gt;
     Local $iSide = 0&lt;br /&gt;
     Local $iTopBot = 0&lt;br /&gt;
     If $aCurInfo[0] &amp;lt; $iMargin Then $iSide = 1&lt;br /&gt;
     If $aCurInfo[0] &amp;gt; $aWinPos[2] - $iMargin Then $iSide = 2&lt;br /&gt;
     If $aCurInfo[1] &amp;lt; $iMargin Then $iTopBot = 3&lt;br /&gt;
     If $aCurInfo[1] &amp;gt; $aWinPos[3] - $iMargin Then $iTopBot = 6&lt;br /&gt;
     Return $iSide + $iTopBot&lt;br /&gt;
 EndFunc ;==&amp;gt;_GetBorder&lt;br /&gt;
 &lt;br /&gt;
 ; Set min and max GUI sizes&lt;br /&gt;
 Func _WM_GETMINMAXINFO($hWnd, $iMsg, $wParam, $lParam)&lt;br /&gt;
     $tMinMaxInfo = DllStructCreate(&amp;quot;int;int;int;int;int;int;int;int;int;int&amp;quot;, $lParam)&lt;br /&gt;
     DllStructSetData($tMinMaxInfo,  7, $iGUIMinX)&lt;br /&gt;
     DllStructSetData($tMinMaxInfo,  8, $iGUIMinY)&lt;br /&gt;
     DllStructSetData($tMinMaxInfo,  9, $iGUIMaxX)&lt;br /&gt;
     DllStructSetData($tMinMaxInfo, 10, $iGUIMaxY)&lt;br /&gt;
     Return 0&lt;br /&gt;
 EndFunc   ;==&amp;gt;_WM_GETMINMAXINFO&lt;br /&gt;
 &lt;br /&gt;
 Func On_Exit()&lt;br /&gt;
     Exit&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Summary=&lt;br /&gt;
&lt;br /&gt;
Although it seems impossible to move and resize &#039;&#039;$WS_POPUP&#039;&#039; style GUIs because they lack the usual title bar and borders, you can se that it is not that difficult to do it.  All we do is mimic what Windows does to a normal GUI.&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Adding_UDFs_to_AutoIt_and_SciTE&amp;diff=12782</id>
		<title>Adding UDFs to AutoIt and SciTE</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Adding_UDFs_to_AutoIt_and_SciTE&amp;diff=12782"/>
		<updated>2015-02-24T09:59:14Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:SciTE]][[Category:UDF]]&lt;br /&gt;
The ability to download UDFs created by other users is one of the major advantages of AutoIt, but are you one of the many coders who just add these UDFs to the existing &amp;quot;&#039;&#039;Include&#039;&#039;&amp;quot; folder which contains the standard UDFS distributed with AutoIt?  If so then there is much better way to do it - one which will prevent you from losing all of these additional UDFs when you upgrade.  Just use a user-defined folder to store all your UDFs - AutoIt makes this very easy to do.&lt;br /&gt;
&lt;br /&gt;
=Creating a Personal Include Folder=&lt;br /&gt;
&lt;br /&gt;
Begin by creating a new folder to hold the additional UDFs - it is recommended that you do &#039;&#039;&#039;NOT&#039;&#039;&#039; put this folder in the AutoIt install folder (or it will get overwritten when you upgrade).  Then tell AutoIt about this folder.&lt;br /&gt;
&lt;br /&gt;
- If you have &#039;&#039;SciTE4AutoIt3&#039;&#039; you can use &#039;&#039;&#039;SciTEConfig&#039;&#039;&#039; - look for the &#039;&#039;User Include Dir&#039;&#039; input about 2/3 way down the dialog. &lt;br /&gt;
&lt;br /&gt;
- If not (and why not? You can download it from here[http://www.autoitscript.com/site/autoit-script-editor/downloads/]) you need to modify the registry directly as explained on the &amp;quot;&#039;&#039;Include&#039;&#039;&amp;quot; page of the Help file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 There is a special registry value that can be created at &amp;quot;HKEY_CURRENT_USER\Software\AutoIt v3\AutoIt&amp;quot; called &amp;quot;Include&amp;quot;.&lt;br /&gt;
 It should be a REG_SZ (string) value.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;CYA Note&#039;&#039;&#039;: Normal precautions are advised if modifying the registry. &lt;br /&gt;
&lt;br /&gt;
You now have a folder to store modified, downloaded or personal UDFs which are available to use with no need to specify the path and which will not be &lt;br /&gt;
lost on upgrade.  &lt;br /&gt;
&lt;br /&gt;
=Adding CallTips  and AutoComplete=&lt;br /&gt;
&lt;br /&gt;
But to make coding with these UDFs even easier you can also add &#039;&#039;&#039;CallTips&#039;&#039;&#039; and &#039;&#039;&#039;AutoComplete&#039;&#039;&#039; for them.&lt;br /&gt;
&lt;br /&gt;
As you might expect, the full &#039;&#039;SciTE4AutoIt3&#039;&#039; package makes it easy - have you downloaded and installed it yet? If you have then just open &#039;&#039;&#039;SciTEConfig&#039;&#039;&#039; on the &#039;&#039;&#039;Other Tools&#039;&#039;&#039; tab and press &#039;&#039;&#039;Run User Call Tip Manager&#039;&#039;&#039;.  Then you just need to select the UDF file to add and everything is done for you automatically.  Full instructions on using the &#039;&#039;User Call Tip Manager&#039;&#039; are found in the &#039;&#039;SciTE4AutoIt3&#039;&#039; Help file under &#039;&#039;&amp;lt;Extra Utilities&amp;gt;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
But if you want to do it manually (which is &#039;&#039;&#039;not&#039;&#039;&#039; recommended):&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Calltips&#039;&#039;&#039; first. These are stored in &#039;&#039;&amp;lt;Your_User_Profile&amp;gt;\au3.user.calltips.api&#039;&#039;.  If you are doing this for the first time then this file will not exist and you will have to create it.  Then add a line like this to the file for each function you wish to have a calltip:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 _Function($param1, $param2, $param3) Explanation of function (Requires: #Include UDF.au3)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Of course you need to change the &#039;&#039;Function, $param&#039;&#039; and &#039;&#039;UDF&#039;&#039; words to the correct values for the UDF function you want to include.&lt;br /&gt;
&lt;br /&gt;
Now &#039;&#039;&#039;AutoComplete&#039;&#039;&#039;. Again a special file is used &#039;&#039;&amp;lt;Your_User_Profile&amp;gt;\au3.userudfs.properties&#039;&#039; - again you will have to create it initially - which should read as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 au3.keywords.user.udfs=_function1 _function2 _function3 _function4 \&lt;br /&gt;
        _function5 _function6 _function7&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note that the entries are all in lowercase and all lines other than the first begin with a &#039;&#039;@TAB&#039;&#039; character.&lt;br /&gt;
&lt;br /&gt;
Then save all files, close and restart SciTE. You will have &#039;&#039;&#039;AutoComplete&#039;&#039;&#039; when you start typing the UDF function name in a script and a syntax &#039;&#039;&#039;CallTip&#039;&#039;&#039; as you enter the parameters.   These files are not overwritten when you update SciTE so all your hard work to set this up should be a once-only event.&lt;br /&gt;
&lt;br /&gt;
One final thing.  If you want the &amp;quot;&#039;&#039;Tools - Open Include&#039;&#039;&amp;quot; menu item in SciTE to work on the files within this new folder you need to add the following lines to your &amp;quot;&#039;&#039;SciTEUser.properties&#039;&#039;&amp;quot; file - you open it by using the &amp;lt;&#039;&#039;Options - Open User Options File&#039;&#039;&amp;gt; menu item:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 openpath.$(au3)=$(autoit3dir)\include;Your_Folder_Path&lt;br /&gt;
 openpath.beta.$(au3)=$(autoit3dir)\beta\include;Your_Folder_Path&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Now you are all set - your personal include files are as accessible as the standard set.&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Variables_-_using_Global,_Local,_Static_and_ByRef&amp;diff=11957</id>
		<title>Variables - using Global, Local, Static and ByRef</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Variables_-_using_Global,_Local,_Static_and_ByRef&amp;diff=11957"/>
		<updated>2013-11-05T08:38:03Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorials]]&lt;br /&gt;
These keywords confuse many coders - this tutorial should help make their use clear.&lt;br /&gt;
&lt;br /&gt;
In most programming languages you can define the scope of variables - this determines the visibility or accessibility of the variable from different parts of the program. &lt;br /&gt;
&lt;br /&gt;
In AutoIt there are two possible scopes: &#039;&#039;Global&#039;&#039; and &#039;&#039;Local&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
- A &#039;&#039;&#039;Global&#039;&#039;&#039; variable is visible throughout your script - any part of the script can both read its value and, importantly, change it.&lt;br /&gt;
&lt;br /&gt;
- A &#039;&#039;&#039;Local&#039;&#039;&#039; variable exists only within the function in which it is declared and is destroyed when the function terminates.  It is invisible to any other function unless it is passed as a parameter.&lt;br /&gt;
&lt;br /&gt;
Additionally declaring a variable as &#039;&#039;&#039;Static&#039;&#039;&#039; changes its behaviour slightly.  A &#039;&#039;Global Static&#039;&#039; variable serves no useful purpose as it is essentially the same as a normal &#039;&#039;Global&#039;&#039; variable.  However, a &#039;&#039;Local Static&#039;&#039; variable exists only within the function in which it is declared, but is NOT destroyed when the function ends and can be reused when the function is next entered.  You can assign an initial value to this variable when it is created - if it is already in existence then the assignment is ignored.  Note that the order of the keywords is not important.&lt;br /&gt;
&lt;br /&gt;
Why do we need to scope variables?  Well, it is often useful to have a single variable used throughout the script - perhaps the name of an Ini file which if declared as &#039;&#039;Global&#039;&#039; can then be read by any function that requires it. And &#039;&#039;Local&#039;&#039; variables allow us to save resources by only using variables as long as we need - for example if we create a large array which is only needed within a single function.&lt;br /&gt;
&lt;br /&gt;
We scope variables by using the &#039;&#039;Global, Local&#039;&#039; and &#039;&#039;Static&#039;&#039; keywords when the variables are first declared - look at the examples below.  By default, AutoIt scopes any variables declared in the main body of a script (that is not between a &#039;&#039;Func&#039;&#039; and &#039;&#039;EndFunc&#039;&#039; pair) as &#039;&#039;Global&#039;&#039; and any variables declared within function declarations as &#039;&#039;Local&#039;&#039;. But it is a good idea to explicitly declare your variables to make sure that you get what you want.  For example, you can declare a variable as &#039;&#039;Global&#039;&#039; within a function - although you may get a gentle reminder when you run your script within SciTE that this is not recommended.  But there is no point declaring any variables in the main body of a script as &#039;&#039;Local&#039;&#039; - they will be &#039;&#039;Global&#039;&#039; regardless.  If you use the &#039;&#039;AutoItSetOption(&amp;quot;MustDeclareVars&amp;quot;, 1)&#039;&#039; directive you &#039;&#039;must&#039;&#039; declare the scope of your variables or you will get error messages.&lt;br /&gt;
&lt;br /&gt;
In the Help file pages for &#039;&#039;Global, Local&#039;&#039; and &#039;&#039;Static&#039;&#039; you will also see mention of &#039;&#039;Dim&#039;&#039; and &#039;&#039;ReDim&#039;&#039;.  Using &#039;&#039;Dim&#039;&#039; will declare a variable and satisfy the &#039;&#039;AutoItSetOption&#039;&#039; just mentioned, but will let AutoIt scope the variable using the default settings as described above.  It is much better practice to use &#039;&#039;Global&#039;&#039; or &#039;&#039;Local&#039;&#039; to set the scope you require explicitly.  Despite its similar name, &#039;&#039;ReDim&#039;&#039; is only used to resize arrays without destroying the content and is outside the scope of this tutorial.&lt;br /&gt;
&lt;br /&gt;
Let us now look at a simple example when we read and change &#039;&#039;Global&#039;&#039; variables in a function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;Constants.au3&amp;gt; ; only required for MsgBox constants&lt;br /&gt;
&lt;br /&gt;
 Global $Var_1 = &amp;quot;Variable 1&amp;quot;&lt;br /&gt;
 Global $Var_2 = &amp;quot;Variable 2&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; Read the variables&lt;br /&gt;
 MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Reading&amp;quot;, &amp;quot;In The Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1 &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 2 = &amp;quot; &amp;amp; $Var_2)&lt;br /&gt;
 &lt;br /&gt;
 ; Read the variables in a function&lt;br /&gt;
 _Function()&lt;br /&gt;
 &lt;br /&gt;
 ; And now read the variables again - see that $iVar_2 has changed&lt;br /&gt;
 MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Reading&amp;quot;, &amp;quot;Back In The Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1 &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 2 = &amp;quot; &amp;amp; $Var_2)&lt;br /&gt;
 &lt;br /&gt;
 Func _Function()&lt;br /&gt;
 	; Read the variables&lt;br /&gt;
 	MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Reading&amp;quot;, &amp;quot;In The Function&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1 &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 2 = &amp;quot; &amp;amp; $Var_2)&lt;br /&gt;
 	; Now let us change one of the variables WITHIN the function&lt;br /&gt;
 	$Var_2 = &amp;quot;Changed Variable 2&amp;quot;&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here is a simple example showing how &#039;&#039;Local&#039;&#039; variables are only visible &#039;&#039;inside&#039;&#039; their own function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;Constants.au3&amp;gt; ; only required for MsgBox constants&lt;br /&gt;
&lt;br /&gt;
 Global $Var_1 = &amp;quot;Variable 1&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; Read the variable&lt;br /&gt;
 MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Reading&amp;quot;, &amp;quot;In The Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1)&lt;br /&gt;
 &lt;br /&gt;
 ; Now run a function&lt;br /&gt;
 _Function()&lt;br /&gt;
 &lt;br /&gt;
 ; And now try to read Variable 3 OUTSIDE the function&lt;br /&gt;
 MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Reading&amp;quot;, &amp;quot;Back In The Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1 &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 3 = &amp;quot; &amp;amp; $Var_3)&lt;br /&gt;
 &lt;br /&gt;
 Func _Function()&lt;br /&gt;
 	; Declare a LOCAL variable&lt;br /&gt;
 	Local $Var_3 = &amp;quot;Variable 3&amp;quot;&lt;br /&gt;
 	; Read the variables&lt;br /&gt;
 	MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Reading&amp;quot;, &amp;quot;In The Function&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1 &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 3 = &amp;quot; &amp;amp; $Var_3)&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
You should have got errors telling you that &#039;&#039;$Var3&#039;&#039; was &amp;quot;&#039;&#039;possibly used before declaration&#039;&#039;&amp;quot; and an &amp;quot;&#039;&#039;undeclared global variable&#039;&#039;&amp;quot;.  This is because &#039;&#039;$Var3&#039;&#039; exists only &#039;&#039;within&#039;&#039; the function - when the function ends it is destroyed.&lt;br /&gt;
&lt;br /&gt;
This means that we can use the same variable name in different functions without causing a problem - very useful for simple variables which are only used temporarily:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;Constants.au3&amp;gt; ; only required for MsgBox constants&lt;br /&gt;
&lt;br /&gt;
 Function_1()&lt;br /&gt;
 &lt;br /&gt;
 Func Function_1()&lt;br /&gt;
 &lt;br /&gt;
 	; Declare the variable in this function&lt;br /&gt;
 	Local $sString = &amp;quot;Variable in Function One&amp;quot;&lt;br /&gt;
 	; Read the value&lt;br /&gt;
 	MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Reading&amp;quot;, &amp;quot;In Function One&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 	; Now run Function Two&lt;br /&gt;
 	Function_2()&lt;br /&gt;
 &lt;br /&gt;
 	; Now read the variable again - we still get the variable from this function&lt;br /&gt;
 	; The variable in Function 2 has been destroyed now the function has terminated&lt;br /&gt;
 	MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Reading&amp;quot;, &amp;quot;In Function One&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func Function_2()&lt;br /&gt;
 &lt;br /&gt;
 	; Declare a variable with the SAME name&lt;br /&gt;
 	Local $sString = &amp;quot;Variable in Function Two&amp;quot;&lt;br /&gt;
 	; Read this variable - see how we get the value in this function, not the value in Function One&lt;br /&gt;
 	MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Reading&amp;quot;, &amp;quot;In Function Two&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
AutoIt even allows you to use the same name for &#039;&#039;Global&#039;&#039; and &#039;&#039;Local&#039;&#039; variables, although this is &#039;&#039;not&#039;&#039; recommended as it could easily lead to confusion.  If there is a naming conflict of this kind, AutoIt uses the &#039;&#039;Local&#039;&#039; value as you can see here:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;Constants.au3&amp;gt; ; only required for MsgBox constants&lt;br /&gt;
&lt;br /&gt;
 ; Declare the variable as Global&lt;br /&gt;
 Global $sString = &amp;quot;Global Variable in the Main Script&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; Read it&lt;br /&gt;
 MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Reading&amp;quot;, &amp;quot;In the Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 ; Run the functions which declare Local variables with the same name&lt;br /&gt;
 Function_1()&lt;br /&gt;
 &lt;br /&gt;
 ; And now see that the Global variable still exists unchanged&lt;br /&gt;
 MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Reading&amp;quot;, &amp;quot;In the Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 Func Function_1()&lt;br /&gt;
 &lt;br /&gt;
 	; Declare a variable with the SAME name as Local to this function&lt;br /&gt;
 	Local $sString = &amp;quot;Variable in Function One&amp;quot;&lt;br /&gt;
 	; Read the value - we get the value of the Local variable in this function, not the Global one&lt;br /&gt;
 	MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Reading&amp;quot;, &amp;quot;In Function One&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A good use for &#039;&#039;Static&#039;&#039; variables is when you need to maintain a record of a value within a function even though the function itself ends.  An example might be that you want to do something the first time a function is called, but not subsequently:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Foo()&lt;br /&gt;
 Foo()&lt;br /&gt;
 Foo()&lt;br /&gt;
 &lt;br /&gt;
 Func Foo()&lt;br /&gt;
 	; Set the flag only on the first entry into the function&lt;br /&gt;
 	; This assignment will be ignored on subsequent entries&lt;br /&gt;
 	Local Static $fFoo_First_Pass = True&lt;br /&gt;
 	&lt;br /&gt;
 	; Check the flag&lt;br /&gt;
 	If $fFoo_First_Pass Then&lt;br /&gt;
 		; Immediately clear the flag to prevent running on subsequent passes&lt;br /&gt;
 		$fFoo_First_Pass = False&lt;br /&gt;
 		; Run on first pass because flag is set&lt;br /&gt;
 		ConsoleWrite(&amp;quot;First pass&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 	Else&lt;br /&gt;
 		; Flag remains cleared for subsequent passes&lt;br /&gt;
 		ConsoleWrite(&amp;quot;Not first pass&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 	EndIf&lt;br /&gt;
 EndFunc   ;==&amp;gt;Foo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
As the &#039;&#039;Local&#039;&#039; part of their declaration implies, you can use the same name for &#039;&#039;Static&#039;&#039; variables in different functions - even though they are not destroyed when the functions end:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 For $i = 1 To 5&lt;br /&gt;
     _Function_1()&lt;br /&gt;
     _Function_2()&lt;br /&gt;
 Next&lt;br /&gt;
 &lt;br /&gt;
 Func _Function_1()&lt;br /&gt;
     ; Declare the variable as Static - remember this only happens once&lt;br /&gt;
     Local Static $vVar = 0&lt;br /&gt;
     ; Increase the value of the variable each time we enter the function&lt;br /&gt;
     $vVar += 10&lt;br /&gt;
     ; And show that it has retained its value as the function exits&lt;br /&gt;
     ConsoleWrite(&amp;quot;In Function_1: &amp;quot; &amp;amp; $vVar &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Function_2()&lt;br /&gt;
     ; Use the same variable name&lt;br /&gt;
     Local Static $vVar = 0&lt;br /&gt;
     $vVar += 100&lt;br /&gt;
     ConsoleWrite(&amp;quot;In Function_2: &amp;quot; &amp;amp; $vVar &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
As a general rule, try to have as few &#039;&#039;Global&#039;&#039; variables as you can.  Remember that you can share &#039;&#039;Local&#039;&#039; variables between functions - and even change their values - by passing them as parameters as we will see in the &#039;&#039;ByRef&#039;&#039; section below.  And declaring a variable as &#039;&#039;Static&#039;&#039; allows you retain its value even though the function in which it is used has ended.&lt;br /&gt;
&lt;br /&gt;
=Passing variables as parameters using ByRef=&lt;br /&gt;
When you call a function in AutoIt, you can pass parameters to the function by including them in the parentheses following the function name like this - &#039;&#039;Function(Parameter_1, Parameter_2)&#039;&#039;.  Passing variables in this way means that you can use variables that have been declared as &#039;&#039;Local&#039;&#039; within other functions. Note that the parameters are automatically declared as &#039;&#039;Local&#039;&#039; variables within the called function and so do not need to be declared again in the code.&lt;br /&gt;
&lt;br /&gt;
Variables can be passed as parameters to a function in 2 ways:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;By Value&#039;&#039;&#039; - This is the default. The parameter is treated as a &#039;&#039;Local&#039;&#039; variable within the function to which it is passed and any changes made to it are lost when the function ends. So no changes are made to the &#039;&#039;Local&#039;&#039; variable within the original function.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;By Reference&#039;&#039;&#039; - This is used when &#039;&#039;ByRef&#039;&#039; is added &#039;&#039;before&#039;&#039; the variable name in the parameter list of the function declaration. Now any changes to the variable made in the function to which it is passed also affect the &#039;&#039;Local&#039;&#039; variable in the original function.  If you do not understand why this is such a powerful capability, you need to read the &#039;&#039;Global/Local&#039;&#039; section again!&lt;br /&gt;
&lt;br /&gt;
Here is a small example to show how parameters are passed when calling a function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;Constants.au3&amp;gt; ; only required for MsgBox constants&lt;br /&gt;
&lt;br /&gt;
 Func_A()&lt;br /&gt;
 &lt;br /&gt;
 Func Func_A()&lt;br /&gt;
 &lt;br /&gt;
 	; Declare variables&lt;br /&gt;
 	Local $iVar_A1 = 10&lt;br /&gt;
 	Local $iVar_A2 = 20&lt;br /&gt;
 	; And read them&lt;br /&gt;
 	MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Read&amp;quot;, &amp;quot;Initial read in Func A:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var A1 = &amp;quot; &amp;amp; $iVar_A1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var A2 = &amp;quot; &amp;amp; $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 	; Now pass these variables to another function - we use the names we have already declared in this function&lt;br /&gt;
 	Func_B($iVar_A1, $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 	; We changed the parameters in Func_B - but nothing happened to the variables in this function&lt;br /&gt;
 	MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Read&amp;quot;, &amp;quot;Second read in Func A:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var A1 = &amp;quot; &amp;amp; $iVar_A1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var A2 = &amp;quot; &amp;amp; $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func Func_B($iVar_B1, $iVar_B2) ; There is no need to declare the variables as parameters are automatically Local in scope&lt;br /&gt;
 &lt;br /&gt;
 	; Now read these variables - note that they have the same value as the variables in Func_A&lt;br /&gt;
 	MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Read&amp;quot;, &amp;quot;Initial read in Func B:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var B1 = &amp;quot; &amp;amp; $iVar_B1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var B2 = &amp;quot; &amp;amp; $iVar_B2)&lt;br /&gt;
 &lt;br /&gt;
 	; Let us change them&lt;br /&gt;
 	$iVar_B1 = 100&lt;br /&gt;
 	$iVar_B2 = 200&lt;br /&gt;
 &lt;br /&gt;
 	; And confirm that they have changed&lt;br /&gt;
 	MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Read&amp;quot;, &amp;quot;Second read in Func B:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var B1 = &amp;quot; &amp;amp; $iVar_B1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var B2 = &amp;quot; &amp;amp; $iVar_B2)&lt;br /&gt;
 &lt;br /&gt;
 	; Now return to the other function&lt;br /&gt;
 	&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
As you can see, the &#039;&#039;Local&#039;&#039; variables within &#039;&#039;Func_A&#039;&#039; are read perfectly by &#039;&#039;Func_B&#039;&#039; when passed as parameters, even though they were declared as &#039;&#039;Local&#039;&#039; in &#039;&#039;Func_A&#039;&#039;.  However, although &#039;&#039;Func_B&#039;&#039; changes the value of the variables, the values of the original variables within &#039;&#039;Func_A&#039;&#039; are not changed.&lt;br /&gt;
&lt;br /&gt;
If we want to change the value of the variables in &#039;&#039;Func_A&#039;&#039; from within &#039;&#039;Func_B&#039;&#039;, we need to use the &#039;&#039;ByRef&#039;&#039; keyword as explained above and illustrated here:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;Constants.au3&amp;gt; ; only required for MsgBox constants&lt;br /&gt;
&lt;br /&gt;
 Func_A()&lt;br /&gt;
 &lt;br /&gt;
 Func Func_A()&lt;br /&gt;
 &lt;br /&gt;
 	; Declare variables&lt;br /&gt;
 	Local $iVar_A1 = 10&lt;br /&gt;
 	Local $iVar_A2 = 20&lt;br /&gt;
 &lt;br /&gt;
 	; And read them&lt;br /&gt;
 	MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Read&amp;quot;, &amp;quot;Initial read in Func A:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var A1 = &amp;quot; &amp;amp; $iVar_A1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var A2 = &amp;quot; &amp;amp; $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 	; Now pass these variables to another function - but this time we will pass $iVar_A2 By Reference&lt;br /&gt;
 	Func_B($iVar_A1, $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 	; We changed the parameters in Func_B - this time we see that we have changed $iVar_A2&lt;br /&gt;
 	MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Read&amp;quot;, &amp;quot;Second read in Func A:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var A1 = &amp;quot; &amp;amp; $iVar_A1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var A2 = &amp;quot; &amp;amp; $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func Func_B($iVar_B1, ByRef $iVar_B2) ; Note the ByRef keyword in the function declaration for the second parameter&lt;br /&gt;
 &lt;br /&gt;
 	; Now read these variables - they have the same value as the variables in Func_A&lt;br /&gt;
 	MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Read&amp;quot;, &amp;quot;Initial read in Func B:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var B1 = &amp;quot; &amp;amp; $iVar_B1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var B2 = &amp;quot; &amp;amp; $iVar_B2)&lt;br /&gt;
 &lt;br /&gt;
 	; Let us change them&lt;br /&gt;
 	$iVar_B1 = 100&lt;br /&gt;
 	$iVar_B2 = 200&lt;br /&gt;
 &lt;br /&gt;
 	; And confirm that they have changed&lt;br /&gt;
 	MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, &amp;quot;Read&amp;quot;, &amp;quot;Second read in Func B:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var B1 = &amp;quot; &amp;amp; $iVar_B1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var B2 = &amp;quot; &amp;amp; $iVar_B2)&lt;br /&gt;
 &lt;br /&gt;
 	; Now return to the other function&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A couple of more advanced points:&lt;br /&gt;
&lt;br /&gt;
- It was mentioned earlier that when you pass variables to functions AutoIt makes local copies of these variables unless you declare that they are to be passed &#039;&#039;ByRef&#039;&#039;.  In the special case of arrays, which are typically larger than a simple variable, AutoIt will only make a local copy if you change the array inside the function - merely accessing the array will use the original version.  So passing the array &#039;&#039;ByRef&#039;&#039; is only advantageous if you intend to modify the array within the function - however, it does no harm to force the issue by using the keyword.&lt;br /&gt;
&lt;br /&gt;
- If you are dealing with a simple variable of considerable size (the text of a file for example) then passing it &#039;&#039;ByRef&#039;&#039; is a sensible action.  But if you want to make sure that the variable cannot be altered inside the function, you can declare it as &#039;&#039;Const ByRef&#039;&#039; in the function definition as shown here:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Global $sString = &amp;quot;A very large chunk of data which we do not want to change&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 Foo($sString)&lt;br /&gt;
 &lt;br /&gt;
 Func Foo(Const ByRef $sText) ; The data is not copied, but also cannot be changed&lt;br /&gt;
 	; Uncomment this line to see what happens when we try&lt;br /&gt;
 	;$sText = &amp;quot;New value&amp;quot;&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;ByRef&#039;&#039; is a very powerful tool - but use it carefully, or you may find that you have changed a variable when you did not want to!&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Variables_-_using_Global,_Local,_Static_and_ByRef&amp;diff=11955</id>
		<title>Variables - using Global, Local, Static and ByRef</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Variables_-_using_Global,_Local,_Static_and_ByRef&amp;diff=11955"/>
		<updated>2013-11-04T18:07:28Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorials]]&lt;br /&gt;
These keywords confuse many coders - this tutorial should help make their use clear.&lt;br /&gt;
&lt;br /&gt;
In most programming languages you can define the scope of variables - this determines the visibility or accessibility of the variable from different parts of the program. &lt;br /&gt;
&lt;br /&gt;
In AutoIt there are two possible scopes: &#039;&#039;Global&#039;&#039; and &#039;&#039;Local&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
- A &#039;&#039;&#039;Global&#039;&#039;&#039; variable is visible throughout your script - any part of the script can both read its value and, importantly, change it.&lt;br /&gt;
&lt;br /&gt;
- A &#039;&#039;&#039;Local&#039;&#039;&#039; variable exists only within the function in which it is declared and is destroyed when the function terminates.  It is invisible to any other function unless it is passed as a parameter.&lt;br /&gt;
&lt;br /&gt;
Additionally declaring a variable as &#039;&#039;&#039;Static&#039;&#039;&#039; changes its behaviour slightly.  A &#039;&#039;Global Static&#039;&#039; variable serves no useful purpose as it is essentially the same as a normal &#039;&#039;Global&#039;&#039; variable.  However, a &#039;&#039;Local Static&#039;&#039; variable exists only within the function in which it is declared, but is NOT destroyed when the function ends and can be reused when the function is next entered.  You can assign an initial value to this variable when it is created - if it is already in existence then the assignment is ignored.  Note that the order of the keywords is not important.&lt;br /&gt;
&lt;br /&gt;
Why do we need to scope variables?  Well, it is often useful to have a single variable used throughout the script - perhaps the name of an Ini file which if declared as &#039;&#039;Global&#039;&#039; can then be read by any function that requires it. And &#039;&#039;Local&#039;&#039; variables allow us to save resources by only using variables as long as we need - for example if we create a large array which is only needed within a single function.&lt;br /&gt;
&lt;br /&gt;
We scope variables by using the &#039;&#039;Global, Local&#039;&#039; and &#039;&#039;Static&#039;&#039; keywords when the variables are first declared - look at the examples below.  By default, AutoIt scopes any variables declared in the main body of a script (that is not between a &#039;&#039;Func&#039;&#039; and &#039;&#039;EndFunc&#039;&#039; pair) as &#039;&#039;Global&#039;&#039; and any variables declared within function declarations as &#039;&#039;Local&#039;&#039;. But it is a good idea to explicitly declare your variables to make sure that you get what you want.  For example, you can declare a variable as &#039;&#039;Global&#039;&#039; within a function - although you may get a gentle reminder when you run your script within SciTE that this is not recommended.  But there is no point declaring any variables in the main body of a script as &#039;&#039;Local&#039;&#039; - they will be &#039;&#039;Global&#039;&#039; regardless.  If you use the &#039;&#039;AutoItSetOption(&amp;quot;MustDeclareVars&amp;quot;, 1)&#039;&#039; directive you &#039;&#039;must&#039;&#039; declare the scope of your variables or you will get error messages.&lt;br /&gt;
&lt;br /&gt;
In the Help file pages for &#039;&#039;Global, Local&#039;&#039; and &#039;&#039;Static&#039;&#039; you will also see mention of &#039;&#039;Dim&#039;&#039; and &#039;&#039;ReDim&#039;&#039;.  Using &#039;&#039;Dim&#039;&#039; will declare a variable and satisfy the &#039;&#039;AutoItSetOption&#039;&#039; just mentioned, but will let AutoIt scope the variable using the default settings as described above.  It is much better practice to use &#039;&#039;Global&#039;&#039; or &#039;&#039;Local&#039;&#039; to set the scope you require explicitly.  Despite its similar name, &#039;&#039;ReDim&#039;&#039; is only used to resize arrays without destroying the content and is outside the scope of this tutorial.&lt;br /&gt;
&lt;br /&gt;
Let us now look at a simple example when we read and change &#039;&#039;Global&#039;&#039; variables in a function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Global $Var_1 = &amp;quot;Variable 1&amp;quot;&lt;br /&gt;
 Global $Var_2 = &amp;quot;Variable 2&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; Read the variables&lt;br /&gt;
 MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In The Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1 &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 2 = &amp;quot; &amp;amp; $Var_2)&lt;br /&gt;
 &lt;br /&gt;
 ; Read the variables in a function&lt;br /&gt;
 _Function()&lt;br /&gt;
 &lt;br /&gt;
 ; And now read the variables again - see that $iVar_2 has changed&lt;br /&gt;
 MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;Back In The Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1 &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 2 = &amp;quot; &amp;amp; $Var_2)&lt;br /&gt;
 &lt;br /&gt;
 Func _Function()&lt;br /&gt;
 	; Read the variables&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In The Function&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1 &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 2 = &amp;quot; &amp;amp; $Var_2)&lt;br /&gt;
 	; Now let us change one of the variables WITHIN the function&lt;br /&gt;
 	$Var_2 = &amp;quot;Changed Variable 2&amp;quot;&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here is a simple example showing how &#039;&#039;Local&#039;&#039; variables are only visible &#039;&#039;inside&#039;&#039; their own function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Global $Var_1 = &amp;quot;Variable 1&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; Read the variable&lt;br /&gt;
 MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In The Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1)&lt;br /&gt;
 &lt;br /&gt;
 ; Now run a function&lt;br /&gt;
 _Function()&lt;br /&gt;
 &lt;br /&gt;
 ; And now try to read Variable 3 OUTSIDE the function&lt;br /&gt;
 MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;Back In The Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1 &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 3 = &amp;quot; &amp;amp; $Var_3)&lt;br /&gt;
 &lt;br /&gt;
 Func _Function()&lt;br /&gt;
 	; Declare a LOCAL variable&lt;br /&gt;
 	Local $Var_3 = &amp;quot;Variable 3&amp;quot;&lt;br /&gt;
 	; Read the variables&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In The Function&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1 &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 3 = &amp;quot; &amp;amp; $Var_3)&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
You should have got errors telling you that &#039;&#039;$Var3&#039;&#039; was &amp;quot;&#039;&#039;possibly used before declaration&#039;&#039;&amp;quot; and an &amp;quot;&#039;&#039;undeclared global variable&#039;&#039;&amp;quot;.  This is because &#039;&#039;$Var3&#039;&#039; exists only &#039;&#039;within&#039;&#039; the function - when the function ends it is destroyed.&lt;br /&gt;
&lt;br /&gt;
This means that we can use the same variable name in different functions without causing a problem - very useful for simple variables which are only used temporarily:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Function_1()&lt;br /&gt;
 &lt;br /&gt;
 Func Function_1()&lt;br /&gt;
 &lt;br /&gt;
 	; Declare the variable in this function&lt;br /&gt;
 	Local $sString = &amp;quot;Variable in Function One&amp;quot;&lt;br /&gt;
 	; Read the value&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In Function One&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 	; Now run Function Two&lt;br /&gt;
 	Function_2()&lt;br /&gt;
 &lt;br /&gt;
 	; Now read the variable again - we still get the variable from this function&lt;br /&gt;
 	; The variable in Function 2 has been destroyed now the function has terminated&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In Function One&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func Function_2()&lt;br /&gt;
 &lt;br /&gt;
 	; Declare a variable with the SAME name&lt;br /&gt;
 	Local $sString = &amp;quot;Variable in Function Two&amp;quot;&lt;br /&gt;
 	; Read this variable - see how we get the value in this function, not the value in Function One&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In Function Two&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
AutoIt even allows you to use the same name for &#039;&#039;Global&#039;&#039; and &#039;&#039;Local&#039;&#039; variables, although this is &#039;&#039;not&#039;&#039; recommended as it could easily lead to confusion.  If there is a naming conflict of this kind, AutoIt uses the &#039;&#039;Local&#039;&#039; value as you can see here:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 ; Declare the variable as Global&lt;br /&gt;
 Global $sString = &amp;quot;Global Variable in the Main Script&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; Read it&lt;br /&gt;
 MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In the Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 ; Run the functions which declare Local variables with the same name&lt;br /&gt;
 Function_1()&lt;br /&gt;
 &lt;br /&gt;
 ; And now see that the Global variable still exists unchanged&lt;br /&gt;
 MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In the Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 Func Function_1()&lt;br /&gt;
 &lt;br /&gt;
 	; Declare a variable with the SAME name as Local to this function&lt;br /&gt;
 	Local $sString = &amp;quot;Variable in Function One&amp;quot;&lt;br /&gt;
 	; Read the value - we get the value of the Local variable in this function, not the Global one&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In Function One&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A good use for &#039;&#039;Static&#039;&#039; variables is when you need to maintain a record of a value within a function even though the function itself ends.  An example might be that you want to do something the first time a function is called, but not subsequently:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Func Foo()&lt;br /&gt;
     ; Set the value only on the first entry into the function&lt;br /&gt;
     Local Static $iFooCount = -1 &lt;br /&gt;
     ; Increase the value each time we enter the function&lt;br /&gt;
     $iFooCount += 1&lt;br /&gt;
     ; Now look at value in the variable&lt;br /&gt;
     If $iFooCount Then&lt;br /&gt;
         ; Not the first pass because value &amp;gt; 0&lt;br /&gt;
     Else&lt;br /&gt;
         ; First pass because value = 0&lt;br /&gt;
     EndIf&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
As the &#039;&#039;Local&#039;&#039; part of their declaration implies, you can use the same name for &#039;&#039;Static&#039;&#039; variables in different functions - even though they are not destroyed when the functions end:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 For $i = 1 To 5&lt;br /&gt;
     _Function_1()&lt;br /&gt;
     _Function_2()&lt;br /&gt;
 Next&lt;br /&gt;
 &lt;br /&gt;
 Func _Function_1()&lt;br /&gt;
     ; Declare the variable as Static - remember this only happens once&lt;br /&gt;
     Local Static $vVar = 0&lt;br /&gt;
     ; Increase the value of the variable each time we enter the function&lt;br /&gt;
     $vVar += 10&lt;br /&gt;
     ; And show that it has retained its value as the function exits&lt;br /&gt;
     ConsoleWrite(&amp;quot;In Function_1: &amp;quot; &amp;amp; $vVar &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Function_2()&lt;br /&gt;
     ; Use the same variable name&lt;br /&gt;
     Local Static $vVar = 0&lt;br /&gt;
     $vVar += 100&lt;br /&gt;
     ConsoleWrite(&amp;quot;In Function_2: &amp;quot; &amp;amp; $vVar &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
As a general rule, try to have as few &#039;&#039;Global&#039;&#039; variables as you can.  Remember that you can share &#039;&#039;Local&#039;&#039; variables between functions - and even change their values - by passing them as parameters as we will see in the &#039;&#039;ByRef&#039;&#039; section below.  And declaring a variable as &#039;&#039;Static&#039;&#039; allows you retain its value even though the function in which it is used has ended.&lt;br /&gt;
&lt;br /&gt;
=Passing variables as parameters using ByRef=&lt;br /&gt;
When you call a function in AutoIt, you can pass parameters to the function by including them in the parentheses following the function name like this - &#039;&#039;Function(Parameter_1, Parameter_2)&#039;&#039;.  Passing variables in this way means that you can use variables that have been declared as &#039;&#039;Local&#039;&#039; within other functions. Note that the parameters are automatically declared as &#039;&#039;Local&#039;&#039; variables within the called function and so do not need to be declared again in the code.&lt;br /&gt;
&lt;br /&gt;
Variables can be passed as parameters to a function in 2 ways:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;By Value&#039;&#039;&#039; - This is the default. The parameter is treated as a &#039;&#039;Local&#039;&#039; variable within the function to which it is passed and any changes made to it are lost when the function ends. So no changes are made to the &#039;&#039;Local&#039;&#039; variable within the original function.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;By Reference&#039;&#039;&#039; - This is used when &#039;&#039;ByRef&#039;&#039; is added &#039;&#039;before&#039;&#039; the variable name in the parameter list of the function declaration. Now any changes to the variable made in the function to which it is passed also affect the &#039;&#039;Local&#039;&#039; variable in the original function.  If you do not understand why this is such a powerful capability, you need to read the &#039;&#039;Global/Local&#039;&#039; section again!&lt;br /&gt;
&lt;br /&gt;
Here is a small example to show how parameters are passed when calling a function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Func_A()&lt;br /&gt;
 &lt;br /&gt;
 Func Func_A()&lt;br /&gt;
 &lt;br /&gt;
 	; Declare variables&lt;br /&gt;
 	Local $iVar_A1 = 10&lt;br /&gt;
 	Local $iVar_A2 = 20&lt;br /&gt;
 	; And read them&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Initial read in Func A:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var A1 = &amp;quot; &amp;amp; $iVar_A1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var A2 = &amp;quot; &amp;amp; $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 	; Now pass these variables to another function - we use the names we have already declared in this function&lt;br /&gt;
 	Func_B($iVar_A1, $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 	; We changed the parameters in Func_B - but nothing happened to the variables in this function&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Second read in Func A:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var A1 = &amp;quot; &amp;amp; $iVar_A1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var A2 = &amp;quot; &amp;amp; $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func Func_B($iVar_B1, $iVar_B2) ; There is no need to declare the variables as parameters are automatically Local in scope&lt;br /&gt;
 &lt;br /&gt;
 	; Now read these variables - note that they have the same value as the variables in Func_A&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Initial read in Func B:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var B1 = &amp;quot; &amp;amp; $iVar_B1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var B2 = &amp;quot; &amp;amp; $iVar_B2)&lt;br /&gt;
 &lt;br /&gt;
 	; Let us change them&lt;br /&gt;
 	$iVar_B1 = 100&lt;br /&gt;
 	$iVar_B2 = 200&lt;br /&gt;
 &lt;br /&gt;
 	; And confirm that they have changed&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Second read in Func B:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var B1 = &amp;quot; &amp;amp; $iVar_B1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var B2 = &amp;quot; &amp;amp; $iVar_B2)&lt;br /&gt;
 &lt;br /&gt;
 	; Now return to the other function&lt;br /&gt;
 	&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
As you can see, the &#039;&#039;Local&#039;&#039; variables within &#039;&#039;Func_A&#039;&#039; are read perfectly by &#039;&#039;Func_B&#039;&#039; when passed as parameters, even though they were declared as &#039;&#039;Local&#039;&#039; in &#039;&#039;Func_A&#039;&#039;.  However, although &#039;&#039;Func_B&#039;&#039; changes the value of the variables, the values of the original variables within &#039;&#039;Func_A&#039;&#039; are not changed.&lt;br /&gt;
&lt;br /&gt;
If we want to change the value of the variables in &#039;&#039;Func_A&#039;&#039; from within &#039;&#039;Func_B&#039;&#039;, we need to use the &#039;&#039;ByRef&#039;&#039; keyword as explained above and illustrated here:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Func_A()&lt;br /&gt;
 &lt;br /&gt;
 Func Func_A()&lt;br /&gt;
 &lt;br /&gt;
 	; Declare variables&lt;br /&gt;
 	Local $iVar_A1 = 10&lt;br /&gt;
 	Local $iVar_A2 = 20&lt;br /&gt;
 &lt;br /&gt;
 	; And read them&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Initial read in Func A:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var A1 = &amp;quot; &amp;amp; $iVar_A1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var A2 = &amp;quot; &amp;amp; $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 	; Now pass these variables to another function - but this time we will pass $iVar_A2 By Reference&lt;br /&gt;
 	Func_B($iVar_A1, $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 	; We changed the parameters in Func_B - this time we see that we have changed $iVar_A2&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Second read in Func A:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var A1 = &amp;quot; &amp;amp; $iVar_A1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var A2 = &amp;quot; &amp;amp; $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func Func_B($iVar_B1, ByRef $iVar_B2) ; Note the ByRef keyword in the function declaration for the second parameter&lt;br /&gt;
 &lt;br /&gt;
 	; Now read these variables - they have the same value as the variables in Func_A&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Initial read in Func B:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var B1 = &amp;quot; &amp;amp; $iVar_B1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var B2 = &amp;quot; &amp;amp; $iVar_B2)&lt;br /&gt;
 &lt;br /&gt;
 	; Let us change them&lt;br /&gt;
 	$iVar_B1 = 100&lt;br /&gt;
 	$iVar_B2 = 200&lt;br /&gt;
 &lt;br /&gt;
 	; And confirm that they have changed&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Second read in Func B:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var B1 = &amp;quot; &amp;amp; $iVar_B1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var B2 = &amp;quot; &amp;amp; $iVar_B2)&lt;br /&gt;
 &lt;br /&gt;
 	; Now return to the other function&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;ByRef&#039;&#039; is a very powerful tool - but use it carefully, or you may find that you have changed a variable when you did not want to!&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Adding_UDFs_to_AutoIt_and_SciTE&amp;diff=11931</id>
		<title>Adding UDFs to AutoIt and SciTE</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Adding_UDFs_to_AutoIt_and_SciTE&amp;diff=11931"/>
		<updated>2013-09-07T14:35:18Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:SciTE]][[Category:UDF]]&lt;br /&gt;
The ability to download UDFs created by other users is one of the major advantages of AutoIt, but are you one of the many coders who just add these UDFs to the existing &amp;quot;&#039;&#039;Include&#039;&#039;&amp;quot; folder which contains the standard UDFS distributed with AutoIt?  If so then there is much better way to do it - one which will prevent you from losing all of these additional UDFs when you upgrade.  Just use a user-defined folder to store all your UDFs - AutoIt makes this very easy to do.&lt;br /&gt;
&lt;br /&gt;
Begin by creating a new folder to hold the additional UDFs - it is recommended that you do &#039;&#039;&#039;NOT&#039;&#039;&#039; put this folder in the AutoIt install folder (or it will get overwritten when you upgrade).  Then tell AutoIt about this folder.&lt;br /&gt;
&lt;br /&gt;
- If you have &#039;&#039;SciTE4AutoIt3&#039;&#039; you can use &#039;&#039;&#039;SciTEConfig&#039;&#039;&#039; - look for the &#039;&#039;User Include Dir&#039;&#039; input about 2/3 way down the dialog. &lt;br /&gt;
&lt;br /&gt;
- If not (and why not? You can download it from here[http://www.autoitscript.com/site/autoit-script-editor/downloads/]) you need to modify the registry directly as explained on the &amp;quot;&#039;&#039;Include&#039;&#039;&amp;quot; page of the Help file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 There is a special registry value that can be created at &amp;quot;HKEY_CURRENT_USER\Software\AutoIt v3\AutoIt&amp;quot; called &amp;quot;Include&amp;quot;.&lt;br /&gt;
 It should be a REG_SZ (string) value.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;CYA Note&#039;&#039;&#039;: Normal precautions are advised if modifying the registry. &lt;br /&gt;
&lt;br /&gt;
You now have a folder to store modified, downloaded or personal UDFs which are available to use with no need to specify the path and which will not be lost on upgrade.  But to make coding with these UDFs even easier you can also add &#039;&#039;&#039;CallTips&#039;&#039;&#039; and &#039;&#039;&#039;AutoComplete&#039;&#039;&#039; for them.&lt;br /&gt;
&lt;br /&gt;
As you might expect, the full &#039;&#039;SciTE4AutoIt3&#039;&#039; package makes it easy - have you downloaded and installed it yet? If you have then just open &#039;&#039;&#039;SciTEConfig&#039;&#039;&#039; on the &#039;&#039;&#039;Other Tools&#039;&#039;&#039; tab and press &#039;&#039;&#039;Run User Call Tip Manager&#039;&#039;&#039;.  Then you just need to select the UDF file to add and everything is done for you automatically.&lt;br /&gt;
&lt;br /&gt;
But if you want to do it manually (which is &#039;&#039;&#039;not&#039;&#039;&#039; recommended):&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Calltips&#039;&#039;&#039; first. These are stored in &#039;&#039;&amp;lt;Your_User_Profile&amp;gt;\au3.user.calltips.api&#039;&#039;.  If you are doing this for the first time then this file will not exist and you will have to create it.  Then add a line like this to the file for each function you wish to have a calltip:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 _Function($param1, $param2, $param3) Explanation of function (Requires: #Include UDF.au3)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Of course you need to change the &#039;&#039;Function, $param&#039;&#039; and &#039;&#039;UDF&#039;&#039; words to the correct values for the UDF function you want to include.&lt;br /&gt;
&lt;br /&gt;
Now &#039;&#039;&#039;AutoComplete&#039;&#039;&#039;. Again a special file is used &#039;&#039;&amp;lt;Your_User_Profile&amp;gt;\au3.userudfs.properties&#039;&#039; - again you will have to create it initially - which should read as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 au3.keywords.user.udfs=_function1 _function2 _function3 _function4 \&lt;br /&gt;
        _function5 _function6 _function7&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note that the entries are all in lowercase and all lines other than the first begin with a &#039;&#039;@TAB&#039;&#039; character.&lt;br /&gt;
&lt;br /&gt;
Then save all files, close and restart SciTE. You will have &#039;&#039;&#039;AutoComplete&#039;&#039;&#039; when you start typing the UDF function name in a script and a syntax &#039;&#039;&#039;CallTip&#039;&#039;&#039; as you enter the parameters.   These files are not overwritten when you update SciTE so all your hard work to set this up should be a once-only event.&lt;br /&gt;
&lt;br /&gt;
One final thing.  If you want the &amp;quot;&#039;&#039;Tools - Open Include&#039;&#039;&amp;quot; menu item in SciTE to work on the files within this new folder you need to add the following lines to your &amp;quot;&#039;&#039;SciTEUser.properties&#039;&#039;&amp;quot; file - you open it by using the &amp;lt;&#039;&#039;Options - Open User Options File&#039;&#039;&amp;gt; menu item:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 openpath.$(au3)=$(autoit3dir)\include;Your_Folder_Path&lt;br /&gt;
 openpath.beta.$(au3)=$(autoit3dir)\beta\include;Your_Folder_Path&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Now you are all set - your personal include files are as accessible as the standard set.&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Variables_-_using_Global,_Local,_Static_and_ByRef&amp;diff=11929</id>
		<title>Variables - using Global, Local, Static and ByRef</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Variables_-_using_Global,_Local,_Static_and_ByRef&amp;diff=11929"/>
		<updated>2013-09-03T16:29:37Z</updated>

		<summary type="html">&lt;p&gt;Melba23: Created page with &amp;quot;Category:Tutorials These keywords confuse many coders - this tutorial should help make their use clear.  In most programming languages you can define the scope of variable...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorials]]&lt;br /&gt;
These keywords confuse many coders - this tutorial should help make their use clear.&lt;br /&gt;
&lt;br /&gt;
In most programming languages you can define the scope of variables - this determines the visibility or accessibility of the variable from different parts of the program. &lt;br /&gt;
&lt;br /&gt;
In AutoIt there are three possible scopes: &#039;&#039;Global, Local&#039;&#039; and &#039;&#039;Static&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
- A &#039;&#039;&#039;Global&#039;&#039;&#039; variable is visible throughout your script - any part of teh script can both read its value and, importantly, change it.&lt;br /&gt;
&lt;br /&gt;
- A &#039;&#039;&#039;Local&#039;&#039;&#039; variable exists only within the function in which it is declared and is destroyed when the function terminates.  It is invisible to any other function unless it is passed as a parameter.&lt;br /&gt;
&lt;br /&gt;
- A &#039;&#039;&#039;Static&#039;&#039;&#039; variable exists only within the function in which it is declared, but is NOT destroyed when the function ends and can be reused when the function is next entered.  You can assign an initial value to this variable when it is created - if it is already in existence then the assignment is ignored.&lt;br /&gt;
&lt;br /&gt;
Why do we need to scope variables?  Well, it is often useful to have a single variable used throughout the script - perhaps the name of an Ini file which if declared as &#039;&#039;Global&#039;&#039; can then be read by any function that requires it. And &#039;&#039;Local&#039;&#039; variables allow us to save resources by only using variables as long as we need - for example if we create a large array which is only needed within a single function.&lt;br /&gt;
&lt;br /&gt;
We scope variables by using the &#039;&#039;Global, Local&#039;&#039; and &#039;&#039;Static&#039;&#039; keywords when the variables are first declared - look at the examples below.  By default, AutoIt scopes any variables declared in the main body of a script (that is not between a &#039;&#039;Func&#039;&#039; and &#039;&#039;EndFunc&#039;&#039; pair) as &#039;&#039;Global&#039;&#039; and any variables declared within function declarations as &#039;&#039;Local&#039;&#039;. But it is a good idea to explicitly declare your variables to make sure that you get what you want.  For example, you can declare a variable as &#039;&#039;Global&#039;&#039; within a function - although you may get a gentle reminder when you run your script within SciTE that this is not recommended.  But there is no point declaring any variables in the main body of a script as &#039;&#039;Local&#039;&#039; - they will be &#039;&#039;Global&#039;&#039; regardless.  If you use the &#039;&#039;AutoItSetOption(&amp;quot;MustDeclareVars&amp;quot;, 1)&#039;&#039; directive you &#039;&#039;must&#039;&#039; declare the scope of your variables or you will get error messages.&lt;br /&gt;
&lt;br /&gt;
In the Help file pages for &#039;&#039;Global, Local&#039;&#039; and &#039;&#039;Static&#039;&#039; you will also see mention of &#039;&#039;Dim&#039;&#039; and &#039;&#039;ReDim&#039;&#039;.  Using &#039;&#039;Dim&#039;&#039; will declare a variable and satisfy the &#039;&#039;AutoItSetOption&#039;&#039; just mentioned, but will let AutoIt scope the variable using the default settings as described above.  It is much better practice to use &#039;&#039;Global/Local/Static&#039;&#039; to explicitly set the scope you require.  Despite its similar name, &#039;&#039;ReDim&#039;&#039; is only used to resize arrays without destroying the content and is outside the scope of this tutorial.&lt;br /&gt;
&lt;br /&gt;
Let us now look at a simple example when we read and change &#039;&#039;Global&#039;&#039; variables in a function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Global $Var_1 = &amp;quot;Variable 1&amp;quot;&lt;br /&gt;
 Global $Var_2 = &amp;quot;Variable 2&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; Read the variables&lt;br /&gt;
 MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In The Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1 &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 2 = &amp;quot; &amp;amp; $Var_2)&lt;br /&gt;
 &lt;br /&gt;
 ; Read the variables in a function&lt;br /&gt;
 _Function()&lt;br /&gt;
 &lt;br /&gt;
 ; And now read the variables again - see that $iVar_2 has changed&lt;br /&gt;
 MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;Back In The Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1 &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 2 = &amp;quot; &amp;amp; $Var_2)&lt;br /&gt;
 &lt;br /&gt;
 Func _Function()&lt;br /&gt;
 	; Read the variables&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In The Function&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1 &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 2 = &amp;quot; &amp;amp; $Var_2)&lt;br /&gt;
 	; Now let us change one of the variables WITHIN the function&lt;br /&gt;
 	$Var_2 = &amp;quot;Changed Variable 2&amp;quot;&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here is a simple example showing how &#039;&#039;Local&#039;&#039; variables are only visible &#039;&#039;inside&#039;&#039; their own function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Global $Var_1 = &amp;quot;Variable 1&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; Read the variable&lt;br /&gt;
 MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In The Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1)&lt;br /&gt;
 &lt;br /&gt;
 ; Now run a function&lt;br /&gt;
 _Function()&lt;br /&gt;
 &lt;br /&gt;
 ; And now try to read Variable 3 OUTSIDE the function&lt;br /&gt;
 MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;Back In The Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1 &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 3 = &amp;quot; &amp;amp; $Var_3)&lt;br /&gt;
 &lt;br /&gt;
 Func _Function()&lt;br /&gt;
 	; Declare a LOCAL variable&lt;br /&gt;
 	Local $Var_3 = &amp;quot;Variable 3&amp;quot;&lt;br /&gt;
 	; Read the variables&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In The Function&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 1 = &amp;quot; &amp;amp; $Var_1 &amp;amp; @CRLF &amp;amp; &amp;quot;Variable 3 = &amp;quot; &amp;amp; $Var_3)&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
You should have got errors telling you that &#039;&#039;$Var3&#039;&#039; was &amp;quot;&#039;&#039;possibly used before declaration&#039;&#039;&amp;quot; and an &amp;quot;&#039;&#039;undeclared global variable&#039;&#039;&amp;quot;.  This is because &#039;&#039;$Var3&#039;&#039; exists only &#039;&#039;within&#039;&#039; the function - when the function ends it is destroyed.&lt;br /&gt;
&lt;br /&gt;
This means that we can use the same variable name in different functions without causing a problem - very useful for simple variables which are only used temporarily:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Function_1()&lt;br /&gt;
 &lt;br /&gt;
 Func Function_1()&lt;br /&gt;
 &lt;br /&gt;
 	; Declare the variable in this function&lt;br /&gt;
 	Local $sString = &amp;quot;Variable in Function One&amp;quot;&lt;br /&gt;
 	; Read the value&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In Function One&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 	; Now run Function Two&lt;br /&gt;
 	Function_2()&lt;br /&gt;
 &lt;br /&gt;
 	; Now read the variable again - we still get the variable from this function&lt;br /&gt;
 	; The variable in Function 2 has been destroyed now the function has terminated&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In Function One&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func Function_2()&lt;br /&gt;
 &lt;br /&gt;
 	; Declare a variable with the SAME name&lt;br /&gt;
 	Local $sString = &amp;quot;Variable in Function Two&amp;quot;&lt;br /&gt;
 	; Read this variable - see how we get the value in this function, not the value in Function One&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In Function Two&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
AutoIt even allows you to use the same name for &#039;&#039;Global&#039;&#039; and &#039;&#039;Local&#039;&#039; variables, although this is &#039;&#039;not&#039;&#039; recommended as it could easily lead to confusion.  If there is a naming conflict of this kind, AutoIt uses the &#039;&#039;Local&#039;&#039; value as you can see here:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 ; Declare the variable as Global&lt;br /&gt;
 Global $sString = &amp;quot;Global Variable in the Main Script&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ; Read it&lt;br /&gt;
 MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In the Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 ; Run the functions which declare Local variables with the same name&lt;br /&gt;
 Function_1()&lt;br /&gt;
 &lt;br /&gt;
 ; And now see that the Global variable still exists unchanged&lt;br /&gt;
 MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In the Main Script&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 Func Function_1()&lt;br /&gt;
 &lt;br /&gt;
 	; Declare a variable with the SAME name as Local to this function&lt;br /&gt;
 	Local $sString = &amp;quot;Variable in Function One&amp;quot;&lt;br /&gt;
 	; Read the value - we get the value of the Local variable in this function, not the Global one&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Reading&amp;quot;, &amp;quot;In Function One&amp;quot; &amp;amp; @CRLF &amp;amp; @CRLF &amp;amp; &amp;quot;Variable = &amp;quot; &amp;amp; $sString)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A good use for &#039;&#039;Static&#039;&#039; variables is when you need to maintain a record of a value within a function even though the function itself ends.  An example might be that you want to do something the first time a function is called, but not subsequently:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Func Foo()&lt;br /&gt;
     ; Set the value only on the first entry into the function&lt;br /&gt;
     Static $iFooCount = -1 &lt;br /&gt;
     ; Increase the value each time we enter the function&lt;br /&gt;
     $iFooCount += 1&lt;br /&gt;
     ; Now look at value in the variable&lt;br /&gt;
     If $iFooCount Then&lt;br /&gt;
         ; Not the first pass because value &amp;gt; 0&lt;br /&gt;
     Else&lt;br /&gt;
         ; First pass because value = 0&lt;br /&gt;
     EndIf&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
As with &#039;&#039;Local&#039;&#039; variables, you can use the same name for &#039;&#039;Static&#039;&#039; variables in different functions - even though they are not destroyed when the functions end:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 For $i = 1 To 5&lt;br /&gt;
     _Function_1()&lt;br /&gt;
     _Function_2()&lt;br /&gt;
 Next&lt;br /&gt;
 &lt;br /&gt;
 Func _Function_1()&lt;br /&gt;
     ; Declare the variable as Static - remember this only happens once&lt;br /&gt;
     Static $vVar = 0&lt;br /&gt;
     ; Increase the value of the variable each time we enter the function&lt;br /&gt;
     $vVar += 10&lt;br /&gt;
     ; And show that it has retained its value as the function exits&lt;br /&gt;
     ConsoleWrite(&amp;quot;In Function_1: &amp;quot; &amp;amp; $vVar &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Function_2()&lt;br /&gt;
     ; Use the same variable name&lt;br /&gt;
     Static $vVar = 0&lt;br /&gt;
     $vVar += 100&lt;br /&gt;
     ConsoleWrite(&amp;quot;In Function_2: &amp;quot; &amp;amp; $vVar &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
As a general rule, try to have as few &#039;&#039;Global&#039;&#039; variables as you can.  Remember that you can share &#039;&#039;Local&#039;&#039; variables between functions - and even change their values - by passing them as parameters as we will see in the &#039;&#039;ByRef&#039;&#039; section below.  And declaring a variable as &#039;&#039;Static&#039;&#039; allows you retain its value even though the function in which it is used has ended.&lt;br /&gt;
&lt;br /&gt;
=Passing variables as parameters using ByRef=&lt;br /&gt;
When you call a function in AutoIt, you can pass parameters to the function by including them in the parentheses following the function name like this - &#039;&#039;Function(Parameter_1, Parameter_2)&#039;&#039;.  Passing variables in this way means that you can use variables that have been declared as &#039;&#039;Local&#039;&#039; within other functions. Note that the parameters are automatically declared as &#039;&#039;Local&#039;&#039; variables within the called function and so do not need to be declared again in the code.&lt;br /&gt;
&lt;br /&gt;
Variables can be passed as parameters to a function in 2 ways:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;By Value&#039;&#039;&#039; - This is the default. The parameter is treated as a &#039;&#039;Local&#039;&#039; variable within the function to which it is passed and any changes made to it are lost when the function ends. So no changes are made to the &#039;&#039;Local&#039;&#039; variable within the original function.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;By Reference&#039;&#039;&#039; - This is used when &#039;&#039;ByRef&#039;&#039; is added &#039;&#039;before&#039;&#039; the variable name in the parameter list of the function declaration. Now any changes to the variable made in the function to which it is passed also affect the &#039;&#039;Local&#039;&#039; variable in the original function.  If you do not understand why this such a powerful capability, you need to read the &#039;&#039;Global/Local&#039;&#039; section again!&lt;br /&gt;
&lt;br /&gt;
Here is a small example to show how parameters are passed when calling a function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Func_A()&lt;br /&gt;
 &lt;br /&gt;
 Func Func_A()&lt;br /&gt;
 &lt;br /&gt;
 	; Declare variables&lt;br /&gt;
 	Local $iVar_A1 = 10&lt;br /&gt;
 	Local $iVar_A2 = 20&lt;br /&gt;
 	; And read them&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Initial read in Func A:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var A1 = &amp;quot; &amp;amp; $iVar_A1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var A2 = &amp;quot; &amp;amp; $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 	; Now pass these variables to another function - we use the names we have already declared in this function&lt;br /&gt;
 	Func_B($iVar_A1, $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 	; We changed the parameters in Func_B - but nothing happened to the variables in this function&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Second read in Func A:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var A1 = &amp;quot; &amp;amp; $iVar_A1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var A2 = &amp;quot; &amp;amp; $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func Func_B($iVar_B1, $iVar_B2) ; There is no need to declare the variables as parameters are automatically Local in scope&lt;br /&gt;
 &lt;br /&gt;
 	; Now read these variables - note that they have the same value as the variables in Func_A&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Initial read in Func B:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var B1 = &amp;quot; &amp;amp; $iVar_B1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var B2 = &amp;quot; &amp;amp; $iVar_B2)&lt;br /&gt;
 &lt;br /&gt;
 	; Let us change them&lt;br /&gt;
 	$iVar_B1 = 100&lt;br /&gt;
 	$iVar_B2 = 200&lt;br /&gt;
 &lt;br /&gt;
 	; And confirm that they have changed&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Second read in Func B:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var B1 = &amp;quot; &amp;amp; $iVar_B1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var B2 = &amp;quot; &amp;amp; $iVar_B2)&lt;br /&gt;
 &lt;br /&gt;
 	; Now return to the other function&lt;br /&gt;
 	&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
As you can see, the &#039;&#039;Local&#039;&#039; variables within &#039;&#039;Func_A&#039;&#039; are read perfectly by &#039;&#039;Func_B&#039;&#039; when passed as parameters, even though they were declared as &#039;&#039;Local&#039;&#039; in &#039;&#039;Func_A&#039;&#039;.  However, although &#039;&#039;Func_B&#039;&#039; changes the value of the variables, the values of the original variables within &#039;&#039;Func_A&#039;&#039; are not changed.&lt;br /&gt;
&lt;br /&gt;
If we want to change the value of the variables in &#039;&#039;Func_A&#039;&#039; from within &#039;&#039;Func_B&#039;&#039;, we need to use the &#039;&#039;ByRef&#039;&#039; keyword as explained above and illustrated here:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Func_A()&lt;br /&gt;
 &lt;br /&gt;
 Func Func_A()&lt;br /&gt;
 &lt;br /&gt;
 	; Declare variables&lt;br /&gt;
 	Local $iVar_A1 = 10&lt;br /&gt;
 	Local $iVar_A2 = 20&lt;br /&gt;
 &lt;br /&gt;
 	; And read them&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Initial read in Func A:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var A1 = &amp;quot; &amp;amp; $iVar_A1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var A2 = &amp;quot; &amp;amp; $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 	; Now pass these variables to another function - but this time we will pass $iVar_A2 By Reference&lt;br /&gt;
 	Func_B($iVar_A1, $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 	; We changed the parameters in Func_B - this time we see that we have changed $iVar_A2&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Second read in Func A:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var A1 = &amp;quot; &amp;amp; $iVar_A1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var A2 = &amp;quot; &amp;amp; $iVar_A2)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func Func_B($iVar_B1, ByRef $iVar_B2) ; Note the ByRef keyword in the function declaration for the second parameter&lt;br /&gt;
 &lt;br /&gt;
 	; Now read these variables - they have the same value as the variables in Func_A&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Initial read in Func B:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var B1 = &amp;quot; &amp;amp; $iVar_B1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var B2 = &amp;quot; &amp;amp; $iVar_B2)&lt;br /&gt;
 &lt;br /&gt;
 	; Let us change them&lt;br /&gt;
 	$iVar_B1 = 100&lt;br /&gt;
 	$iVar_B2 = 200&lt;br /&gt;
 &lt;br /&gt;
 	; And confirm that they have changed&lt;br /&gt;
 	MsgBox(0x40040, &amp;quot;Read&amp;quot;, &amp;quot;Second read in Func B:&amp;quot; &amp;amp; @CRLF &amp;amp; &amp;quot;Var B1 = &amp;quot; &amp;amp; $iVar_B1 &amp;amp; @CRLF &amp;amp; &amp;quot;Var B2 = &amp;quot; &amp;amp; $iVar_B2)&lt;br /&gt;
 &lt;br /&gt;
 	; Now return to the other function&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;ByRef&#039;&#039; is a very powerful tool - but use it carefully, or you may find that you have changed a variable when you did not want to!&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Tutorials&amp;diff=11928</id>
		<title>Tutorials</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Tutorials&amp;diff=11928"/>
		<updated>2013-09-03T16:22:55Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorials]]&lt;br /&gt;
There are many tutorials available for AutoIt. This page is an overview of a few known tutorials. More tutorials can possibly be found and will be added to this page in time.&lt;br /&gt;
&lt;br /&gt;
= AutoIt beginner =&lt;br /&gt;
These tutorials describe simple tasks and AutoIt syntax.&lt;br /&gt;
&lt;br /&gt;
* [[Tutorial_Core_Language|Language tutorial]] &#039;&#039;( cheat sheet )&#039;&#039;&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=21048 Welcome to AutoIt 1-2-3]&lt;br /&gt;
* [http://www.autoitscript.com/forum/index.php?showtopic=84960 Learning to script with AutoIt v3]&lt;br /&gt;
&lt;br /&gt;
==Autoit-1-2-3==&lt;br /&gt;
&lt;br /&gt;
By Valuater, this tutorial is one of the most popular. Some key features are:&lt;br /&gt;
* Over 19 Interactive GUI&#039;s&lt;br /&gt;
* Over 50 Step-by-Step Scripts&lt;br /&gt;
* Verbal Instructions&lt;br /&gt;
* Complete with Demonstrations and Answers&lt;br /&gt;
* Exe Format for New People&lt;br /&gt;
&lt;br /&gt;
This is the second page you will see when running AutoIt 1-2-3.  It gives important links to necessary downloads and allows you to run demos that are supplied with the program.&lt;br /&gt;
[[image:Autoit-1-2-3.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
You can download AutoIt 1-2-3 from [http://www.autoitscript.com/forum/index.php?act=attach&amp;amp;type=post&amp;amp;id=10824 here], or check out the [http://www.autoitscript.com/forum/index.php?showtopic=21048&amp;amp;hl=tutorials Forum page].&lt;br /&gt;
&lt;br /&gt;
==Learning to script with AutoIt V3==&lt;br /&gt;
&lt;br /&gt;
This tutorial has example AU3 files contained in the text, printable exercise question/answer sheet and more. Originally by lxP and updated by BrettF, this is a great starting point for those who have never scripted before. For people who may have done other languages, this will also be a good back to basics tutorial.&lt;br /&gt;
&lt;br /&gt;
[http://www.autoitscript.com/forum/index.php?showtopic=84960 Download now].&lt;br /&gt;
&lt;br /&gt;
= Video =&lt;br /&gt;
These are almost 20 AutoIt video tutorials by 403forbidden. You can view all the tutorials at the link below.  They start at a beginner level and work up from there.&lt;br /&gt;
* [http://www.youtube.com/watch?v=BLU60CD-Poo AutoIt Video Tutorials - Part 1]&lt;br /&gt;
&lt;br /&gt;
Set of tutorials by [http://www.autoitscript.com/forum/user/64654-morthawt/ Morthawt]&lt;br /&gt;
* [http://www.youtube.com/playlist?list=PLNpExbvcyUkOJvgxtCPcKsuMTk9XwoWum&amp;amp;feature=view_all Easy Autoit Scripting Video Tutorials]&lt;br /&gt;
&lt;br /&gt;
= More complicated AutoIt commands and concepts =&lt;br /&gt;
*[[Arrays]]&lt;br /&gt;
*[[Tutorial GUIRegisterMsg|GUIRegisterMsg]]&lt;br /&gt;
*[[Interrupting a running function]]&lt;br /&gt;
*[[Variables - using Global, Local, Static and ByRef]]&lt;br /&gt;
*[[Managing Multiple GUIs|Managing multiple GUIs]]&lt;br /&gt;
*[[Setting Styles|Setting styles]]&lt;br /&gt;
*[[Moving and Resizing PopUp GUIs|Moving and resizing pop up GUIs]]&lt;br /&gt;
*[[Modal MsgBox Styles|Modal MsgBox styles]]&lt;br /&gt;
*[[Tabs]]&lt;br /&gt;
*[[Recursion]]&lt;br /&gt;
&lt;br /&gt;
= Tips to make your coding easier =&lt;br /&gt;
*[[Adding UDFs to AutoIt and SciTE]]&lt;br /&gt;
*[[Adding utilities to the SciTE Tools menu]]&lt;br /&gt;
*[http://www.autoitscript.com/forum/topic/131833-scite-jump-navigate-between-functions-and-regions-in-an-autoit-script/  Use tools like SciTE Jump]&lt;br /&gt;
&lt;br /&gt;
= Books =&lt;br /&gt;
[http://www.oreilly.com/catalog/9780596515126/ AutoIt v3: Your Quick Guide (Andy Flesner, O&#039;Reilly)]&lt;br /&gt;
&lt;br /&gt;
This guide teaches you the foundations of the AutoIt v3 language. You will learn about variables and includes, graphical user interfaces, user-defined functions, and conditional and loop statements. You will then apply what you have learned in examples related to the system administration field.&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Tabs&amp;diff=11660</id>
		<title>Tabs</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Tabs&amp;diff=11660"/>
		<updated>2013-05-27T10:26:24Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Tabs And How To Deal With Them=&lt;br /&gt;
&lt;br /&gt;
Tabs are a valuable tool when you need to fit a lot of controls into a small GUI.  But inexperienced users often have problems with them - particularly in making sure that controls only appear on the correct tab.  This tutorial should help. Before going further, it is important to understand the differences between controls created using the built-in AutoIt commands (&#039;&#039;GUICtrlCreate*&#039;&#039;) and those created with the UDFs.  The built-in commands produce controls which are managed internally by AutoIt - they return &#039;&#039;&#039;ControlID&#039;&#039;&#039;s.  The UDF commands create controls that are not in Autoit&#039;s internal management structure and need to be managed by the code - they normally return &#039;&#039;&#039;handles&#039;&#039;&#039; (the special unique identifier for all Windows components).&lt;br /&gt;
&lt;br /&gt;
=Tabs Created With Native AutoIt Functions=&lt;br /&gt;
&lt;br /&gt;
Any tabs created by the built-in AutoIt commands &#039;&#039;GUICtrlCreateTab/TabItem&#039;&#039; will automatically take care of displaying any built-in controls created at the same time within the tab creation structure.  Here is an example:&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$hGUI = GUICreate(&amp;quot;Built-In Tab Example&amp;quot;, 500, 500)&lt;br /&gt;
&lt;br /&gt;
$hTab = GUICtrlCreateTab(10, 10, 480, 480)&lt;br /&gt;
; Create tabitems&lt;br /&gt;
For $i = 0 To 2&lt;br /&gt;
    GUICtrlCreateTabItem(&amp;quot;Tab &amp;quot; &amp;amp; $i)&lt;br /&gt;
    GUICtrlCreateButton(&amp;quot;Button &amp;quot; &amp;amp; $i, 20 + ($i * 100), 40 + ($i * 50), 80, 30)&lt;br /&gt;
Next&lt;br /&gt;
; Close Tab definiton&lt;br /&gt;
GUICtrlCreateTabItem(&amp;quot;&amp;quot;) &lt;br /&gt;
&lt;br /&gt;
GUISetState()&lt;br /&gt;
&lt;br /&gt;
While 1&lt;br /&gt;
    Switch GUIGetMsg()&lt;br /&gt;
        Case $GUI_EVENT_CLOSE&lt;br /&gt;
            Exit&lt;br /&gt;
    EndSwitch&lt;br /&gt;
WEnd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
As you can see, the controls for each tab are created just after the TabItem on which they are to appear and before the next TabItem.  Do not forget to close the Tab definition - many tab problems are caused by omitting this vital line.&lt;br /&gt;
&lt;br /&gt;
What happens if we add some UDF created controls to these tabs?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #Include &amp;lt;GuiButton.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Built-In Tab Example&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 $hTab = GUICtrlCreateTab(10, 10, 480, 480)&lt;br /&gt;
 ; Create tabitems&lt;br /&gt;
 For $i = 0 To 2&lt;br /&gt;
     GUICtrlCreateTabItem(&amp;quot;Tab &amp;quot; &amp;amp; $i)&lt;br /&gt;
     GUICtrlCreateButton(&amp;quot;Built-In &amp;quot; &amp;amp; $i, 20 + ($i * 100), 40 + ($i * 50), 80, 30)&lt;br /&gt;
     _GUICtrlButton_Create($hGUI, &amp;quot;UDF &amp;quot; &amp;amp; $i, 20 + ($i * 100), 80 + ($i * 50),80, 30)&lt;br /&gt;
 Next&lt;br /&gt;
 ; Close Tab definiton&lt;br /&gt;
 GUICtrlCreateTabItem(&amp;quot;&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
As you can see, the UDF created controls appear on every tab.  Remember this is because they are not part of the internal AutoIt control management structure, so AutoIt does not know how to handle them.  It is up to you to manage them by seeing which tab is active and hiding/showing these controls as required:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #Include &amp;lt;GuiButton.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Global $hButtons[3]&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Built-In Tab Example&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 $hTab = GUICtrlCreateTab(10, 10, 480, 480)&lt;br /&gt;
 ; Create tabitems&lt;br /&gt;
 For $i = 0 To 2&lt;br /&gt;
     GUICtrlCreateTabItem(&amp;quot;Tab &amp;quot; &amp;amp; $i)&lt;br /&gt;
     GUICtrlCreateButton(&amp;quot;Built-In &amp;quot; &amp;amp; $i, 20 + ($i * 100), 40 + ($i * 50), 80, 30)&lt;br /&gt;
     ; Add a label to the first tab&lt;br /&gt;
     If $i = 0 Then GUICtrlCreateLabel(&amp;quot;See how &#039;laggy&#039; the UDF buttons are when selecting this tab because of using WinSetState&amp;quot;, 20, 200, 150, 60)&lt;br /&gt;
 Next&lt;br /&gt;
 &lt;br /&gt;
 GUICtrlCreateTabItem(&amp;quot;&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Create UDF controls&lt;br /&gt;
 For $i = 0 To 2&lt;br /&gt;
     $hButtons[$i] = _GUICtrlButton_Create($hGUI, &amp;quot;UDF &amp;quot; &amp;amp; $i, 20 + ($i * 100), 80 + ($i * 50),80, 30)&lt;br /&gt;
 Next&lt;br /&gt;
 &lt;br /&gt;
 ; Hide the controls so only the one on the first tab is visible&lt;br /&gt;
 WinSetState($hButtons[1], &amp;quot;&amp;quot;, @SW_HIDE)&lt;br /&gt;
 WinSetState($hButtons[2], &amp;quot;&amp;quot;, @SW_HIDE)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; This is the current active tab&lt;br /&gt;
 $iLastTab = 0&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
         Case $hTab&lt;br /&gt;
             ; Check which Tab is active&lt;br /&gt;
             $iCurrTab = GUICtrlRead($hTab)&lt;br /&gt;
             ; If the Tab has changed&lt;br /&gt;
             If $iCurrTab &amp;lt;&amp;gt; $iLastTab Then&lt;br /&gt;
                 ; Show/Hide controls as required&lt;br /&gt;
                 Switch $iCurrTab&lt;br /&gt;
                     Case 0&lt;br /&gt;
                         ; Note lag when WinSetState is used&lt;br /&gt;
                         WinSetState($hButtons[1], &amp;quot;&amp;quot;, @SW_HIDE)&lt;br /&gt;
                         WinSetState($hButtons[2], &amp;quot;&amp;quot;, @SW_HIDE)&lt;br /&gt;
                         WinSetState($hButtons[0], &amp;quot;&amp;quot;, @SW_SHOW)&lt;br /&gt;
                     Case 1&lt;br /&gt;
                         ; No lag when using ControlHide/Show&lt;br /&gt;
                         ControlHide($hGUI, &amp;quot;&amp;quot;, $hButtons[0])&lt;br /&gt;
                         ControlHide($hGUI, &amp;quot;&amp;quot;, $hButtons[2])&lt;br /&gt;
                         ControlShow($hGUI, &amp;quot;&amp;quot;, $hButtons[1])&lt;br /&gt;
                     Case 2&lt;br /&gt;
                         ; Nor when using this DLL&lt;br /&gt;
                         DllCall(&amp;quot;User32.dll&amp;quot;, &amp;quot;bool&amp;quot;, &amp;quot;ShowWindowAsync&amp;quot;, &amp;quot;hwnd&amp;quot;, $hButtons[0], &amp;quot;int&amp;quot;, @SW_HIDE)&lt;br /&gt;
                         DllCall(&amp;quot;User32.dll&amp;quot;, &amp;quot;bool&amp;quot;, &amp;quot;ShowWindowAsync&amp;quot;, &amp;quot;hwnd&amp;quot;, $hButtons[1], &amp;quot;int&amp;quot;, @SW_HIDE)&lt;br /&gt;
                         DllCall(&amp;quot;User32.dll&amp;quot;, &amp;quot;bool&amp;quot;, &amp;quot;ShowWindowAsync&amp;quot;, &amp;quot;hwnd&amp;quot;, $hButtons[2], &amp;quot;int&amp;quot;, @SW_SHOW)&lt;br /&gt;
 &lt;br /&gt;
                 EndSwitch&lt;br /&gt;
                 ; Store the value for future comparisons&lt;br /&gt;
                 $iLastTab = $iCurrTab&lt;br /&gt;
             EndIf&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note the lag in hiding/showing the UDF created controls if you use &#039;&#039;WinSetState&#039;&#039; - I would recommend using &#039;&#039;ControlShow/Hide&#039;&#039; which gives an instantaneous response.  Also how you do not need to create the UDF controls within the tab creation structure - as you have to look after them, there is no requirement to do so.&lt;br /&gt;
&lt;br /&gt;
=Tabs Created With UDFs=&lt;br /&gt;
&lt;br /&gt;
Now let us look at Tabs created with the &#039;&#039;GUITab&#039;&#039; UDF.  In this case you need to manage all of the controls on the tabs yourself, even if they are created using the built-in commands:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #Include &amp;lt;GuiButton.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;GuiTab.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Global $hBuiltIn_Buttons[3]&lt;br /&gt;
 Global $hUDF_Buttons[3]&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Built-In Tab Example&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 $hTab = _GUICtrlTab_Create($hGUI, 10, 10, 480, 480)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; Add tabs&lt;br /&gt;
 _GUICtrlTab_InsertItem($hTab, 0, &amp;quot;Tab 0&amp;quot;)&lt;br /&gt;
 _GUICtrlTab_InsertItem($hTab, 1, &amp;quot;Tab 1&amp;quot;)&lt;br /&gt;
 _GUICtrlTab_InsertItem($hTab, 2, &amp;quot;Tab 2&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Create the Built-in and UDF buttons&lt;br /&gt;
 For $i = 0 To 2&lt;br /&gt;
     $hBuiltIn_Buttons[$i] = GUICtrlCreateButton(&amp;quot;Button &amp;quot; &amp;amp; $i, 20 + ($i * 100), 40 + ($i * 50), 80, 30)&lt;br /&gt;
     $hUDF_Buttons[$i] = _GUICtrlButton_Create($hGUI, &amp;quot;UDF &amp;quot; &amp;amp; $i, 20 + ($i * 100), 80 + ($i * 50),80, 30)&lt;br /&gt;
 Next&lt;br /&gt;
 &lt;br /&gt;
 ; Hide the controls so only the one on the first tab is visible&lt;br /&gt;
 GUICtrlSetState($hBuiltIn_Buttons[1], $GUI_HIDE)&lt;br /&gt;
 GUICtrlSetState($hBuiltIn_Buttons[2], $GUI_HIDE)&lt;br /&gt;
 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[1])&lt;br /&gt;
 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[2])&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; This is the current active tab&lt;br /&gt;
 $iLastTab = 0&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 &lt;br /&gt;
     ; Check which Tab is active&lt;br /&gt;
     $iCurrTab = _GUICtrlTab_GetCurFocus($hTab)&lt;br /&gt;
     ; If the Tab has changed&lt;br /&gt;
     If $iCurrTab &amp;lt;&amp;gt; $iLastTab Then&lt;br /&gt;
         ; Store the value for future comparisons&lt;br /&gt;
         $iLastTab = $iCurrTab&lt;br /&gt;
         ; Show/Hide controls as required&lt;br /&gt;
         Switch $iCurrTab&lt;br /&gt;
             Case 0&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[1], $GUI_HIDE)&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[2], $GUI_HIDE)&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[0], $GUI_SHOW)&lt;br /&gt;
                 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[1])&lt;br /&gt;
                 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[2])&lt;br /&gt;
                 ControlShow($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[0])&lt;br /&gt;
             Case 1&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[0], $GUI_HIDE)&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[2], $GUI_HIDE)&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[1], $GUI_SHOW)&lt;br /&gt;
                 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[0])&lt;br /&gt;
                 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[2])&lt;br /&gt;
                 ControlShow($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[1])&lt;br /&gt;
            Case 2&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[0], $GUI_HIDE)&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[1], $GUI_HIDE)&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[2], $GUI_SHOW)&lt;br /&gt;
                 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[0])&lt;br /&gt;
                 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[1])&lt;br /&gt;
                 ControlShow($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[2])&lt;br /&gt;
         EndSwitch&lt;br /&gt;
     EndIf&lt;br /&gt;
 WEnd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
A lot of work but a very satisfactory result.  Note the need to use different commands to hide/show the built-in and UDF created controls to avoid &amp;quot;lag&amp;quot; on the latter as was shown in the earlier example.&lt;br /&gt;
&lt;br /&gt;
So, a couple of lessons to draw from this:&lt;br /&gt;
&lt;br /&gt;
- 1.  When using tabs, try and use built-in commands if at all possible.  If you do, AutoIt looks after the showing/hiding problem for you as long as you create the controls &#039;&#039;within&#039;&#039; the tab creation structure.  See the next section for how to add controls to tabs after their creation.&lt;br /&gt;
&lt;br /&gt;
- 2.  If you must use UDF created controls for any reason, you have to manage hiding/showing all controls yourself.&lt;br /&gt;
&lt;br /&gt;
=Adding Controls To Tabs After Creation=&lt;br /&gt;
&lt;br /&gt;
If you need to add built-in controls to a tab after the tabs have already been created, then you &#039;&#039;must&#039;&#039; use &#039;&#039;GUISwitch&#039;&#039; with the &#039;&#039;tabitemID&#039;&#039; parameter to select the correct tab before you create the control or you will find that it is visible on all tabs.&lt;br /&gt;
&lt;br /&gt;
Here is an example to show how to do it:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
&lt;br /&gt;
$cTab = GUICtrlCreateTab(10, 10, 480, 350)&lt;br /&gt;
$cTab_0 = GUICtrlCreateTabItem(&amp;quot;Tab 0&amp;quot;)&lt;br /&gt;
$cTab_1 = GUICtrlCreateTabItem(&amp;quot;Tab 1&amp;quot;)&lt;br /&gt;
GUICtrlCreateTabItem(&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
$cButton = GUICtrlCreateButton(&amp;quot;Add controls&amp;quot;, 10, 450, 80, 30)&lt;br /&gt;
&lt;br /&gt;
GUISetState()&lt;br /&gt;
&lt;br /&gt;
While 1&lt;br /&gt;
	Switch GUIGetMsg()&lt;br /&gt;
		Case $GUI_EVENT_CLOSE&lt;br /&gt;
			Exit&lt;br /&gt;
		Case $cButton&lt;br /&gt;
			; Correct&lt;br /&gt;
			GUISwitch($hGUI, $cTab_0)&lt;br /&gt;
			GUICtrlCreateLabel(&amp;quot;Only on Tab 0&amp;quot;, 40, 40, 200, 20)&lt;br /&gt;
			GUICtrlSetBkColor(-1, 0xCCFFCC)&lt;br /&gt;
			GUICtrlCreateTabItem(&amp;quot;&amp;quot;)&lt;br /&gt;
			GUISwitch($hGUI)&lt;br /&gt;
			; Incorrect&lt;br /&gt;
			GUICtrlCreateLabel(&amp;quot;OnTab 0 AND Tab 1&amp;quot;, 40, 100, 200, 20)&lt;br /&gt;
			GUICtrlSetBkColor(-1, 0xFFCCCC)&lt;br /&gt;
	EndSwitch&lt;br /&gt;
WEnd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Do not forget to reclose the tab definition after adding the new controls.&lt;br /&gt;
&lt;br /&gt;
=Multiple Tabs In A GUI=&lt;br /&gt;
&lt;br /&gt;
Unfortunately, only one built-in tab control can be created per GUI - you cannot have several tabs on a single GUI.  But there is a way around this - just create child GUIs which can each hold a tab:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;WindowsConstants.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; Create child GUIs to hold tabs&lt;br /&gt;
 $hTab_Win0 = GUICreate(&amp;quot;&amp;quot;, 400, 200, 50, 20, $WS_POPUP, $WS_EX_MDICHILD, $hGUI)&lt;br /&gt;
 $hTab_0 = GUICtrlCreateTab(10, 10, 380, 180)&lt;br /&gt;
     $hTab_00 = GUICtrlCreateTabitem(&amp;quot;00&amp;quot;)&lt;br /&gt;
         GUICtrlCreateButton(&amp;quot;00&amp;quot;, 160, 90, 80, 30)&lt;br /&gt;
     $hTab_01 = GUICtrlCreateTabitem(&amp;quot;01&amp;quot;)&lt;br /&gt;
         GUICtrlCreateButton(&amp;quot;01&amp;quot;, 160, 90, 80, 30)&lt;br /&gt;
 &lt;br /&gt;
 GUICtrlCreateTabitem (&amp;quot;&amp;quot;)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 $hTab_Win1 = GUICreate(&amp;quot;&amp;quot;, 400, 200, 50, 250, $WS_POPUP, $WS_EX_MDICHILD, $hGUI)&lt;br /&gt;
 $hTab_1 = GUICtrlCreateTab(10, 10, 380, 180)&lt;br /&gt;
     $hTab_10 = GUICtrlCreateTabitem(&amp;quot;10&amp;quot;)&lt;br /&gt;
         GUICtrlCreateButton(&amp;quot;10&amp;quot;, 160, 90, 80, 30)&lt;br /&gt;
     $hTab_11 = GUICtrlCreateTabitem(&amp;quot;11&amp;quot;)&lt;br /&gt;
         GUICtrlCreateButton(&amp;quot;11&amp;quot;, 160, 90, 80, 30)&lt;br /&gt;
 GUICtrlCreateTabitem (&amp;quot;&amp;quot;)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Easy when you know how!&lt;br /&gt;
&lt;br /&gt;
=Summary=&lt;br /&gt;
&lt;br /&gt;
Tabs are useful controls, but can be difficult to master.  After this tutorial you should be well on your way!&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Interrupting_a_running_function&amp;diff=11599</id>
		<title>Interrupting a running function</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Interrupting_a_running_function&amp;diff=11599"/>
		<updated>2013-02-10T11:05:03Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorials]]&lt;br /&gt;
This is a common question and this tutorial explains how to do it within the limitations of Autoit.&lt;br /&gt;
&lt;br /&gt;
AutoIt queues function calls in both &#039;&#039;OnEvent&#039;&#039; and &#039;&#039;MessageLoop&#039;&#039; modes.  This means that it waits until a function is finished and the code is back in your idle &#039;&#039;While...WEnd&#039;&#039; loop before running the next.&lt;br /&gt;
&lt;br /&gt;
Here are 2 short scripts in both modes to show this in action.  Start &#039;&#039;Function 1&#039;&#039; by pressing its button and then immediately try to run &#039;&#039;Function 2&#039;&#039; by pressing its button a couple of times.  You will see from the console output that &#039;&#039;Function 2&#039;&#039; will only run &#039;&#039;&#039;AFTER&#039;&#039;&#039; &#039;&#039;Function 1&#039;&#039; has terminated - and then it will run as many times as you pressed the button.&lt;br /&gt;
&lt;br /&gt;
We start with &#039;&#039;MessageLoop&#039;&#039; mode:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 $hButton_1 = GUICtrlCreateButton(&amp;quot;Func One&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
 $hButton_2 = GUICtrlCreateButton(&amp;quot;Func Two&amp;quot;, 10, 50, 80, 30)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
         Case $hButton_1&lt;br /&gt;
             _Func_1()&lt;br /&gt;
         Case $hButton_2&lt;br /&gt;
         _Func_2()&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
     For $i = 1 To 20&lt;br /&gt;
         ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_2()&lt;br /&gt;
     For $i = 1 To 3&lt;br /&gt;
         ConsoleWrite(&amp;quot;+Func 2 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 2 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
And now in &#039;&#039;OnEvent&#039;&#039; mode:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Opt(&amp;quot;GUIOnEventMode&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 GUISetOnEvent($GUI_EVENT_CLOSE, &amp;quot;_Exit&amp;quot;) &lt;br /&gt;
 &lt;br /&gt;
 $hButton_1 = GUICtrlCreateButton(&amp;quot;Func One&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_1, &amp;quot;_Func_1&amp;quot;)&lt;br /&gt;
 $hButton_2 = GUICtrlCreateButton(&amp;quot;Func Two&amp;quot;, 10, 50, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_2, &amp;quot;_Func_2&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Sleep(10)&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
 For $i = 1 To 20&lt;br /&gt;
     ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_2()&lt;br /&gt;
     For $i = 1 To 3&lt;br /&gt;
         ConsoleWrite(&amp;quot;+Func 2 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 2 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Exit()&lt;br /&gt;
     Exit&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
So is it impossible to interrupt a running function?  Of course not or this tutorial would serve no purpose - but there are limitations on the type of function which can be interrupted.  &lt;br /&gt;
&lt;br /&gt;
If you are in &#039;&#039;OnEvent&#039;&#039; mode then there is an easy way to interrupt a running function, as long as the function is started within the main code and not by an &#039;&#039;OnEvent&#039;&#039; call.  This script shows how to do it by using a flag and checking if it is set - in this way the function is started by the main script and can be interrupted.&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ; Declare a flag&lt;br /&gt;
 Global $fRunOne = False&lt;br /&gt;
 &lt;br /&gt;
 Opt(&amp;quot;GUIOnEventMode&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 GUISetOnEvent($GUI_EVENT_CLOSE, &amp;quot;_Exit&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 $hButton_1 = GUICtrlCreateButton(&amp;quot;Func One&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_1, &amp;quot;_Func_1&amp;quot;)&lt;br /&gt;
 $hButton_2 = GUICtrlCreateButton(&amp;quot;Func Two&amp;quot;, 10, 50, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_2, &amp;quot;_Func_2&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Sleep(10)&lt;br /&gt;
     ; Check if the flag has been set by the OnEvent function&lt;br /&gt;
     If $fRunOne Then&lt;br /&gt;
         ; Now start the &amp;quot;real&amp;quot; function from within the main code&lt;br /&gt;
         _Func_1_Run()&lt;br /&gt;
     EndIf&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
     ; Set the flag within the OnEvent function&lt;br /&gt;
     $fRunOne = True&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Func_1&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1_Run()&lt;br /&gt;
     For $i = 1 To 20&lt;br /&gt;
         ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
     Global $fRunOne = False&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Func_1_Run&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_2()&lt;br /&gt;
     For $i = 1 To 3&lt;br /&gt;
         ConsoleWrite(&amp;quot;+Func 2 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 2 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Func_2&lt;br /&gt;
 &lt;br /&gt;
 Func _Exit()&lt;br /&gt;
     Exit&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
However, this method does not work in &#039;&#039;MessageLoop&#039;&#039; mode, nor when you want to interrupt a function which was started by an &#039;&#039;OnEvent&#039;&#039; call in &#039;&#039;OnEvent&#039;&#039; mode.  In these cases the function you want to interrupt must have regular checks of a flag which we set when we want to interrupt.  If the function does not have a suitable loop where such a check is easy to make, you might not be able to interrupt it.&lt;br /&gt;
&lt;br /&gt;
Let us now look at the 2 ways an AutoIt script can break into a suitable function: a &#039;&#039;&#039;HotKey&#039;&#039;&#039; and a &#039;&#039;&#039;Windows message handler&#039;&#039;&#039;.  The first is easier to code, but cannot be linked to a control on your GUI; the latter is a little more complicated to code, but can be linked to a control.&lt;br /&gt;
&lt;br /&gt;
How do they work?&lt;br /&gt;
&lt;br /&gt;
Let us start with the &#039;&#039;HotKey&#039;&#039;.  From the AutoIt Help file: &#039;&#039;A hotkey-press *typically* interrupts the active AutoIt function/statement and runs its user function until it completes or is interrupted&#039;&#039;.  So a &#039;&#039;HotKey&#039;&#039; press is designed to interrupt your running function - just what we need.  But the running function will resume after the &#039;&#039;HotKey&#039;&#039; function terminates - so, as explained above, we use the &#039;&#039;HotKey&#039;&#039; function to set a flag which is looked for by our running function.  Remember that this flag must be declared as a &#039;&#039;Global&#039;&#039; variable because it needs to be seen by both functions.&lt;br /&gt;
&lt;br /&gt;
Now many coders do not like using &#039;&#039;HotKey&#039;&#039;s because they remain active while a script is running and can interfere with other apps.  One way to get around this is to use &#039;&#039;Accelerator&#039;&#039; keys - these look very much like &#039;&#039;HotKey&#039;&#039;s to the user, but are only active in the script in which they are declared.  Although &#039;&#039;Accelerator&#039;&#039; keys look like &#039;&#039;HotKey&#039;&#039;s, they are tied to GUI controls and you must use the &#039;&#039;message handler&#039;&#039; method explained below if you want to use them to interrupt a running function.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;Windows message handler&#039;&#039; method is a little more complicated and if you are not used to working with them, you might want to read the [[GUIRegisterMsg]] tutorial first.&lt;br /&gt;
&lt;br /&gt;
What we do here is intercept the message that your GUI control sends when it is activated - the same message that AutoIt queues to run the required code once the running function terminates.  We use our own message to get a sneak preview of this queuing and use it to set a similar flag to that described above.  If our running function sees the flag, it terminates and AutoIt then runs the function waiting in the queue - simple really!&lt;br /&gt;
&lt;br /&gt;
Here are scripts using both methods to show how &#039;&#039;HotKey&#039;&#039;s, &#039;&#039;Accelerator&#039;&#039; keys and GUI controls can interrupt a running function.  Just as before, start &#039;&#039;Function_1&#039;&#039; by pressing its button  - but now you can interrupt it at will!&lt;br /&gt;
&lt;br /&gt;
First in &#039;&#039;MessageLoop&#039;&#039; mode:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;WindowsConstants.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ; Set a HotKey&lt;br /&gt;
 HotKeySet(&amp;quot;x&amp;quot;, &amp;quot;_Interrupt&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Declare a flag&lt;br /&gt;
 $fInterrupt = 0&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 $hButton_1 = GUICtrlCreateButton(&amp;quot;Func One&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
 $hButton_2 = GUICtrlCreateButton(&amp;quot;Func Two&amp;quot;, 10, 50, 80, 30)&lt;br /&gt;
 &lt;br /&gt;
 ; Create a dummy control for the Accelerator to action when pressed&lt;br /&gt;
 $hAccelInterupt = GUICtrlCreateDummy()&lt;br /&gt;
 ; Set an Accelerator key to action the dummy control&lt;br /&gt;
 Dim $AccelKeys[1][2]=[ [&amp;quot;z&amp;quot;, $hAccelInterupt] ]&lt;br /&gt;
 GUISetAccelerators($AccelKeys)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; Intercept Windows command messages with out own handler&lt;br /&gt;
 GUIRegisterMsg($WM_COMMAND, &amp;quot;_WM_COMMAND&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
         Case $hButton_1&lt;br /&gt;
             _Func_1()&lt;br /&gt;
         Case $hButton_2&lt;br /&gt;
             _Func_2()&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
     ; Make sure the flag is cleared&lt;br /&gt;
     $fInterrupt = 0&lt;br /&gt;
     For $i = 1 To 20&lt;br /&gt;
         ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         ; Look for the flag&lt;br /&gt;
         If $fInterrupt &amp;lt;&amp;gt; 0 Then&lt;br /&gt;
             ; The flag was set&lt;br /&gt;
             Switch $fInterrupt&lt;br /&gt;
                 Case 1&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by Func 2&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
                 Case 2&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by HotKey&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
                 Case 3&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by Accelerator&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
             EndSwitch&lt;br /&gt;
             Return&lt;br /&gt;
         EndIf&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_2()&lt;br /&gt;
     For $i = 1 To 3&lt;br /&gt;
         ConsoleWrite(&amp;quot;+Func 2 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 2 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Interrupt()&lt;br /&gt;
     ; The HotKey was pressed so set the flag&lt;br /&gt;
     $fInterrupt = 2&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)&lt;br /&gt;
     ; The Func 2 button was pressed so set the flag&lt;br /&gt;
     If BitAND($wParam, 0x0000FFFF) =  $hButton_2 Then $fInterrupt = 1&lt;br /&gt;
     ; The dummy control was actioned by the Accelerator key so set the flag&lt;br /&gt;
     If BitAND($wParam, 0x0000FFFF) =  $hAccelInterupt Then $fInterrupt = 3&lt;br /&gt;
     Return $GUI_RUNDEFMSG&lt;br /&gt;
 EndFunc   ;==&amp;gt;_WM_COMMAND&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
And now in &#039;&#039;OnEvent&#039;&#039; mode:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;WindowsConstants.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ; Set a HotKey&lt;br /&gt;
 HotKeySet(&amp;quot;x&amp;quot;, &amp;quot;_Interrupt_HotKey&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Declare a flag&lt;br /&gt;
 $fInterrupt = 0&lt;br /&gt;
 &lt;br /&gt;
 Opt(&amp;quot;GUIOnEventMode&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 GUISetOnEvent($GUI_EVENT_CLOSE, &amp;quot;_Exit&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 $hButton_1 = GUICtrlCreateButton(&amp;quot;Func One&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_1, &amp;quot;_Func_1&amp;quot;)&lt;br /&gt;
 $hButton_2 = GUICtrlCreateButton(&amp;quot;Func Two&amp;quot;, 10, 50, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_2, &amp;quot;_Func_2&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Create a dummy control for the Accelerator to action&lt;br /&gt;
 $hAccelInterupt = GUICtrlCreateDummy()&lt;br /&gt;
 GUICtrlSetOnEvent($hAccelInterupt, &amp;quot;_Interrupt_Accel&amp;quot;)&lt;br /&gt;
 ; Set an Accelerator key to action the dummy control&lt;br /&gt;
 Dim $AccelKeys[1][2]=[ [&amp;quot;z&amp;quot;, $hAccelInterupt] ]&lt;br /&gt;
 GUISetAccelerators($AccelKeys)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; Intercept Windows command messages with out own handler&lt;br /&gt;
 GUIRegisterMsg($WM_COMMAND, &amp;quot;_WM_COMMAND&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
 	Sleep(10)&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
     ; Make sure the flag is cleared&lt;br /&gt;
     $fInterrupt = 0&lt;br /&gt;
     For $i = 1 To 20&lt;br /&gt;
         ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         ; Look for the flag&lt;br /&gt;
         If $fInterrupt &amp;lt;&amp;gt; 0 Then&lt;br /&gt;
             ; The flag was set&lt;br /&gt;
             Switch $fInterrupt&lt;br /&gt;
                 Case 1&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by Func 2&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
                 Case 2&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by HotKey&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
                 Case 3&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by Accelerator&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
             EndSwitch&lt;br /&gt;
             Return&lt;br /&gt;
         EndIf&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_2()&lt;br /&gt;
     For $i = 1 To 3&lt;br /&gt;
         ConsoleWrite(&amp;quot;+Func 2 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 2 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Exit()&lt;br /&gt;
     Exit&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Interrupt_HotKey()&lt;br /&gt;
     ; The HotKey was pressed so set the flag&lt;br /&gt;
     $fInterrupt = 2&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Interrupt_Accel()&lt;br /&gt;
     ; This is an empty function for the dummy control linked to the Accelerator key&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)&lt;br /&gt;
     ; The Func 2 button was pressed so set the flag&lt;br /&gt;
     If BitAND($wParam, 0x0000FFFF) =  $hButton_2 Then $fInterrupt = 1&lt;br /&gt;
     ; The dummy control was actioned by the Accelerator key so set the flag&lt;br /&gt;
     If BitAND($wParam, 0x0000FFFF) =  $hAccelInterupt Then $fInterrupt = 3&lt;br /&gt;
     Return $GUI_RUNDEFMSG&lt;br /&gt;
 EndFunc   ;==&amp;gt;_WM_COMMAND&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
But what if you want to have a longish &#039;&#039;Sleep&#039;&#039; or some other function which waits for a fair time inside the running function?  If you add a &#039;&#039;Sleep(5000)&#039;&#039; to &#039;&#039;Func_1&#039;&#039; in the above examples, you will see that you have to wait until the function returns from the &#039;&#039;Sleep&#039;&#039; before the interrupt is actioned, which is not what we want:&lt;br /&gt;
----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
 	; Make sure the flag is cleared&lt;br /&gt;
 	$fInterrupt = 0&lt;br /&gt;
 	For $i = 1 To 20&lt;br /&gt;
 		ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 		; Add a long Sleep ; &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;br /&gt;
 		Sleep(5000)&lt;br /&gt;
 		; Look for the flag&lt;br /&gt;
          	If $fInterrupt &amp;lt;&amp;gt; 0 Then&lt;br /&gt;
 			; The flag was set&lt;br /&gt;
 			Switch $fInterrupt&lt;br /&gt;
 				Case 1&lt;br /&gt;
 					ConsoleWrite(&amp;quot;!Func 1 interrrupted by Func 2&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 				Case 2&lt;br /&gt;
 					ConsoleWrite(&amp;quot;!Func 1 interrrupted by HotKey&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 				Case 3&lt;br /&gt;
 					ConsoleWrite(&amp;quot;!Func 1 interrrupted by Accelerator&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 			EndSwitch&lt;br /&gt;
 			Return&lt;br /&gt;
 		EndIf&lt;br /&gt;
 		Sleep(100)&lt;br /&gt;
 	Next&lt;br /&gt;
 	ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Func_1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&lt;br /&gt;
The answer is to put the blocking function inside a wrapper function which does check for the interrupt flag at regular intervals.  Replace the Sleep line with a call to the wrapper function and add the wrapper function to the script:&lt;br /&gt;
&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 ; Use a wrapper function in place of the blocking function&lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
 	; Make sure the flag is cleared&lt;br /&gt;
 	$fInterrupt = 0&lt;br /&gt;
 	For $i = 1 To 20&lt;br /&gt;
 		ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 		; Run a modified Sleep function which checks for the interrupt&lt;br /&gt;
 		If _Interrupt_Sleep(5000) Then ; &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;br /&gt;
 			; The flag was set&lt;br /&gt;
 			Switch $fInterrupt&lt;br /&gt;
 				Case 1&lt;br /&gt;
 					ConsoleWrite(&amp;quot;!Func 1 interrrupted by Func 2&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 				Case 2&lt;br /&gt;
 					ConsoleWrite(&amp;quot;!Func 1 interrrupted by HotKey&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 				Case 3&lt;br /&gt;
 					ConsoleWrite(&amp;quot;!Func 1 interrrupted by Accelerator&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 			EndSwitch&lt;br /&gt;
 			Return&lt;br /&gt;
 		EndIf&lt;br /&gt;
 		Sleep(100)&lt;br /&gt;
 	Next&lt;br /&gt;
 	ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Func_1&lt;br /&gt;
 &lt;br /&gt;
 ; And here is the wrapper function itself&lt;br /&gt;
 Func _Interrupt_Sleep($iDelay)&lt;br /&gt;
 	; Get a timestamp&lt;br /&gt;
 	Local $iBegin = TimerInit()&lt;br /&gt;
 	; And run a tight loop&lt;br /&gt;
 	Do&lt;br /&gt;
 		; Use a minimum Sleep (could also be a WinWaitActive with a short timeout)&lt;br /&gt;
 		Sleep(10)&lt;br /&gt;
 		; Look for the interrrupt&lt;br /&gt;
 		If $fInterrupt Then&lt;br /&gt;
 			; And return True immediately if set&lt;br /&gt;
 			Return True&lt;br /&gt;
 		EndIf&lt;br /&gt;
 	Until TimerDiff($iBegin) &amp;gt; $iDelay&lt;br /&gt;
 	; Return False if timed out and no interrupt was set&lt;br /&gt;
 	Return False&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Interrupt_Sleep&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
So there are the ways available in AutoIt to interrupt a running function.  Remember that you must be in &#039;&#039;OnEvent&#039;&#039; mode and start the function from the main code - or have a function which checks internally whether it ought to allow an interruption.  You may need to use a wrapper function if you want to use a blocking function such as &#039;&#039;Sleep&#039;&#039; or &#039;&#039;WinWaitActive&#039;&#039;.  In all other cases you are are not going to be able to interrupt your function.&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Interrupting_a_running_function&amp;diff=11598</id>
		<title>Interrupting a running function</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Interrupting_a_running_function&amp;diff=11598"/>
		<updated>2013-02-07T10:43:00Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Tutorials]]&lt;br /&gt;
This is a common question and this tutorial explains how to do it within the limitations of Autoit.&lt;br /&gt;
&lt;br /&gt;
AutoIt queues function calls in both &#039;&#039;OnEvent&#039;&#039; and &#039;&#039;MessageLoop&#039;&#039; modes.  This means that it waits until a function is finished and the code is back in your idle &#039;&#039;While...WEnd&#039;&#039; loop before running the next.&lt;br /&gt;
&lt;br /&gt;
Here are 2 short scripts in both modes to show this in action.  Start &#039;&#039;Function 1&#039;&#039; by pressing its button and then immediately try to run &#039;&#039;Function 2&#039;&#039; by pressing its button a couple of times.  You will see from the console output that &#039;&#039;Function 2&#039;&#039; will only run &#039;&#039;&#039;AFTER&#039;&#039;&#039; &#039;&#039;Function 1&#039;&#039; has terminated - and then it will run as many times as you pressed the button.&lt;br /&gt;
&lt;br /&gt;
We start with &#039;&#039;MessageLoop&#039;&#039; mode:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 $hButton_1 = GUICtrlCreateButton(&amp;quot;Func One&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
 $hButton_2 = GUICtrlCreateButton(&amp;quot;Func Two&amp;quot;, 10, 50, 80, 30)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
         Case $hButton_1&lt;br /&gt;
             _Func_1()&lt;br /&gt;
         Case $hButton_2&lt;br /&gt;
         _Func_2()&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
     For $i = 1 To 20&lt;br /&gt;
         ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_2()&lt;br /&gt;
     For $i = 1 To 3&lt;br /&gt;
         ConsoleWrite(&amp;quot;+Func 2 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 2 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
And now in &#039;&#039;OnEvent&#039;&#039; mode:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Opt(&amp;quot;GUIOnEventMode&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 GUISetOnEvent($GUI_EVENT_CLOSE, &amp;quot;_Exit&amp;quot;) &lt;br /&gt;
 &lt;br /&gt;
 $hButton_1 = GUICtrlCreateButton(&amp;quot;Func One&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_1, &amp;quot;_Func_1&amp;quot;)&lt;br /&gt;
 $hButton_2 = GUICtrlCreateButton(&amp;quot;Func Two&amp;quot;, 10, 50, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_2, &amp;quot;_Func_2&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Sleep(10)&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
 For $i = 1 To 20&lt;br /&gt;
     ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_2()&lt;br /&gt;
     For $i = 1 To 3&lt;br /&gt;
         ConsoleWrite(&amp;quot;+Func 2 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 2 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Exit()&lt;br /&gt;
     Exit&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
So is it impossible to interrupt a running function?  Of course not or this tutorial would serve no purpose - but there are limitations on the type of function which can be interrupted.  &lt;br /&gt;
&lt;br /&gt;
If you are in &#039;&#039;OnEvent&#039;&#039; mode then there is an easy way to interrupt a running function, as long as the function is started within the main code and not by an &#039;&#039;OnEvent&#039;&#039; call.  This script shows how to do it by using a flag and checking if it is set - in this way the function is started by the main script and can be interrupted.&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ; Declare a flag&lt;br /&gt;
 Global $fRunOne = False&lt;br /&gt;
 &lt;br /&gt;
 Opt(&amp;quot;GUIOnEventMode&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 GUISetOnEvent($GUI_EVENT_CLOSE, &amp;quot;_Exit&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 $hButton_1 = GUICtrlCreateButton(&amp;quot;Func One&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_1, &amp;quot;_Func_1&amp;quot;)&lt;br /&gt;
 $hButton_2 = GUICtrlCreateButton(&amp;quot;Func Two&amp;quot;, 10, 50, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_2, &amp;quot;_Func_2&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Sleep(10)&lt;br /&gt;
     ; Check if the flag has been set by the OnEvent function&lt;br /&gt;
     If $fRunOne Then&lt;br /&gt;
         ; Now start the &amp;quot;real&amp;quot; function from within the main code&lt;br /&gt;
         _Func_1_Run()&lt;br /&gt;
     EndIf&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
     ; Set the flag within the OnEvent function&lt;br /&gt;
     $fRunOne = True&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Func_1&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1_Run()&lt;br /&gt;
     For $i = 1 To 20&lt;br /&gt;
         ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
     Global $fRunOne = False&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Func_1_Run&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_2()&lt;br /&gt;
     For $i = 1 To 3&lt;br /&gt;
         ConsoleWrite(&amp;quot;+Func 2 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 2 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Func_2&lt;br /&gt;
 &lt;br /&gt;
 Func _Exit()&lt;br /&gt;
     Exit&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
However, this method does not work in &#039;&#039;MessageLoop&#039;&#039; mode, not when you want to interrupt a function which was started by an &#039;&#039;OnEvent&#039;&#039; call in &#039;&#039;OnEvent&#039;&#039; mode.  In these cases the function you want to interrupt must have regular checks of a flag which we set when we want to interrupt.  If the function does not have a suitable loop where such a check is easy to make, you might not be able to interrupt it.&lt;br /&gt;
&lt;br /&gt;
Let us now look at the 2 ways an AutoIt script can break into a suitable function: a &#039;&#039;&#039;HotKey&#039;&#039;&#039; and a &#039;&#039;&#039;Windows message handler&#039;&#039;&#039;.  The first is easier to code, but cannot be linked to a control on your GUI; the latter is a little more complicated to code, but can be linked to a control.&lt;br /&gt;
&lt;br /&gt;
How do they work?&lt;br /&gt;
&lt;br /&gt;
Let us start with the &#039;&#039;HotKey&#039;&#039;.  From the AutoIt Help file: &#039;&#039;A hotkey-press *typically* interrupts the active AutoIt function/statement and runs its user function until it completes or is interrupted&#039;&#039;.  So a &#039;&#039;HotKey&#039;&#039; press is designed to interrupt your running function - just what we need.  But the running function will resume after the &#039;&#039;HotKey&#039;&#039; function terminates - so, as explained above, we use the &#039;&#039;HotKey&#039;&#039; function to set a flag which is looked for by our running function.  Remember that this flag must be declared as a &#039;&#039;Global&#039;&#039; variable because it needs to be seen by both functions.&lt;br /&gt;
&lt;br /&gt;
Now many coders do not like using &#039;&#039;HotKey&#039;&#039;s because they remain active while a script is running and can interfere with other apps.  One way to get around this is to use &#039;&#039;Accelerator&#039;&#039; keys - these look very much like &#039;&#039;HotKey&#039;&#039;s to the user, but are only active in the script in which they are declared.  Although &#039;&#039;Accelerator&#039;&#039; keys look like &#039;&#039;HotKey&#039;&#039;s, they are tied to GUI controls and you must use the &#039;&#039;message handler&#039;&#039; method explained below if you want to use them to interrupt a running function.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;Windows message handler&#039;&#039; method is a little more complicated and if you are not used to working with them, you might want to read the [[GUIRegisterMsg]] tutorial first.&lt;br /&gt;
&lt;br /&gt;
What we do here is intercept the message that your GUI control sends when it is activated - the same message that AutoIt queues to run the required code once the running function terminates.  We use our own message to get a sneak preview of this queuing and use it to set a similar flag to that described above.  If our running function sees the flag, it terminates and AutoIt then runs the function waiting in the queue - simple really!&lt;br /&gt;
&lt;br /&gt;
Here are scripts using both methods to show how &#039;&#039;HotKey&#039;&#039;s, &#039;&#039;Accelerator&#039;&#039; keys and GUI controls can interrupt a running function.  Just as before, start &#039;&#039;Function_1&#039;&#039; by pressing its button  - but now you can interrupt it at will!&lt;br /&gt;
&lt;br /&gt;
First in &#039;&#039;MessageLoop&#039;&#039; mode:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;WindowsConstants.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ; Set a HotKey&lt;br /&gt;
 HotKeySet(&amp;quot;x&amp;quot;, &amp;quot;_Interrupt&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Declare a flag&lt;br /&gt;
 $fInterrupt = 0&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 $hButton_1 = GUICtrlCreateButton(&amp;quot;Func One&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
 $hButton_2 = GUICtrlCreateButton(&amp;quot;Func Two&amp;quot;, 10, 50, 80, 30)&lt;br /&gt;
 &lt;br /&gt;
 ; Create a dummy control for the Accelerator to action when pressed&lt;br /&gt;
 $hAccelInterupt = GUICtrlCreateDummy()&lt;br /&gt;
 ; Set an Accelerator key to action the dummy control&lt;br /&gt;
 Dim $AccelKeys[1][2]=[ [&amp;quot;z&amp;quot;, $hAccelInterupt] ]&lt;br /&gt;
 GUISetAccelerators($AccelKeys)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; Intercept Windows command messages with out own handler&lt;br /&gt;
 GUIRegisterMsg($WM_COMMAND, &amp;quot;_WM_COMMAND&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
         Case $hButton_1&lt;br /&gt;
             _Func_1()&lt;br /&gt;
         Case $hButton_2&lt;br /&gt;
             _Func_2()&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
     ; Make sure the flag is cleared&lt;br /&gt;
     $fInterrupt = 0&lt;br /&gt;
     For $i = 1 To 20&lt;br /&gt;
         ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         ; Look for the flag&lt;br /&gt;
         If $fInterrupt &amp;lt;&amp;gt; 0 Then&lt;br /&gt;
             ; The flag was set&lt;br /&gt;
             Switch $fInterrupt&lt;br /&gt;
                 Case 1&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by Func 2&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
                 Case 2&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by HotKey&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
                 Case 3&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by Accelerator&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
             EndSwitch&lt;br /&gt;
             Return&lt;br /&gt;
         EndIf&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_2()&lt;br /&gt;
     For $i = 1 To 3&lt;br /&gt;
         ConsoleWrite(&amp;quot;+Func 2 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 2 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Interrupt()&lt;br /&gt;
     ; The HotKey was pressed so set the flag&lt;br /&gt;
     $fInterrupt = 2&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)&lt;br /&gt;
     ; The Func 2 button was pressed so set the flag&lt;br /&gt;
     If BitAND($wParam, 0x0000FFFF) =  $hButton_2 Then $fInterrupt = 1&lt;br /&gt;
     ; The dummy control was actioned by the Accelerator key so set the flag&lt;br /&gt;
     If BitAND($wParam, 0x0000FFFF) =  $hAccelInterupt Then $fInterrupt = 3&lt;br /&gt;
     Return $GUI_RUNDEFMSG&lt;br /&gt;
 EndFunc   ;==&amp;gt;_WM_COMMAND&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
And now in &#039;&#039;OnEvent&#039;&#039; mode:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;WindowsConstants.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ; Set a HotKey&lt;br /&gt;
 HotKeySet(&amp;quot;x&amp;quot;, &amp;quot;_Interrupt_HotKey&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Declare a flag&lt;br /&gt;
 $fInterrupt = 0&lt;br /&gt;
 &lt;br /&gt;
 Opt(&amp;quot;GUIOnEventMode&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 GUISetOnEvent($GUI_EVENT_CLOSE, &amp;quot;_Exit&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 $hButton_1 = GUICtrlCreateButton(&amp;quot;Func One&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_1, &amp;quot;_Func_1&amp;quot;)&lt;br /&gt;
 $hButton_2 = GUICtrlCreateButton(&amp;quot;Func Two&amp;quot;, 10, 50, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_2, &amp;quot;_Func_2&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Create a dummy control for the Accelerator to action&lt;br /&gt;
 $hAccelInterupt = GUICtrlCreateDummy()&lt;br /&gt;
 GUICtrlSetOnEvent($hAccelInterupt, &amp;quot;_Interrupt_Accel&amp;quot;)&lt;br /&gt;
 ; Set an Accelerator key to action the dummy control&lt;br /&gt;
 Dim $AccelKeys[1][2]=[ [&amp;quot;z&amp;quot;, $hAccelInterupt] ]&lt;br /&gt;
 GUISetAccelerators($AccelKeys)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; Intercept Windows command messages with out own handler&lt;br /&gt;
 GUIRegisterMsg($WM_COMMAND, &amp;quot;_WM_COMMAND&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
 	Sleep(10)&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
     ; Make sure the flag is cleared&lt;br /&gt;
     $fInterrupt = 0&lt;br /&gt;
     For $i = 1 To 20&lt;br /&gt;
         ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         ; Look for the flag&lt;br /&gt;
         If $fInterrupt &amp;lt;&amp;gt; 0 Then&lt;br /&gt;
             ; The flag was set&lt;br /&gt;
             Switch $fInterrupt&lt;br /&gt;
                 Case 1&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by Func 2&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
                 Case 2&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by HotKey&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
                 Case 3&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by Accelerator&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
             EndSwitch&lt;br /&gt;
             Return&lt;br /&gt;
         EndIf&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_2()&lt;br /&gt;
     For $i = 1 To 3&lt;br /&gt;
         ConsoleWrite(&amp;quot;+Func 2 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 2 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Exit()&lt;br /&gt;
     Exit&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Interrupt_HotKey()&lt;br /&gt;
     ; The HotKey was pressed so set the flag&lt;br /&gt;
     $fInterrupt = 2&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Interrupt_Accel()&lt;br /&gt;
     ; This is an empty function for the dummy control linked to the Accelerator key&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)&lt;br /&gt;
     ; The Func 2 button was pressed so set the flag&lt;br /&gt;
     If BitAND($wParam, 0x0000FFFF) =  $hButton_2 Then $fInterrupt = 1&lt;br /&gt;
     ; The dummy control was actioned by the Accelerator key so set the flag&lt;br /&gt;
     If BitAND($wParam, 0x0000FFFF) =  $hAccelInterupt Then $fInterrupt = 3&lt;br /&gt;
     Return $GUI_RUNDEFMSG&lt;br /&gt;
 EndFunc   ;==&amp;gt;_WM_COMMAND&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
But what if you want to have a longish &#039;&#039;Sleep&#039;&#039; or some other function which waits for a fair time inside the running function?  If you add a &#039;&#039;Sleep(5000)&#039;&#039; to &#039;&#039;Func_1&#039;&#039; in the above examples, you will see that you have to wait until the function returns from the &#039;&#039;Sleep&#039;&#039; before the interrupt is actioned, which is not what we want:&lt;br /&gt;
----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
 	; Make sure the flag is cleared&lt;br /&gt;
 	$fInterrupt = 0&lt;br /&gt;
 	For $i = 1 To 20&lt;br /&gt;
 		ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 		; Add a long Sleep ; &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;br /&gt;
 		Sleep(5000)&lt;br /&gt;
 		; Look for the flag&lt;br /&gt;
          If $fInterrupt &amp;lt;&amp;gt; 0 Then&lt;br /&gt;
 			; The flag was set&lt;br /&gt;
 			Switch $fInterrupt&lt;br /&gt;
 				Case 1&lt;br /&gt;
 					ConsoleWrite(&amp;quot;!Func 1 interrrupted by Func 2&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 				Case 2&lt;br /&gt;
 					ConsoleWrite(&amp;quot;!Func 1 interrrupted by HotKey&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 				Case 3&lt;br /&gt;
 					ConsoleWrite(&amp;quot;!Func 1 interrrupted by Accelerator&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 			EndSwitch&lt;br /&gt;
 			Return&lt;br /&gt;
 		EndIf&lt;br /&gt;
 		Sleep(100)&lt;br /&gt;
 	Next&lt;br /&gt;
 	ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Func_1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&lt;br /&gt;
The answer is to put the blocking function inside a wrapper function which does check for the interrupt flag at regular intervals.  Replace the Sleep line with a call to the wrapper function and add the wrapper function to the script:&lt;br /&gt;
&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 ; Use a wrapper function in place of the blocking function&lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
 	; Make sure the flag is cleared&lt;br /&gt;
 	$fInterrupt = 0&lt;br /&gt;
 	For $i = 1 To 20&lt;br /&gt;
 		ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 		; Run a modified Sleep function which checks for the interrupt&lt;br /&gt;
 		If _Interrupt_Sleep(5000) Then ; &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;br /&gt;
 			; The flag was set&lt;br /&gt;
 			Switch $fInterrupt&lt;br /&gt;
 				Case 1&lt;br /&gt;
 					ConsoleWrite(&amp;quot;!Func 1 interrrupted by Func 2&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 				Case 2&lt;br /&gt;
 					ConsoleWrite(&amp;quot;!Func 1 interrrupted by HotKey&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 				Case 3&lt;br /&gt;
 					ConsoleWrite(&amp;quot;!Func 1 interrrupted by Accelerator&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 			EndSwitch&lt;br /&gt;
 			Return&lt;br /&gt;
 		EndIf&lt;br /&gt;
 		Sleep(100)&lt;br /&gt;
 	Next&lt;br /&gt;
 	ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Func_1&lt;br /&gt;
 &lt;br /&gt;
 ; And here is the wrapper function itself&lt;br /&gt;
 Func _Interrupt_Sleep($iDelay)&lt;br /&gt;
 	; Get a timestamp&lt;br /&gt;
 	Local $iBegin = TimerInit()&lt;br /&gt;
 	; And run a tight loop&lt;br /&gt;
 	Do&lt;br /&gt;
 		; Use a minimum Sleep (could also be a WinWaitActive with a short timeout)&lt;br /&gt;
 		Sleep(10)&lt;br /&gt;
 		; Look for the interrrupt&lt;br /&gt;
 		If $fInterrupt Then&lt;br /&gt;
 			; And return True immediately if set&lt;br /&gt;
 			Return True&lt;br /&gt;
 		EndIf&lt;br /&gt;
 	Until TimerDiff($iBegin) &amp;gt; $iDelay&lt;br /&gt;
 	; Return False if timed out and no interrupt was set&lt;br /&gt;
 	Return False&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Interrupt_Sleep&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
So there are the ways available in AutoIt to interrupt a running function.  Remember that you must be in &#039;&#039;OnEvent&#039;&#039; mode and start the function from the main code - or have a function which checks internally whether it ought to allow an interruption.  You may need to use a wrapper function if you want to use a blocking function such as &#039;&#039;Sleep&#039;&#039; or &#039;&#039;WinWaitActive&#039;&#039;.  In all other cases you are are not going to be able to interrupt your function.&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Adding_UDFs_to_AutoIt_and_SciTE&amp;diff=10834</id>
		<title>Adding UDFs to AutoIt and SciTE</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Adding_UDFs_to_AutoIt_and_SciTE&amp;diff=10834"/>
		<updated>2012-11-03T09:51:29Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The ability to download UDFs created by other users is one of the major advantages of AutoIt, but are you one of the many coders who just add these UDFs to the existing &amp;quot;&#039;&#039;Include&#039;&#039;&amp;quot; folder which contains the standard UDFS distributed with AutoIt?  If so then there is much better way to do it - one which will prevent you from losing all of these additional UDFs when you upgrade.  Just use a user-defined folder to store all your UDFs - AutoIt makes this very easy to do.&lt;br /&gt;
&lt;br /&gt;
Begin by creating a new folder to hold the additional UDFs - it is recommended that you do &#039;&#039;&#039;NOT&#039;&#039;&#039; put this folder in the AutoIt install folder (or it will get overwritten when you upgrade).  Then tell AutoIt about this folder.&lt;br /&gt;
&lt;br /&gt;
- If you have &#039;&#039;SciTE4AutoIt3&#039;&#039; you can use &#039;&#039;&#039;SciTEConfig&#039;&#039;&#039; - look for the &#039;&#039;User Include Dir&#039;&#039; input about 2/3 way down the dialog. &lt;br /&gt;
&lt;br /&gt;
- If not (and why not? You can download it from here[http://www.autoitscript.com/site/autoit-script-editor/downloads/]) you need to modify the registry directly as explained on the &amp;quot;&#039;&#039;Include&#039;&#039;&amp;quot; page of the Help file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 There is a special registry value that can be created at &amp;quot;HKEY_CURRENT_USER\Software\AutoIt v3\AutoIt&amp;quot; called &amp;quot;Include&amp;quot;.&lt;br /&gt;
 It should be a REG_SZ (string) value.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;CYA Note&#039;&#039;&#039;: Normal precautions are advised if modifying the registry. &lt;br /&gt;
&lt;br /&gt;
You now have a folder to store modified, downloaded or personal UDFs which are available to use with no need to specify the path and which will not be lost on upgrade.  But to make coding with these UDFs even easier you can also add &#039;&#039;&#039;CallTips&#039;&#039;&#039; and &#039;&#039;&#039;AutoComplete&#039;&#039;&#039; for them.&lt;br /&gt;
&lt;br /&gt;
As you might expect, the full &#039;&#039;SciTE4AutoIt3&#039;&#039; package makes it easy - have you downloaded and installed it yet? If you have then just open &#039;&#039;&#039;SciTEConfig&#039;&#039;&#039; on the &#039;&#039;&#039;Other Tools&#039;&#039;&#039; tab and press &#039;&#039;&#039;Run User Call Tip Manager&#039;&#039;&#039;.  Then you just need to select the UDF file to add and everything is done for you automatically.&lt;br /&gt;
&lt;br /&gt;
But if you want to do it manually:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Calltips&#039;&#039;&#039; first. These are stored in &#039;&#039;C:\Program Files\AutoIt3\SciTE\api\au3.user.calltips.api&#039;&#039;.  If you are doing this for the first time then this file will not exist and you will have to create it.  Then add a line like this to the file for each function you wish to have a calltip:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 _Function($param1, $param2, $param3) Explanation of function (Requires: #Include UDF.au3)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Of course you need to change the &#039;&#039;Function, $param&#039;&#039; and &#039;&#039;UDF&#039;&#039; words to the correct values for the UDF function you want to include.&lt;br /&gt;
&lt;br /&gt;
Now &#039;&#039;&#039;AutoComplete&#039;&#039;&#039;. Again a special file is used &#039;&#039;C:\Program Files\AutoIt3\SciTE\Properties\au3.userudfs.properties&#039;&#039; - again you will have to create it initially - which should read as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 au3.keywords.user.udfs=_function1 _function2 _function3 _function4 \&lt;br /&gt;
        _function5 _function6 _function7&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note that the entries are all in lowercase and all lines other than the first begin with a &#039;&#039;@TAB&#039;&#039; character.&lt;br /&gt;
&lt;br /&gt;
You may have adjust the path if you have installed SciTE elsewhere than the recommended option.&lt;br /&gt;
&lt;br /&gt;
Then save all files, close and restart SciTE. You will have &#039;&#039;&#039;AutoComplete&#039;&#039;&#039; when you start typing the UDF function name in a script and a syntax &#039;&#039;&#039;CallTip&#039;&#039;&#039; as you enter the parameters.   These files are not overwritten when you update SciTE so all your hard work to set this up should be a once-only event.&lt;br /&gt;
&lt;br /&gt;
One final thing.  If you want the &amp;quot;&#039;&#039;Tools - Open Include&#039;&#039;&amp;quot; menu item in SciTE to work on the files within this new folder you need to add the following lines to your &amp;quot;&#039;&#039;SciTEUser.properties&#039;&#039;&amp;quot; file - you open it by using the &amp;lt;&#039;&#039;Options - Open User Options File&#039;&#039;&amp;gt; menu item:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 openpath.$(au3)=$(autoit3dir)\include;Your_Folder_Path&lt;br /&gt;
 openpath.beta.$(au3)=$(autoit3dir)\beta\include;Your_Folder_Path&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Now you are all set - your personal include files are as accessible as the standard set.&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Recursion&amp;diff=10487</id>
		<title>Recursion</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Recursion&amp;diff=10487"/>
		<updated>2012-04-28T15:38:49Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Recursion is a topic which many find difficult to grasp and even more difficult to realise.  However, as I hope this tutorial will show, it is not that daunting and can prove very useful.  However, you do need to take great care when using recursion, including tidying up after yourself, as otherwise you can crash your system very quickly.&lt;br /&gt;
&lt;br /&gt;
[[What is recursion?]]&lt;br /&gt;
&lt;br /&gt;
Let us start by explaining what is meant by recursion.  Basically it means a function calling itself while the original function is still running.  You might wonder why you would ever want to do this - perhaps the simplest example is searching through a folder structure where you need to look in each of the subfolders you find at each level.  Another example would be my &#039;&#039;GUIFrames&#039;&#039; UDF where I use recursion to resize the frames inside a resized GUI, even if the frames are inside other frames - each resized element uses the same function to resize the elements within it.  Without recursion this would be almost impossible to do.&lt;br /&gt;
&lt;br /&gt;
[[Why is recursion difficult to use?]]&lt;br /&gt;
&lt;br /&gt;
So now we know what recursion is, why is it tricky to use?  The following is a very simplistic explanation, but it will suffice to illustrate the problem.  Like any other application, AutoIt maintains an area of memory known as the &#039;&#039;stack&#039;&#039; where it stores temporary data.  When you call a function, AutoIt puts a fair amout of data onto the &#039;&#039;stack&#039;&#039; so that it can reload it when the function returns and so knows where it was, what it was doing and what the various variable values were.  If you call other functions from within the running function, the amount of data in the &#039;&#039;stack&#039;&#039; increases each time and if you do it enough times you can get a &amp;quot;&#039;&#039;stack overflow&#039;&#039;&amp;quot; error which usually spells disaster!  Of course, most scripts do not nest functions to any great depth and the &#039;&#039;stack&#039;&#039; is comfortably large enough to cope as the data is removed once the function returns.  But recursion, where a function keeps calling itself, can lead to a very rapid increase in the amount of &#039;&#039;stack&#039;&#039; space required and so a rapid crash.  AutoIt actually prevents the crash by limiting the recursion level - it will not allow you to store too many datasets (i.e. call too many functions without ever getting back to the main idle loop) on the &#039;&#039;stack&#039;&#039;.  It is extremely unlikely that you would ever get anywhere close to this limit unless you get into a recursive loop with a function calling itself.&lt;br /&gt;
&lt;br /&gt;
[[Some simple examples - bad and good!]]&lt;br /&gt;
&lt;br /&gt;
So what does a recursive loop look like?  Here is a very simple example which on first glance looks as if it will just print an ever-increasing value in the console.  But try running it - it will not work as you might think, but it will not harm your machine:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 _AddOne(0)&lt;br /&gt;
 &lt;br /&gt;
 Func _AddOne($i)&lt;br /&gt;
 &lt;br /&gt;
     ConsoleWrite(&amp;quot;In: &amp;quot; &amp;amp; $i &amp;amp; @CRLF)&lt;br /&gt;
 &lt;br /&gt;
     $i += 1&lt;br /&gt;
 &lt;br /&gt;
     _AddOne($i)&lt;br /&gt;
 &lt;br /&gt;
     ConsoleWrite(&amp;quot;Out: &amp;quot; &amp;amp; $i &amp;amp; @CRLF)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
I get to 3898 and then see:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;M:\Program\Au3 Scripts\Recursion Demo.au3 (13) : ==&amp;gt; Recursion level has been exceeded - AutoIt will quit to prevent stack overflow.:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As you see, you get the &amp;quot;&#039;&#039;In&#039;&#039;&amp;quot; values printed, but as you immediately call the function again you never get to see the &amp;quot;&#039;&#039;Out&#039;&#039;&amp;quot; values as you never actually reach that point in the function - you are in an infinite recursive loop and only AutoIt&#039;s built-in limit prevents a crash as the &#039;&#039;stack&#039;&#039; approaches overflow.&lt;br /&gt;
&lt;br /&gt;
But adding a single limit line to prevent the infinite loop will show how recursion can work without this problem:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 _AddOne(0)&lt;br /&gt;
 &lt;br /&gt;
 Func _AddOne($i)&lt;br /&gt;
 &lt;br /&gt;
     ConsoleWrite(&amp;quot;In: &amp;quot; &amp;amp; $i &amp;amp; @CRLF)&lt;br /&gt;
 &lt;br /&gt;
     $i += 1&lt;br /&gt;
 &lt;br /&gt;
     If $i = 100 Then Return ; This is where we break the infinite recursive loop &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;br /&gt;
 &lt;br /&gt;
     _AddOne($i)&lt;br /&gt;
 &lt;br /&gt;
     ConsoleWrite(&amp;quot;Out: &amp;quot; &amp;amp; $i &amp;amp; @CRLF)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
Here you can see that the &amp;quot;&#039;&#039;In&#039;&#039;&amp;quot; values are printed as before until the limit is reached and the final function returns.  This triggers all the other functions that had been called to continue to run and you get the &amp;quot;&#039;&#039;Out&#039;&#039;&amp;quot; values printed.  Note that they are in the reverse order as AutoIt pulls the data back from the &#039;&#039;stack&#039;&#039; and resets each function to the state it was in before the recursive call.&lt;br /&gt;
&lt;br /&gt;
[[A practical use of recursion]]&lt;br /&gt;
&lt;br /&gt;
I hope the above has made it clear what recursion is and why you must make sure that you do not enter an infinite recursive loop.  Let us now look at a practical application of recursion - searching a folder tree.&lt;br /&gt;
&lt;br /&gt;
The problem is simple - we need to search an initial folder - and any subfolders that we find within that folder - and any subfolders within those subfolders - and any subfolder within those subfolders......  You can see why recursion might be useful here!  This is a very simple script to list the files in the &amp;quot;&#039;&#039;Extras&#039;&#039;&amp;quot; folder of your AutoIt install:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 ListFiles_Recursive(@ProgramFilesDir &amp;amp; &amp;quot;\AutoIt3\Extras&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 Func ListFiles_Recursive($sSourceFolder)&lt;br /&gt;
 &lt;br /&gt;
     Local $sFile&lt;br /&gt;
 &lt;br /&gt;
     ; Force a trailing \&lt;br /&gt;
     If StringRight($sSourceFolder, 1) &amp;lt;&amp;gt; &amp;quot;\&amp;quot; Then $sSourceFolder &amp;amp;= &amp;quot;\&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     ; Start the search&lt;br /&gt;
     Local $hSearch = FileFindFirstFile($sSourceFolder &amp;amp; &amp;quot;*.*&amp;quot;)&lt;br /&gt;
     ; If no files found then return&lt;br /&gt;
     If $hSearch = -1 Then Return ; This is where we break the recursive loop &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;br /&gt;
 &lt;br /&gt;
         ; Now run through the contents of the folder&lt;br /&gt;
         While 1&lt;br /&gt;
             ; Get next match&lt;br /&gt;
             $sFile = FileFindNextFile($hSearch)&lt;br /&gt;
             ; If no more files then close search handle and return&lt;br /&gt;
             If @error Then ExitLoop  ; This is where we break the recursive loop &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;br /&gt;
 &lt;br /&gt;
             ; Check if a folder&lt;br /&gt;
             If @extended Then&lt;br /&gt;
                 ; If so then call the function recursively&lt;br /&gt;
                 ListFiles_Recursive($sSourceFolder &amp;amp; $sFile)&lt;br /&gt;
             Else&lt;br /&gt;
                 ; If a file than write path and name&lt;br /&gt;
                 ConsoleWrite(&amp;quot;Found: &amp;quot; &amp;amp; $sSourceFolder &amp;amp; $sFile &amp;amp; @CRLF)&lt;br /&gt;
             EndIf&lt;br /&gt;
         WEnd&lt;br /&gt;
 &lt;br /&gt;
         ; Close search handle&lt;br /&gt;
         FileClose($hSearch)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc   ;==&amp;gt;ListFiles_Recursive&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
The 2 &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; lines are the limiters to prevent infinite recursion.  The first returns when the &#039;&#039;FileFindFirstFile&#039;&#039; does not find any files in a folder, the second when &#039;&#039;FileFindNextFile&#039;&#039; finds no more files in a folder.  Take careful note of the difference in the action the 2 limiters take - the first returns instantly, the second exits the loop to make sure that the &#039;&#039;$hSearch&#039;&#039; handle is closed before returning.  This is a good example of the &amp;quot;&#039;&#039;tidying up&#039;&#039;&amp;quot; I mentioned right at the beginning - there are only a limited number of handles available and leaving one open each time you call a recursive function is a good recipe for a catastophe later on.&lt;br /&gt;
&lt;br /&gt;
I hope this short introduction to recursion has clarified what it is and why you need to take such care when using it.  However, I would advise you &#039;&#039;&#039;not&#039;&#039;&#039; to use recursion unless there is absolutely no alternative.  Unless you take extreme care, it is simply too easy to mess up the limiters and end up in an infinite recursive loop.&lt;br /&gt;
&lt;br /&gt;
[[A way of avoiding of recursion]]&lt;br /&gt;
&lt;br /&gt;
So what can you do when recursion seems the obvious and best solution?  One possibility is to look at iteration, where you call a function several times but return from it each time and then restart it with another set of parameters.  Here is a very similar file listing script to the example above using an iterative technique.  Each time a subfolder is found its path is added to an array and the internal loop continues until all them have been searched:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 ListFiles_Iterative(@ProgramFilesDir &amp;amp; &amp;quot;\AutoIt3\Extras&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 Func ListFiles_Iterative($sSourceFolder)&lt;br /&gt;
 &lt;br /&gt;
     Local $sFile&lt;br /&gt;
 &lt;br /&gt;
     ; Force a trailing \&lt;br /&gt;
     If StringRight($sSourceFolder, 1) &amp;lt;&amp;gt; &amp;quot;\&amp;quot; Then $sSourceFolder &amp;amp;= &amp;quot;\&amp;quot;&lt;br /&gt;
     ; Create an array to hold the folders to be searched&lt;br /&gt;
     Local $aFolderList[10] = [1, $sSourceFolder]&lt;br /&gt;
 &lt;br /&gt;
     ; Search within listed folders until all have been searched&lt;br /&gt;
     While $aFolderList[0] &amp;gt; 0&lt;br /&gt;
 	&lt;br /&gt;
         ; Get path of folder to search&lt;br /&gt;
         Local $sSearchPath = $aFolderList[$aFolderList[0]]&lt;br /&gt;
         ; Remove folder from list&lt;br /&gt;
         $aFolderList[0] -= 1&lt;br /&gt;
 &lt;br /&gt;
         ; Start the search&lt;br /&gt;
         Local $hSearch = FileFindFirstFile($sSearchPath &amp;amp; &amp;quot;*.*&amp;quot;)&lt;br /&gt;
         ; If failure then return&lt;br /&gt;
         If $hSearch = -1 Then Return&lt;br /&gt;
 	&lt;br /&gt;
         ; Now run through the contents of the folder&lt;br /&gt;
         While 1&lt;br /&gt;
             ; Get next match&lt;br /&gt;
             $sFile = FileFindNextFile($hSearch)&lt;br /&gt;
             ; If no more files then close search handle and return&lt;br /&gt;
             If @error Then ExitLoop&lt;br /&gt;
             ; If a folder then add to array to be searched&lt;br /&gt;
             If @extended Then&lt;br /&gt;
 	&lt;br /&gt;
                 ; #######################################&lt;br /&gt;
 	&lt;br /&gt;
                 ; Increase folder count&lt;br /&gt;
                 $aFolderList[0] += 1&lt;br /&gt;
                 ; Double array size if too small (fewer ReDim needed)&lt;br /&gt;
                 If UBound($aFolderList) &amp;lt;= $aFolderList[0] Then ReDim $aFolderList[UBound($aFolderList) * 2]&lt;br /&gt;
                 ; Add folder&lt;br /&gt;
                 $aFolderList[$aFolderList[0]] = $sSearchPath &amp;amp; $sFile &amp;amp; &amp;quot;\&amp;quot;&lt;br /&gt;
 		&lt;br /&gt;
                 ; #######################################&lt;br /&gt;
 	&lt;br /&gt;
             Else&lt;br /&gt;
                 ; If a file than write path and name&lt;br /&gt;
                 ConsoleWrite(&amp;quot;Found: &amp;quot; &amp;amp; $sSearchPath &amp;amp; $sFile &amp;amp; @CRLF)&lt;br /&gt;
             EndIf&lt;br /&gt;
         WEnd&lt;br /&gt;
 &lt;br /&gt;
         ; Close search handle&lt;br /&gt;
         FileClose($hSearch)&lt;br /&gt;
 &lt;br /&gt;
     WEnd&lt;br /&gt;
 &lt;br /&gt;
 EndFunc   ;==&amp;gt;ListFiles_Iterative&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
As you can see, you get the same files listed - and no recursion used at all!&lt;br /&gt;
&lt;br /&gt;
[[A little added extra]]&lt;br /&gt;
&lt;br /&gt;
If you have been good enough to read this far, you might like to look carefully at the code between the ######## lines in the example above where the subfolders found are added to the &#039;&#039;$aFolderList&#039;&#039; array.  The code uses a clever trick to speed up the script.  &#039;&#039;ReDim&#039;&#039; is among the slowest of the AutoIt functions, so you want to limit its use as much as possible.  If we were to increase the array size by just the one element each time we added a folder, we would slow down the function enormously - it makes little difference here but imagine if you were scanning an entire drive.  Instead of adding a single additional element we double the array in size if it is already full to make sure we get plenty of extra space.  You will need to have a count variable available to do this - so why not in the [0] element as is the case for many AutoIt arrays?  Just remember that if you want to use the array subsequently (unlike here where it is discarded) you will need one final &#039;&#039;ReDim&#039;&#039; to get rid of any unused elements left over after the last increase in size.&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Tabs&amp;diff=10486</id>
		<title>Tabs</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Tabs&amp;diff=10486"/>
		<updated>2012-04-28T15:37:55Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Tabs and how to deal with them]]&lt;br /&gt;
&lt;br /&gt;
Tabs are a valuable tool when you need to fit a lot of controls into a small GUI.  But inexperienced users often have problems with them - particularly in making sure that controls only appear on the correct tab.  This tutorial should help.&lt;br /&gt;
&lt;br /&gt;
Before going further, it is important to understand the differences between controls created using the built-in AutoIt commands (&#039;&#039;GUICtrlCreate*&#039;&#039;) and those created with the UDFs.  The built-in commands produce controls which are managed internally by AutoIt - they return &#039;&#039;&#039;ControlID&#039;&#039;&#039;s.  The UDF commands create controls that are not in Autoit&#039;s internal management structure and need to be managed by the code - they normally return &#039;&#039;&#039;handles&#039;&#039;&#039; (the special unique identifier for all Windows components).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tabs&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Any tabs created by the built-in AutoIt commands &#039;&#039;GUICtrlCreateTab/TabItem&#039;&#039; will automatically take care of displaying any built-in controls created at the same time within the tab creation structure.  Here is an example:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Built-In Tab Example&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 $hTab = GUICtrlCreateTab(10, 10, 480, 480)&lt;br /&gt;
 ; Create tabitems&lt;br /&gt;
 For $i = 0 To 2&lt;br /&gt;
     GUICtrlCreateTabItem(&amp;quot;Tab &amp;quot; &amp;amp; $i)&lt;br /&gt;
     GUICtrlCreateButton(&amp;quot;Button &amp;quot; &amp;amp; $i, 20 + ($i * 100), 40 + ($i * 50), 80, 30)&lt;br /&gt;
 Next&lt;br /&gt;
 ; Close Tab definiton&lt;br /&gt;
 GUICtrlCreateTabItem(&amp;quot;&amp;quot;) &lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
As you can see, the controls for each tab are created just after the TabItem on which they are to appear and before the next TabItem.  Do not forget to close the Tab definition - many tab problems are caused by omitting this vital line.&lt;br /&gt;
&lt;br /&gt;
What happens if we add some UDF created controls to these tabs?&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #Include &amp;lt;GuiButton.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Built-In Tab Example&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 $hTab = GUICtrlCreateTab(10, 10, 480, 480)&lt;br /&gt;
 ; Create tabitems&lt;br /&gt;
 For $i = 0 To 2&lt;br /&gt;
     GUICtrlCreateTabItem(&amp;quot;Tab &amp;quot; &amp;amp; $i)&lt;br /&gt;
     GUICtrlCreateButton(&amp;quot;Built-In &amp;quot; &amp;amp; $i, 20 + ($i * 100), 40 + ($i * 50), 80, 30)&lt;br /&gt;
     _GUICtrlButton_Create($hGUI, &amp;quot;UDF &amp;quot; &amp;amp; $i, 20 + ($i * 100), 80 + ($i * 50),80, 30)&lt;br /&gt;
 Next&lt;br /&gt;
 ; Close Tab definiton&lt;br /&gt;
 GUICtrlCreateTabItem(&amp;quot;&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
As you can see, the UDF created controls appear on every tab.  Remember this is because they are not part of the internal AutoIt control management structure, so AutoIt does not know how to handle them.  It is up to you to manage them by seeing which tab is active and hiding/showing these controls as required:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #Include &amp;lt;GuiButton.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Global $hButtons[3]&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Built-In Tab Example&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 $hTab = GUICtrlCreateTab(10, 10, 480, 480)&lt;br /&gt;
 ; Create tabitems&lt;br /&gt;
 For $i = 0 To 2&lt;br /&gt;
     GUICtrlCreateTabItem(&amp;quot;Tab &amp;quot; &amp;amp; $i)&lt;br /&gt;
     GUICtrlCreateButton(&amp;quot;Built-In &amp;quot; &amp;amp; $i, 20 + ($i * 100), 40 + ($i * 50), 80, 30)&lt;br /&gt;
     ; Add a label to the first tab&lt;br /&gt;
     If $i = 0 Then GUICtrlCreateLabel(&amp;quot;See how &#039;laggy&#039; the UDF buttons are when selecting this tab because of using WinSetState&amp;quot;, 20, 200, 150, 60)&lt;br /&gt;
 Next&lt;br /&gt;
 &lt;br /&gt;
 GUICtrlCreateTabItem(&amp;quot;&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Create UDF controls&lt;br /&gt;
 For $i = 0 To 2&lt;br /&gt;
     $hButtons[$i] = _GUICtrlButton_Create($hGUI, &amp;quot;UDF &amp;quot; &amp;amp; $i, 20 + ($i * 100), 80 + ($i * 50),80, 30)&lt;br /&gt;
 Next&lt;br /&gt;
 &lt;br /&gt;
 ; Hide the controls so only the one on the first tab is visible&lt;br /&gt;
 WinSetState($hButtons[1], &amp;quot;&amp;quot;, @SW_HIDE)&lt;br /&gt;
 WinSetState($hButtons[2], &amp;quot;&amp;quot;, @SW_HIDE)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; This is the current active tab&lt;br /&gt;
 $iLastTab = 0&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
         Case $hTab&lt;br /&gt;
             ; Check which Tab is active&lt;br /&gt;
             $iCurrTab = GUICtrlRead($hTab)&lt;br /&gt;
             ; If the Tab has changed&lt;br /&gt;
             If $iCurrTab &amp;lt;&amp;gt; $iLastTab Then&lt;br /&gt;
                 ; Show/Hide controls as required&lt;br /&gt;
                 Switch $iCurrTab&lt;br /&gt;
                     Case 0&lt;br /&gt;
                         ; Note lag when WinSetState is used&lt;br /&gt;
                         WinSetState($hButtons[1], &amp;quot;&amp;quot;, @SW_HIDE)&lt;br /&gt;
                         WinSetState($hButtons[2], &amp;quot;&amp;quot;, @SW_HIDE)&lt;br /&gt;
                         WinSetState($hButtons[0], &amp;quot;&amp;quot;, @SW_SHOW)&lt;br /&gt;
                     Case 1&lt;br /&gt;
                         ; No lag when using ControlHide/Show&lt;br /&gt;
                         ControlHide($hGUI, &amp;quot;&amp;quot;, $hButtons[0])&lt;br /&gt;
                         ControlHide($hGUI, &amp;quot;&amp;quot;, $hButtons[2])&lt;br /&gt;
                         ControlShow($hGUI, &amp;quot;&amp;quot;, $hButtons[1])&lt;br /&gt;
                     Case 2&lt;br /&gt;
                         ; Nor when using this DLL&lt;br /&gt;
                         DllCall(&amp;quot;User32.dll&amp;quot;, &amp;quot;bool&amp;quot;, &amp;quot;ShowWindowAsync&amp;quot;, &amp;quot;hwnd&amp;quot;, $hButtons[0], &amp;quot;int&amp;quot;, @SW_HIDE)&lt;br /&gt;
                         DllCall(&amp;quot;User32.dll&amp;quot;, &amp;quot;bool&amp;quot;, &amp;quot;ShowWindowAsync&amp;quot;, &amp;quot;hwnd&amp;quot;, $hButtons[1], &amp;quot;int&amp;quot;, @SW_HIDE)&lt;br /&gt;
                         DllCall(&amp;quot;User32.dll&amp;quot;, &amp;quot;bool&amp;quot;, &amp;quot;ShowWindowAsync&amp;quot;, &amp;quot;hwnd&amp;quot;, $hButtons[2], &amp;quot;int&amp;quot;, @SW_SHOW)&lt;br /&gt;
 &lt;br /&gt;
                 EndSwitch&lt;br /&gt;
                 ; Store the value for future comparisons&lt;br /&gt;
                 $iLastTab = $iCurrTab&lt;br /&gt;
             EndIf&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
Note the lag in hiding/showing the UDF created controls if you use &#039;&#039;WinSetState&#039;&#039; - I would recommend using &#039;&#039;ControlShow/Hide&#039;&#039; which gives an instantaneous response.  Also how you do not need to create the UDF controls within the tab creation structure - as you have to look after them, there is no requirement to do so.&lt;br /&gt;
&lt;br /&gt;
Now let us look at Tabs created with the &#039;&#039;GUITab&#039;&#039; UDF.  In this case you need to manage all of the controls on the tabs yourself, even if they are created using the built-in commands:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #Include &amp;lt;GuiButton.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;GuiTab.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Global $hBuiltIn_Buttons[3]&lt;br /&gt;
 Global $hUDF_Buttons[3]&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Built-In Tab Example&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 $hTab = _GUICtrlTab_Create($hGUI, 10, 10, 480, 480)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; Add tabs&lt;br /&gt;
 _GUICtrlTab_InsertItem($hTab, 0, &amp;quot;Tab 0&amp;quot;)&lt;br /&gt;
 _GUICtrlTab_InsertItem($hTab, 1, &amp;quot;Tab 1&amp;quot;)&lt;br /&gt;
 _GUICtrlTab_InsertItem($hTab, 2, &amp;quot;Tab 2&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Create the Built-in and UDF buttons&lt;br /&gt;
 For $i = 0 To 2&lt;br /&gt;
     $hBuiltIn_Buttons[$i] = GUICtrlCreateButton(&amp;quot;Button &amp;quot; &amp;amp; $i, 20 + ($i * 100), 40 + ($i * 50), 80, 30)&lt;br /&gt;
     $hUDF_Buttons[$i] = _GUICtrlButton_Create($hGUI, &amp;quot;UDF &amp;quot; &amp;amp; $i, 20 + ($i * 100), 80 + ($i * 50),80, 30)&lt;br /&gt;
 Next&lt;br /&gt;
 &lt;br /&gt;
 ; Hide the controls so only the one on the first tab is visible&lt;br /&gt;
 GUICtrlSetState($hBuiltIn_Buttons[1], $GUI_HIDE)&lt;br /&gt;
 GUICtrlSetState($hBuiltIn_Buttons[2], $GUI_HIDE)&lt;br /&gt;
 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[1])&lt;br /&gt;
 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[2])&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; This is the current active tab&lt;br /&gt;
 $iLastTab = 0&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 &lt;br /&gt;
     ; Check which Tab is active&lt;br /&gt;
     $iCurrTab = _GUICtrlTab_GetCurFocus($hTab)&lt;br /&gt;
     ; If the Tab has changed&lt;br /&gt;
     If $iCurrTab &amp;lt;&amp;gt; $iLastTab Then&lt;br /&gt;
         ; Store the value for future comparisons&lt;br /&gt;
         $iLastTab = $iCurrTab&lt;br /&gt;
         ; Show/Hide controls as required&lt;br /&gt;
         Switch $iCurrTab&lt;br /&gt;
             Case 0&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[1], $GUI_HIDE)&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[2], $GUI_HIDE)&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[0], $GUI_SHOW)&lt;br /&gt;
                 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[1])&lt;br /&gt;
                 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[2])&lt;br /&gt;
                 ControlShow($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[0])&lt;br /&gt;
             Case 1&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[0], $GUI_HIDE)&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[2], $GUI_HIDE)&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[1], $GUI_SHOW)&lt;br /&gt;
                 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[0])&lt;br /&gt;
                 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[2])&lt;br /&gt;
                 ControlShow($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[1])&lt;br /&gt;
            Case 2&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[0], $GUI_HIDE)&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[1], $GUI_HIDE)&lt;br /&gt;
                 GUICtrlSetState($hBuiltIn_Buttons[2], $GUI_SHOW)&lt;br /&gt;
                 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[0])&lt;br /&gt;
                 ControlHide($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[1])&lt;br /&gt;
                 ControlShow($hGUI, &amp;quot;&amp;quot;, $hUDF_Buttons[2])&lt;br /&gt;
         EndSwitch&lt;br /&gt;
     EndIf&lt;br /&gt;
 WEnd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
A lot of work but a very satisfactory result.  Note the need to use different commands to hide/show the built-in and UDF created controls to avoid &amp;quot;lag&amp;quot; on the latter as was shown in the earlier example.&lt;br /&gt;
&lt;br /&gt;
So, a couple of lessons to draw from this:&lt;br /&gt;
&lt;br /&gt;
- 1.  When using tabs, try and use built-in commands if at all possible.  If you do, AutoIt looks after the showing/hiding problem for you as long as you create the controls WITHIN the tab creation structure.  If you need to add controls after having ended the tab structure definiton, then you &#039;&#039;&#039;must&#039;&#039;&#039; use &#039;&#039;GUISwitch&#039;&#039; with the &#039;&#039;tabitemID&#039;&#039; parameter to select the correct tab before you create the control or you will find that it is visible on all tabs.&lt;br /&gt;
&lt;br /&gt;
- 2.  If you must use UDF created controls for any reason, you have to manage hiding/showing all controls yourself.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Multiple tabs in a GUI&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Unfortunately, only one built-in tab control can be created per GUI - you cannot have several tabs on a single GUI.  But there is a way around this - just create child GUIs which can each hold a tab:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;WindowsConstants.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; Create child GUIs to hold tabs&lt;br /&gt;
 $hTab_Win0 = GUICreate(&amp;quot;&amp;quot;, 400, 200, 50, 20, $WS_POPUP, $WS_EX_MDICHILD, $hGUI)&lt;br /&gt;
 $hTab_0 = GUICtrlCreateTab(10, 10, 380, 180)&lt;br /&gt;
     $hTab_00 = GUICtrlCreateTabitem(&amp;quot;00&amp;quot;)&lt;br /&gt;
         GUICtrlCreateButton(&amp;quot;00&amp;quot;, 160, 90, 80, 30)&lt;br /&gt;
     $hTab_01 = GUICtrlCreateTabitem(&amp;quot;01&amp;quot;)&lt;br /&gt;
         GUICtrlCreateButton(&amp;quot;01&amp;quot;, 160, 90, 80, 30)&lt;br /&gt;
 &lt;br /&gt;
 GUICtrlCreateTabitem (&amp;quot;&amp;quot;)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 $hTab_Win1 = GUICreate(&amp;quot;&amp;quot;, 400, 200, 50, 250, $WS_POPUP, $WS_EX_MDICHILD, $hGUI)&lt;br /&gt;
 $hTab_1 = GUICtrlCreateTab(10, 10, 380, 180)&lt;br /&gt;
     $hTab_10 = GUICtrlCreateTabitem(&amp;quot;10&amp;quot;)&lt;br /&gt;
         GUICtrlCreateButton(&amp;quot;10&amp;quot;, 160, 90, 80, 30)&lt;br /&gt;
     $hTab_11 = GUICtrlCreateTabitem(&amp;quot;11&amp;quot;)&lt;br /&gt;
         GUICtrlCreateButton(&amp;quot;11&amp;quot;, 160, 90, 80, 30)&lt;br /&gt;
 GUICtrlCreateTabitem (&amp;quot;&amp;quot;)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
Easy when you know how!&lt;br /&gt;
&lt;br /&gt;
Tabs are useful controls, but can be difficult to master.  After this tutorial you should be well on your way!&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Modal_MsgBox_Styles&amp;diff=10485</id>
		<title>Modal MsgBox Styles</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Modal_MsgBox_Styles&amp;diff=10485"/>
		<updated>2012-04-28T15:36:45Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;MsgBox&#039;&#039; is a blocking function - your script pauses until a button on the &#039;&#039;MsgBox&#039;&#039; is pressed - at which point the function terminates with a return value which you can use in a decision structure of some kind. Your main GUI appears unresponsive until the &#039;&#039;MsgBox&#039;&#039; is cleared.&lt;br /&gt;
&lt;br /&gt;
However, things are not quite that simple, as the &#039;&#039;MsgBox&#039;&#039; can be set as &#039;&#039;&#039;Application, System&#039;&#039;&#039; or &#039;&#039;&#039;Task Modal&#039;&#039;&#039;.  Although the values needed to set these styles are given in the Helpfile, it does not actually explain the difference between them.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Application&#039;&#039;&#039;: This is the default setting. In this case your GUI will react to mouse clicks and will even retake focus from the &#039;&#039;MsgBox&#039;&#039;, but will not act on the clicks until the &#039;&#039;MsgBox&#039;&#039; is cleared. Try closing the main GUI while the &#039;&#039;MsgBox&#039;&#039; is displayed - it will not close unless you clear the &#039;&#039;Msgbox&#039;&#039; first:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 MsgBox(0, &amp;quot;Blocking&amp;quot;, &amp;quot;Press me to continue&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
    Switch GUIGetMsg()&lt;br /&gt;
        Case $GUI_EVENT_CLOSE&lt;br /&gt;
            Exit&lt;br /&gt;
    EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
-----------------------------------&lt;br /&gt;
&#039;&#039;&#039;System Modal&#039;&#039;&#039;: Now the &#039;&#039;MsgBox&#039;&#039; remains in view even if the main GUI regains focus although the main GUI appears inactive the GUI.  However if the main GUI is closed this will again occur as soon as the &#039;&#039;MsgBox&#039;&#039; is cleared.&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 MsgBox(4096, &amp;quot;Blocking&amp;quot;, &amp;quot;Press me to continue&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&#039;&#039;&#039;Task Modal&#039;&#039;&#039;: Now we get to the real deal - you cannot action anything on the main GUI until the &#039;&#039;MsgBox&#039;&#039; is cleared. So you cannot close the main GUI - or do anything else with it at all!&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 MsgBox(8192, &amp;quot;Blocking&amp;quot;, &amp;quot;Press me to continue&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;  &lt;br /&gt;
-----------------------------------&lt;br /&gt;
Now all you have to do is choose which type best suits your needs!&lt;br /&gt;
&lt;br /&gt;
[[An added extra]]&lt;br /&gt;
&lt;br /&gt;
Another way to prevent the GUI from being actioned while the &#039;&#039;MsgBox&#039;&#039; is present is to set the &amp;quot;&#039;&#039;parent&#039;&#039;&amp;quot; parameter like this:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 MsgBox(0, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, 0, $hGUI)&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Setting_Styles&amp;diff=10483</id>
		<title>Setting Styles</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Setting_Styles&amp;diff=10483"/>
		<updated>2012-04-28T15:34:13Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Setting styles and extended styles in an integral part of coding in AutoIt - but it is very easy to get something other than the result you wanted if you do not take care when specifying them!&lt;br /&gt;
&lt;br /&gt;
Note:  Although the text and examples in this tutorial deal with styles, everything here is also applicable to extended styles.&lt;br /&gt;
&lt;br /&gt;
[[Multiple styles]]&lt;br /&gt;
&lt;br /&gt;
Most styles are set at the bit level - they require specific bits within the total style value to be set in order for the specific style to be activated.  This is why you should always use &#039;&#039;BitOR&#039;&#039; rather than simple addition when setting multiple styles to make sure you do not inadvertantly set/unset bits you do not mean to!  Let us look a why this might happen - but if you do not understand binary maths, you might want to go and read about that first!&lt;br /&gt;
&lt;br /&gt;
Let us imagine we want to set 2 styles which have the values 17 and 33 (these values have been chosen just for illustration and are not valid styles).  Expressing the 2 styles in binary gives us:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Style_1 = 17 = 00010001&lt;br /&gt;
 Style_2 = 33 = 00100001&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Now let us see what happens when we try and combine the 2 styles:&lt;br /&gt;
&lt;br /&gt;
Using &#039;&#039;BitOR&#039;&#039; (which sets bits if either or both bits are set) we get:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 BitOR(Style_1, Style_2) = 00110001&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
However, if we use &#039;&#039;simple addition&#039;&#039;, we get:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 17 + 33 = 50 = 00110010&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Windows uses a form of &#039;&#039;BitAND&#039;&#039; to check for styles which means that it looks for specific bits within the larger number.  So if Windows is checking for Style 1, it looks for bits 4 and 8.  In the &#039;&#039;BitOr&#039;&#039; result, these bits are set - and Windows will apply the style.  The same is true for Style 2 - this time bits 3 and 8 are set in both the style and the combined result.&lt;br /&gt;
&lt;br /&gt;
However, if we try the same tests against the result obtained by simple addition, we see that in neither case does Windows find the correct bits set.  So Windows will apply neither style to our control - and will probably apply some other completely different styles instead.&lt;br /&gt;
&lt;br /&gt;
So, always use &#039;&#039;BitOR&#039;&#039; to set multiple styles.  Remember that you can combine several styles within a single &#039;&#039;BitOr&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Adding and removing styles]]&lt;br /&gt;
&lt;br /&gt;
Most AutoIt controls have default styles - look in the &amp;lt;&#039;&#039;Appendix - GUI Control Styles&#039;&#039;&amp;gt; section of the Help file to see what they are.  For example, a List control is created with the &#039;&#039;$LBS_SORT, $WS_BORDER&#039;&#039;, and &#039;&#039;$WS_VSCROLL&#039;&#039; styles set automatically.  As you can see from the &amp;lt;&#039;&#039;List Styles&#039;&#039;&amp;gt; section of the above Help file page, these have been conveniently combined as the &#039;&#039;$GUI_SS_DEFAULT_LIST&#039;&#039; style and similar values are available for all the ususal controls.  However, there is no need to specify any of these default styles in the initial &#039;&#039;GUICtrlCreate*&#039;&#039; statement as they are automatically included as previously mentioned.  Where users often have difficulty is when they want to add further styles to a control.  Whenever you specify a particular style (or multiple styles using &#039;&#039;BitOR&#039;&#039; as explained above) you &#039;&#039;&#039;overwrite&#039;&#039;&#039; the existing style value and set &#039;&#039;&#039;ONLY&#039;&#039;&#039; the value you have just specified.&lt;br /&gt;
&lt;br /&gt;
Here is an example of this overwriting using ListViews.&lt;br /&gt;
&lt;br /&gt;
- The first default ListView is automatically created with the &#039;&#039;$LVS_SHOWSELALWAYS&#039;&#039; and &#039;&#039;$LVS_SINGLESEL&#039;&#039; styles.&lt;br /&gt;
&lt;br /&gt;
- If we want to sort the items, we need to set the &#039;&#039;$LVS_SORTASCENDING/DESCENDING&#039;&#039; style.  So we do this for the second ListView - but as we only specify the &#039;&#039;$LVS_SORTASCENDING&#039;&#039; style we &#039;&#039;&#039;overwrite&#039;&#039;&#039; the default styles.&lt;br /&gt;
&lt;br /&gt;
- The final ListView shows how to add the &#039;&#039;$LVS_SORTASCENDING&#039;&#039; style correctly by using the &#039;&#039;BitOR&#039;&#039; operator on the default setting &#039;&#039;&#039;AND&#039;&#039;&#039; the new style.&lt;br /&gt;
&lt;br /&gt;
If you play with the ListViews, you will see that although the middle ListView is indeed sorted, it now permits multiple selections and does not show the selected items when it does not have focus - because it no longer has the &#039;&#039;$LVS_SINGLESEL&#039;&#039; and &#039;&#039;$LVS_SHOWSELALWAYS &#039;&#039; styles.  The bottom ListView is sorted and has retained the default styles - which is want we wanted.&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;ListviewConstants.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 600)&lt;br /&gt;
 &lt;br /&gt;
 $hLV_Default = GUICtrlCreateListView(&amp;quot;Header&amp;quot;, 10, 10, 480, 180)&lt;br /&gt;
 GUICtrlSetBkColor(-1, 0xC4C4C4)&lt;br /&gt;
 $hLV_Sorted = GUICtrlCreateListView(&amp;quot;Header&amp;quot;, 10, 200, 480, 180, $LVS_SORTASCENDING)&lt;br /&gt;
 GUICtrlSetBkColor(-1, 0xC4C4C4)&lt;br /&gt;
 $hLV_Default_Sorted = GUICtrlCreateListView(&amp;quot;Header&amp;quot;, 10, 400, 480, 180, BitOr($GUI_SS_DEFAULT_LISTVIEW, $LVS_SORTASCENDING))&lt;br /&gt;
 GUICtrlSetBkColor(-1, 0xC4C4C4)&lt;br /&gt;
 &lt;br /&gt;
 For $i = 1 To 8&lt;br /&gt;
     $iItem = Random(0, 9, 1)&lt;br /&gt;
     GUICtrlCreateListViewItem($iItem, $hLV_Default)&lt;br /&gt;
     GUICtrlCreateListViewItem($iItem, $hLV_Sorted)&lt;br /&gt;
     GUICtrlCreateListViewItem($iItem, $hLV_Default_Sorted)&lt;br /&gt;
 Next&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
Things can get a little more complicated if we created the control with a non-standard style set and want to change it.  How do we find out what styles are currently set?  You may have noticed that there is no &#039;&#039;GUIGtrl&#039;&#039;&#039;Get&#039;&#039;&#039;Style&#039;&#039; to match the &#039;&#039;GUICtrl&#039;&#039;&#039;Set&#039;&#039;&#039;Style&#039;&#039; command.&lt;br /&gt;
&lt;br /&gt;
As it is you who are setting the styles in your own script, a good tip is to keep the current value in a variable which you can then easily modify.  But we can also get the current style values by calling the Windows API directly:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;Constants.au3&amp;gt; ; Do not forget these include files!&lt;br /&gt;
 #include &amp;lt;WinAPI.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $iStyle   = _WinAPI_GetWindowLong(GUICtrlGetHandle($iControlID), $GWL_STYLE)&lt;br /&gt;
 $iExStyle = _WinAPI_GetWindowLong(GUICtrlGetHandle($iControlID), $GWL_EXSTYLE)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
Once you have the current value then you can easily add or subtract other styles from it.&lt;br /&gt;
&lt;br /&gt;
Adding a new style is simple - we just use &#039;&#039;BitOR&#039;&#039; as we have already seen:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 GUICtrlSetStyle($iControlID, BitOR($iOldStyleValue, $iNewStyle))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
Subtracting a style can be done in 2 ways - although one is much easier to use:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 GUICtrlSetStyle($iControlID, BitXOR($iOldStyleValue, $iStyleToRemove))&lt;br /&gt;
 &lt;br /&gt;
 GUICtrlSetStyle($iControlID, BitAnd($iOldStyleValue, BitNOT($iStyleToRemove)))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
You can see that we are using &#039;&#039;Bit*&#039;&#039; operators again.  Explaining exactly how they affect the values we give as parameters is beyond the scope of this tutorial, but they all operate in a similar manner to the &#039;&#039;BitOR/BitAND&#039;&#039; case we looked at when combining styles earlier.&lt;br /&gt;
&lt;br /&gt;
Finally, here is a script which shows these various operators and API calls in action.  You can see that the Edit control style value changes between 0x50331&#039;&#039;&#039;0&#039;&#039;&#039;C4 and 0x50331&#039;&#039;&#039;8&#039;&#039;&#039;C4 depending on whether the &#039;&#039;$ES_READONLY&#039;&#039; syle is included - and you can check that the style is applied/removed by attempting to change the Edit content.&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;EditConstants.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;Constants.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;WinAPI.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $iCount = 1&lt;br /&gt;
 $sBut_Add = &amp;quot;Press to add ReadOnly style&amp;quot;&lt;br /&gt;
 $sBut_Sub = &amp;quot;Press to remove ReadOnly style&amp;quot;&lt;br /&gt;
 $sEdit_Text = &amp;quot;You can edit me if you wish&amp;quot;&lt;br /&gt;
 $sRead_Text = &amp;quot;But you can only read me&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 160)&lt;br /&gt;
 &lt;br /&gt;
 $hEdit = GUICtrlCreateEdit($sEdit_Text, 10, 10, 480, 100)&lt;br /&gt;
 $hEdit_Handle = GUICtrlGetHandle(-1)&lt;br /&gt;
 &lt;br /&gt;
 $hButton = GUICtrlCreateButton($sBut_Add, 150, 120, 200, 30)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; Read default values&lt;br /&gt;
 $iStyle   = _WinAPI_GetWindowLong($hEdit_Handle, $GWL_STYLE)&lt;br /&gt;
 MsgBox(0, &amp;quot;Initial Style&amp;quot;, &amp;quot;Style = &amp;quot; &amp;amp; &amp;quot;Ox&amp;quot; &amp;amp; Hex($iStyle, 8))&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
         Case $hButton&lt;br /&gt;
             Switch $iCount&lt;br /&gt;
                 Case 1&lt;br /&gt;
                     ; Use BitOR to ADD style&lt;br /&gt;
                     GUICtrlSetStyle($hEdit, BitOr($iStyle, $ES_READONLY))&lt;br /&gt;
                     $iStyle   = _WinAPI_GetWindowLong($hEdit_Handle, $GWL_STYLE)&lt;br /&gt;
                     $iCount += 1&lt;br /&gt;
                     MsgBox(0, &amp;quot;ReadOnly Added&amp;quot;, &amp;quot;Style = &amp;quot; &amp;amp; &amp;quot;Ox&amp;quot; &amp;amp; Hex($iStyle, 8))&lt;br /&gt;
                     GUICtrlSetData($hButton, $sBut_Sub)&lt;br /&gt;
                     GUICtrlSetData($hEdit, $sRead_Text)&lt;br /&gt;
                 Case 2&lt;br /&gt;
                     ; Read the current style&lt;br /&gt;
                     $iStyle   = _WinAPI_GetWindowLong($hEdit_Handle, $GWL_STYLE)&lt;br /&gt;
                     ; Use BitXOR to SUBTRACT style&lt;br /&gt;
                     GUICtrlSetStyle($hEdit, BitXOR($iStyle, $ES_READONLY))&lt;br /&gt;
                     ; Read the new style&lt;br /&gt;
                     $iStyle   = _WinAPI_GetWindowLong($hEdit_Handle, $GWL_STYLE)&lt;br /&gt;
                     $iCount += 1&lt;br /&gt;
                     MsgBox(0, &amp;quot;ReadOnly Removed&amp;quot;, &amp;quot;Style = &amp;quot; &amp;amp; &amp;quot;Ox&amp;quot; &amp;amp; Hex($iStyle, 8))&lt;br /&gt;
                     GUICtrlSetData($hButton, $sBut_Add)&lt;br /&gt;
                     GUICtrlSetData($hEdit, $sEdit_Text)&lt;br /&gt;
                 Case 3&lt;br /&gt;
                     ; Read the current style&lt;br /&gt;
                     $iStyle   = _WinAPI_GetWindowLong($hEdit_Handle, $GWL_STYLE)&lt;br /&gt;
                     ; Use BitOR to ADD style&lt;br /&gt;
                     GUICtrlSetStyle($hEdit, BitOr($iStyle, $ES_READONLY))&lt;br /&gt;
                     ; Read the new style&lt;br /&gt;
                     $iStyle   = _WinAPI_GetWindowLong($hEdit_Handle, $GWL_STYLE)&lt;br /&gt;
                     $iCount += 1&lt;br /&gt;
                     GUICtrlSetData($hButton, &amp;quot;&amp;quot;)&lt;br /&gt;
                     MsgBox(0, &amp;quot;ReadOnly Added&amp;quot;, &amp;quot;Style = &amp;quot; &amp;amp; &amp;quot;Ox&amp;quot; &amp;amp; Hex($iStyle, 8))&lt;br /&gt;
                     GUICtrlSetData($hButton, $sBut_Sub)&lt;br /&gt;
                     GUICtrlSetData($hEdit, $sRead_Text)&lt;br /&gt;
                 Case 4&lt;br /&gt;
                     ; Read the current style&lt;br /&gt;
                     $iStyle   = _WinAPI_GetWindowLong($hEdit_Handle, $GWL_STYLE)&lt;br /&gt;
                     ; Use BitAnd and BitNOT to SUBTRACT style&lt;br /&gt;
                     GUICtrlSetStyle($hEdit, BitAnd($iStyle, BitNOT($ES_READONLY)))&lt;br /&gt;
                     ; Read the new style&lt;br /&gt;
                     $iStyle   = _WinAPI_GetWindowLong($hEdit_Handle, $GWL_STYLE)&lt;br /&gt;
                     $iCount += 1&lt;br /&gt;
                     MsgBox(0, &amp;quot;ReadOnly Removed&amp;quot;, &amp;quot;Style = &amp;quot; &amp;amp; &amp;quot;Ox&amp;quot; &amp;amp; Hex($iStyle, 8))&lt;br /&gt;
                     GUICtrlSetData($hButton, &amp;quot;Exit&amp;quot;)&lt;br /&gt;
                     GUICtrlSetData($hEdit, $sEdit_Text)&lt;br /&gt;
                 Case 5&lt;br /&gt;
                     Exit&lt;br /&gt;
             EndSwitch&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
[[Summary]]&lt;br /&gt;
&lt;br /&gt;
Setting styles is not difficult, but does require you to combine multiple styles correctly using &#039;&#039;BitOR&#039;&#039;.  And if you want to add or subtract styles for an existing control you need to remember to take the existing styles into account or you will not end up with the final result you wanted.&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Managing_Multiple_GUIs&amp;diff=10482</id>
		<title>Managing Multiple GUIs</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Managing_Multiple_GUIs&amp;diff=10482"/>
		<updated>2012-04-28T15:31:51Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Having several GUIs on the screen at the same time is fairly common - but structuring your code to deal with this can seem quite daunting.  However, as I hope this tutorial will demonstrate, it is nowhere near as difficult as it first appears.  &lt;br /&gt;
&lt;br /&gt;
[[MessageLoop Mode]]&lt;br /&gt;
&lt;br /&gt;
Let us start with &#039;&#039;MessageLoop&#039;&#039; mode as this is where most new coders run into difficulties with multiple GUIS.  This example script illustrates the problem - it exits when the &#039;&#039;&#039;[X]&#039;&#039;&#039; is clicked on either GUI:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Global $hButton3 = 9999&lt;br /&gt;
 &lt;br /&gt;
 gui1()&lt;br /&gt;
 &lt;br /&gt;
 Func gui1()&lt;br /&gt;
 &lt;br /&gt;
     $hGUI1 = GUICreate(&amp;quot;Gui 1&amp;quot;, 200, 200, 100, 100)&lt;br /&gt;
     $hButton1 = GUICtrlCreateButton(&amp;quot;Msgbox 1&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
     $hButton2 = GUICtrlCreateButton(&amp;quot;Show Gui 2&amp;quot;, 10, 60, 80, 30)&lt;br /&gt;
     GUISetState()&lt;br /&gt;
 &lt;br /&gt;
     While 1&lt;br /&gt;
         Switch GUIGetMsg()&lt;br /&gt;
             Case $GUI_EVENT_CLOSE&lt;br /&gt;
                 ExitLoop&lt;br /&gt;
             Case $hButton1&lt;br /&gt;
                 MsgBox(&amp;quot;&amp;quot;, &amp;quot;MsgBox 1&amp;quot;, &amp;quot;Test from Gui 1&amp;quot;)&lt;br /&gt;
             Case $hButton2&lt;br /&gt;
                 GUICtrlSetState($hButton2, $GUI_DISABLE)&lt;br /&gt;
                 gui2()&lt;br /&gt;
             Case $hButton3&lt;br /&gt;
                 MsgBox(&amp;quot;&amp;quot;, &amp;quot;MsgBox 2&amp;quot;, &amp;quot;Test from Gui 2&amp;quot;) &lt;br /&gt;
         EndSwitch&lt;br /&gt;
     WEnd&lt;br /&gt;
 &lt;br /&gt;
 EndFunc   ;==&amp;gt;gui1&lt;br /&gt;
 &lt;br /&gt;
 Func gui2()&lt;br /&gt;
 &lt;br /&gt;
     $hGUI2 = GUICreate(&amp;quot;Gui 2&amp;quot;, 200, 200, 350, 350)&lt;br /&gt;
     $hButton3 = GUICtrlCreateButton(&amp;quot;MsgBox 2&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
     GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 EndFunc   ;==&amp;gt;gui2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
The script exits because it has a single &#039;&#039;GUIGetMsg&#039;&#039; loop and the &#039;&#039;$GUI_EVENT_CLOSE&#039;&#039; message is received when either &#039;&#039;&#039;[X]&#039;&#039;&#039; is clicked - we have no way of telling the messages from the 2 GUIs apart.&lt;br /&gt;
&lt;br /&gt;
The simplest solution is to disable the first GUI while the second is displayed:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 gui1()&lt;br /&gt;
 &lt;br /&gt;
 Func gui1()&lt;br /&gt;
 &lt;br /&gt;
     $hGUI1 = GUICreate(&amp;quot;Gui 1&amp;quot;, 200, 200, 100, 100)&lt;br /&gt;
     $hButton1 = GUICtrlCreateButton(&amp;quot;Msgbox 1&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
     $hButton2 = GUICtrlCreateButton(&amp;quot;Show Gui 2&amp;quot;, 10, 60, 80, 30)&lt;br /&gt;
     GUISetState()&lt;br /&gt;
 &lt;br /&gt;
     While 1&lt;br /&gt;
         Switch GUIGetMsg()&lt;br /&gt;
             Case $GUI_EVENT_CLOSE&lt;br /&gt;
                 ExitLoop&lt;br /&gt;
             Case $hButton1&lt;br /&gt;
                 MsgBox(&amp;quot;&amp;quot;, &amp;quot;MsgBox 1&amp;quot;, &amp;quot;Test from Gui 1&amp;quot;)&lt;br /&gt;
             Case $hButton2&lt;br /&gt;
                 ; Disable the first GUI&lt;br /&gt;
                 GUISetState(@SW_DISABLE, $hGUI1)&lt;br /&gt;
                 gui2()&lt;br /&gt;
                 ; Re-enable the first GUI&lt;br /&gt;
                 GUISetState(@SW_ENABLE, $hGUI1)&lt;br /&gt;
         EndSwitch&lt;br /&gt;
     WEnd&lt;br /&gt;
 &lt;br /&gt;
 EndFunc   ;==&amp;gt;gui1&lt;br /&gt;
 &lt;br /&gt;
 Func gui2()&lt;br /&gt;
 &lt;br /&gt;
     $hGUI2 = GUICreate(&amp;quot;Gui 2&amp;quot;, 200, 200, 350, 350)&lt;br /&gt;
     $hButton3 = GUICtrlCreateButton(&amp;quot;MsgBox 2&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
     GUISetState()&lt;br /&gt;
 &lt;br /&gt;
     While 1&lt;br /&gt;
         ; We can only get messages from the second GUI&lt;br /&gt;
         Switch GUIGetMsg()&lt;br /&gt;
             Case $GUI_EVENT_CLOSE&lt;br /&gt;
                 GUIDelete($hGUI2)&lt;br /&gt;
                 ExitLoop&lt;br /&gt;
             Case $hButton3&lt;br /&gt;
                 MsgBox(&amp;quot;&amp;quot;, &amp;quot;MsgBox 2&amp;quot;, &amp;quot;Test from Gui 2&amp;quot;)&lt;br /&gt;
 		EndSwitch&lt;br /&gt;
 	WEnd&lt;br /&gt;
 &lt;br /&gt;
 EndFunc   ;==&amp;gt;gui2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
This may well be all you need, but it does mean that we cannot action any of the controls on the first GUI until we close the second.  And importantly we remain blocked in the &#039;&#039;While...WEnd&#039;&#039; loop within the &#039;&#039;gui2&#039;&#039; function - go and read the &amp;quot;&#039;&#039;Interrupting a running function&#039;&#039;&amp;quot; tutorial to see why this is less than ideal.&lt;br /&gt;
&lt;br /&gt;
So how can we deal with multiple GUIs visible at the same time?  Fortunately AutoIt offers us a simple way to differentiate between GUIs in &#039;&#039;MessageLoop&#039;&#039; mode.  Normally we use code like this in our idle loop to detect the messages sent by our GUI and its controls:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Switch GUIGetMsg()&lt;br /&gt;
     Case $GUI_EVENT_CLOSE&lt;br /&gt;
         ; Code&lt;br /&gt;
     Case $hButton1&lt;br /&gt;
         ; Code&lt;br /&gt;
 EndSwitch&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
But when dealing with multiple GUIs, we need to use the &amp;quot;&#039;&#039;advanced&#039;&#039;&amp;quot; parameter when we call &#039;&#039;GUIGetMsg&#039;&#039;.  As explained in the Help file, the function then returns an array instead of a single value.  This array includes information on what exactly triggered the message, just what we need to distinguish the message that was sent (element[&#039;&#039;&#039;0&#039;&#039;&#039;] of the array) and which GUI sent it (element[&#039;&#039;&#039;1&#039;&#039;&#039;]).  We can then amend our simple Switch statement above to read like this:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 $aMsg = GUIGetMsg(1) ; Use advanced parameter to get an array returned&lt;br /&gt;
 Switch $aMsg[1] ; First check which GUI sent the message&lt;br /&gt;
     Case $hGUI1&lt;br /&gt;
         Switch $aMsg[0] ; Now check for the messages sent from $hGUI1&lt;br /&gt;
             Case $GUI_EVENT_CLOSE &lt;br /&gt;
                 ; Code&lt;br /&gt;
             Case $hControl&lt;br /&gt;
                 ; Code&lt;br /&gt;
         EndSwitch&lt;br /&gt;
     Case $hGUI2&lt;br /&gt;
         Switch $aMsg[0] ; Now check for the messages sent from $hGUI2&lt;br /&gt;
             Case $GUI_EVENT_CLOSE&lt;br /&gt;
                 ; Code&lt;br /&gt;
             Case $hButton3&lt;br /&gt;
                 ; Code&lt;br /&gt;
         EndSwitch&lt;br /&gt;
 EndSwitch&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
Although this looks complicated, if you take a moment to study it and you will quickly realise it is simply 2 &#039;&#039;Switch&#039;&#039; structures within an outer &#039;&#039;Switch&#039;&#039;.  You have already dealt with a single &#039;&#039;Switch&#039;&#039; structure for a single GUI - all you are doing here is determining which &#039;&#039;Switch&#039;&#039; structure you want to use.  And that depends on the GUI which sent the message, which is why we need the outer &#039;&#039;Switch&#039;&#039; structure as a wrapper.&lt;br /&gt;
&lt;br /&gt;
So here an example of how to manage 2 GUIs simultaneously using the &amp;quot;&#039;&#039;advanced&#039;&#039;&amp;quot; parameter with &#039;&#039;GUIGetMsg&#039;&#039;:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Global $hGUI2 = 9999, $hButton3 = 9999 ; Predeclare the variables with dummy values to prevent firing the Case statements&lt;br /&gt;
 &lt;br /&gt;
 gui1()&lt;br /&gt;
 &lt;br /&gt;
 Func gui1()&lt;br /&gt;
 &lt;br /&gt;
     $hGUI1 = GUICreate(&amp;quot;Gui 1&amp;quot;, 200, 200, 100, 100)&lt;br /&gt;
     $hButton1 = GUICtrlCreateButton(&amp;quot;Msgbox 1&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
     $hButton2 = GUICtrlCreateButton(&amp;quot;Show Gui 2&amp;quot;, 10, 60, 80, 30)&lt;br /&gt;
     GUISetState()&lt;br /&gt;
 &lt;br /&gt;
     While 1&lt;br /&gt;
         $aMsg = GUIGetMsg(1) ; Use advanced parameter to get array&lt;br /&gt;
         Switch $aMsg[1] ; check which GUI sent the message&lt;br /&gt;
             Case $hGUI1&lt;br /&gt;
                 Switch $aMsg[0] ; Now check for the messages for $hGUI1&lt;br /&gt;
                     Case $GUI_EVENT_CLOSE ; If we get the CLOSE message from this GUI - we exit &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;br /&gt;
                         ExitLoop&lt;br /&gt;
                     Case $hButton1&lt;br /&gt;
                         MsgBox(&amp;quot;&amp;quot;, &amp;quot;MsgBox 1&amp;quot;, &amp;quot;Test from Gui 1&amp;quot;)&lt;br /&gt;
                     Case $hButton2&lt;br /&gt;
                         GUICtrlSetState($hButton2, $GUI_DISABLE)&lt;br /&gt;
                         gui2()&lt;br /&gt;
                 EndSwitch&lt;br /&gt;
             Case $hGUI2&lt;br /&gt;
                 Switch $aMsg[0] ; Now check for the messages for $hGUI2&lt;br /&gt;
                     Case $GUI_EVENT_CLOSE ; If we get the CLOSE message from this GUI - we just delete the GUI &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;br /&gt;
                         GUIDelete($hGUI2)&lt;br /&gt;
                         GUICtrlSetState($hButton2, $GUI_ENABLE)&lt;br /&gt;
                     Case $hButton3&lt;br /&gt;
                         MsgBox(&amp;quot;&amp;quot;, &amp;quot;MsgBox&amp;quot;, &amp;quot;Test from Gui 2&amp;quot;)&lt;br /&gt;
                 EndSwitch&lt;br /&gt;
         EndSwitch&lt;br /&gt;
     WEnd&lt;br /&gt;
 &lt;br /&gt;
 EndFunc   ;==&amp;gt;gui1&lt;br /&gt;
 &lt;br /&gt;
 Func gui2()&lt;br /&gt;
 &lt;br /&gt;
     $hGUI2 = GUICreate(&amp;quot;Gui 2&amp;quot;, 200, 200, 350, 350)&lt;br /&gt;
     $hButton3 = GUICtrlCreateButton(&amp;quot;MsgBox 2&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
     GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 EndFunc   ;==&amp;gt;gui2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
As you can see, we have a single &#039;&#039;While...WEnd&#039;&#039; loop which distinguishes between the 2 GUIs, both GUIs and their controls remain active and we stay in the main idle loop while we wait (you did read that other tutorial I hope!).&lt;br /&gt;
&lt;br /&gt;
[[OnEvent Mode]]&lt;br /&gt;
&lt;br /&gt;
Coders using &#039;&#039;OnEvent&#039;&#039; mode do not usually find the same problem with multiple GUIs as they can code separate functions for each &#039;&#039;$GUI_EVENT_CLOSE&#039;&#039; as shown here:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Opt(&amp;quot;GUIOnEventMode&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 Global $hGUI2, $hButton2 ; Predeclare these variables&lt;br /&gt;
 &lt;br /&gt;
 gui1()&lt;br /&gt;
 &lt;br /&gt;
 Func gui1()&lt;br /&gt;
 &lt;br /&gt;
     $hGUI1 = GUICreate(&amp;quot;Gui 1&amp;quot;, 200, 200, 100, 100)&lt;br /&gt;
     GUISetOnEvent($GUI_EVENT_CLOSE, &amp;quot;On_Close_Main&amp;quot;) ; Run this function when the main GUI [X] is clicked&lt;br /&gt;
     $hButton1 = GUICtrlCreateButton(&amp;quot;Msgbox 1&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
     GUICtrlSetOnEvent(-1, &amp;quot;On_Button1&amp;quot;)&lt;br /&gt;
     $hButton2 = GUICtrlCreateButton(&amp;quot;Show Gui 2&amp;quot;, 10, 60, 80, 30)&lt;br /&gt;
     GUICtrlSetOnEvent(-1, &amp;quot;On_Button2&amp;quot;)&lt;br /&gt;
     GUISetState()&lt;br /&gt;
 &lt;br /&gt;
     While 1&lt;br /&gt;
         Sleep(10)&lt;br /&gt;
     WEnd&lt;br /&gt;
 &lt;br /&gt;
 EndFunc   ;==&amp;gt;gui1&lt;br /&gt;
 &lt;br /&gt;
 Func gui2()&lt;br /&gt;
 &lt;br /&gt;
     $hGUI2 = GUICreate(&amp;quot;Gui 2&amp;quot;, 200, 200, 350, 350)&lt;br /&gt;
     GUISetOnEvent($GUI_EVENT_CLOSE, &amp;quot;On_Close_Secondary&amp;quot;) ; Run this function when the secondary GUI [X] is clicked&lt;br /&gt;
     $hButton3 = GUICtrlCreateButton(&amp;quot;MsgBox 2&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
     GUICtrlSetOnEvent(-1, &amp;quot;On_Button3&amp;quot;)&lt;br /&gt;
     GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 EndFunc   ;==&amp;gt;gui2&lt;br /&gt;
 &lt;br /&gt;
 Func On_Close_Main()&lt;br /&gt;
 &lt;br /&gt;
     Exit&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func On_Close_Secondary()&lt;br /&gt;
 &lt;br /&gt;
     GUIDelete($hGUI2)&lt;br /&gt;
     GUICtrlSetState($hButton2, $GUI_ENABLE)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func On_Button1()&lt;br /&gt;
 &lt;br /&gt;
     MsgBox(&amp;quot;&amp;quot;, &amp;quot;MsgBox 1&amp;quot;, &amp;quot;Test from Gui 1&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func On_Button2()&lt;br /&gt;
 &lt;br /&gt;
     GUICtrlSetState($hButton2, $GUI_DISABLE)&lt;br /&gt;
     gui2()&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func On_Button3()&lt;br /&gt;
 &lt;br /&gt;
     MsgBox(&amp;quot;&amp;quot;, &amp;quot;MsgBox 2&amp;quot;, &amp;quot;Test from Gui 2&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
But did you realise that you can also use what some people think of as a hybrid mode - using common &#039;&#039;OnEvent&#039;&#039; functions and then determining the specific GUI or control which called the function within the function?  As an added bonus, this approach may, depending on the circumstances, let you send parameters to the functions you call - something that you normally cannot do in &#039;&#039;OnEvent&#039;&#039; mode.&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Opt(&amp;quot;GUIOnEventMode&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 Global $hGUI1, $hGUI2 = 9999, $hButton1, $hButton2, $hButton3 = 9999 ; Predeclare the variables with dummy values to prevent firing the Case statements&lt;br /&gt;
 &lt;br /&gt;
 gui1()&lt;br /&gt;
 &lt;br /&gt;
 Func gui1()&lt;br /&gt;
 &lt;br /&gt;
     $hGUI1 = GUICreate(&amp;quot;Gui 1&amp;quot;, 200, 200, 100, 100)&lt;br /&gt;
     GUISetOnEvent($GUI_EVENT_CLOSE, &amp;quot;On_Close&amp;quot;) ; Call a common GUI close function&lt;br /&gt;
     $hButton1 = GUICtrlCreateButton(&amp;quot;Msgbox 1&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
     GUICtrlSetOnEvent(-1, &amp;quot;On_Button&amp;quot;) ; Call a common button function&lt;br /&gt;
     $hButton2 = GUICtrlCreateButton(&amp;quot;Show Gui 2&amp;quot;, 10, 60, 80, 30)&lt;br /&gt;
     GUICtrlSetOnEvent(-1, &amp;quot;On_Button&amp;quot;) ; Call a common button function&lt;br /&gt;
     GUISetState()&lt;br /&gt;
 &lt;br /&gt;
     While 1&lt;br /&gt;
         Sleep(10)&lt;br /&gt;
     WEnd&lt;br /&gt;
 &lt;br /&gt;
 EndFunc   ;==&amp;gt;gui1&lt;br /&gt;
 &lt;br /&gt;
 Func gui2()&lt;br /&gt;
 &lt;br /&gt;
     $hGUI2 = GUICreate(&amp;quot;Gui 2&amp;quot;, 200, 200, 350, 350)&lt;br /&gt;
     GUISetOnEvent($GUI_EVENT_CLOSE, &amp;quot;On_Close&amp;quot;) ; Call a common GUI close function&lt;br /&gt;
     $hButton3 = GUICtrlCreateButton(&amp;quot;MsgBox 2&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
     GUICtrlSetOnEvent(-1, &amp;quot;On_Button&amp;quot;) ; Call a common button function&lt;br /&gt;
     GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 EndFunc   ;==&amp;gt;gui2&lt;br /&gt;
 &lt;br /&gt;
 Func On_Close()&lt;br /&gt;
 &lt;br /&gt;
     Switch @GUI_WINHANDLE ; See which GUI sent the CLOSE message&lt;br /&gt;
         Case $hGUI1&lt;br /&gt;
             Exit ; If it was this GUI - we exit &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;br /&gt;
         Case $hGUI2&lt;br /&gt;
             GUIDelete($hGUI2) ; If it was this GUI - we just delete the GUI &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;br /&gt;
             GUICtrlSetState($hButton2, $GUI_ENABLE)&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func On_Button()&lt;br /&gt;
 &lt;br /&gt;
     Switch @GUI_CTRLID ; See which button sent the message&lt;br /&gt;
         Case $hButton1&lt;br /&gt;
             MessageBox(1) ; We can call a function with parameters here &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;br /&gt;
         Case $hButton2&lt;br /&gt;
             GUICtrlSetState($hButton2, $GUI_DISABLE)&lt;br /&gt;
             gui2()&lt;br /&gt;
         Case $hButton3&lt;br /&gt;
             MessageBox(2) ; We can call a function with parameters here &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func MessageBox($iIndex)&lt;br /&gt;
 &lt;br /&gt;
     MsgBox(&amp;quot;&amp;quot;, &amp;quot;MsgBox &amp;quot; &amp;amp; $iIndex, &amp;quot;Test from Gui &amp;quot; &amp;amp; $iIndex)&lt;br /&gt;
 &lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
So you see that managing multiple GUIS is not as difficult as you might think.  One of these methods is bound to suit your script, but do not try and mix them - only one method per script please!&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Tutorial_GUIRegisterMsg&amp;diff=10480</id>
		<title>Tutorial GUIRegisterMsg</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Tutorial_GUIRegisterMsg&amp;diff=10480"/>
		<updated>2012-04-28T15:28:25Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Here is a short tutorial on &#039;&#039;GUIRegisterMsg&#039;&#039; - one of the more mysterious functions within AutoIt for newcomers.  Purists might quibble over details here, but it is good enough for hobbyists like me!  &lt;br /&gt;
&lt;br /&gt;
Windows works by sending messages to everything on the system, so that everything knows what is going on. By messages, I mean things like the &#039;&#039;$GUI_EVENT_CLOSE&#039;&#039; we look for when we exit a GUI - but the possible range is much, much wider; change of focus, change of state, mouseclicks, mousemoves, key presses, etc, etc, etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;GUIRegisterMsg&#039;&#039; allows us to intercept certain of these messages as they are sent by the GUIs we have created, so we can see who sent what. So when you see a &#039;&#039;GUIRegisterMsg($WM_COMMAND, &amp;quot;MY_WM_COMMAND&amp;quot;)&#039;&#039; line in a script, this translates as &amp;quot;&#039;&#039;Whenever a WM_COMMAND message is sent by my GUI, please intercept it and pass it through the MY_WM_COMMAND function in this script&#039;&#039;&amp;quot;. The actual message title is denoted by the constant &#039;&#039;$WM_COMMAND&#039;&#039; which is stored in &#039;&#039;WindowsConstant.au3&#039;&#039; include file.  Of course, you can use other message types as well (such as &#039;&#039;$WM_NOTIFY&#039;&#039;) - and call your function whatever you wish!&lt;br /&gt;
&lt;br /&gt;
The function that you use &#039;&#039;GUIRegisterMsg&#039;&#039; to call &#039;&#039;&#039;MUST&#039;&#039;&#039; have these 4 parameters - &#039;&#039;$hWnd, $iMsg, $wParam, $lParam&#039;&#039; - because that is what Windows uses itself to pass the messages around.  In the majority of cases, these parameters relate to the following:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;$hWnd&#039;&#039; - the GUI which sent the message&lt;br /&gt;
*&#039;&#039;$iMsg&#039;&#039; - the code for the message sent&lt;br /&gt;
*&#039;&#039;$wParam, $iParam&#039;&#039; - details of what exactly the message is about. This varies according to the message and details can be found in MSDN but often these parameters will hold the identity of control that has been used and the exact version of the message that has been sent.&lt;br /&gt;
&lt;br /&gt;
Let us look at some examples:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 GUIRegisterMsg($WM_COMMAND, &amp;quot;MY_WM_COMMAND&amp;quot;)&lt;br /&gt;
 ;&lt;br /&gt;
 Func MY_WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)&lt;br /&gt;
 ;&lt;br /&gt;
     Local $iIDFrom = BitAND($wParam, 0xFFFF) ; LoWord - this gives the control which sent the message&lt;br /&gt;
     Local $iCode = BitShift($wParam, 16)     ; HiWord - this gives the message that was sent&lt;br /&gt;
     If $iCode = $EN_CHANGE Then ; If we have the correct message&lt;br /&gt;
         Switch $iIDFrom ; See if it comes from one of the inputs&lt;br /&gt;
             Case $hInput1&lt;br /&gt;
                 ; Do something&lt;br /&gt;
             Case $hInput2&lt;br /&gt;
                 ; Do something else&lt;br /&gt;
         EndSwitch&lt;br /&gt;
     EndIf&lt;br /&gt;
 ;&lt;br /&gt;
 EndFunc ;==&amp;gt;MY_WM_COMMAND&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
Here we are looking to see if the contents of two Input controls have been altered.  We first intercept the &#039;&#039;$WM_COMMAND&#039;&#039; messages from our GUI using &#039;&#039;GUIRegisterMsg&#039;&#039;.  We can ignore the GUI and the main message in this case - &#039;&#039;$WM_COMMAND&#039;&#039; is a huge set and as we are interested in the control we need not worry about the GUI - if we correctly identify the control, it can only come from our GUI!  But in other cases, this is vital information, as you can imagine.&lt;br /&gt;
&lt;br /&gt;
To see if an Input has been altered, we need to look for the &#039;&#039;$EN_CHANGE&#039;&#039; submessage and as you can see we need to investigate the contents of &#039;&#039;$wParam&#039;&#039; to determine this - and then determine the identity of the Input control which is also obtained from&#039;&#039; $wParam&#039;&#039; (MSDN is the bible here). The &#039;&#039;Bit*&#039;&#039; operators allow us to extract these values:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 Local $iIDFrom = BitAND($wParam, 0xFFFF) ; LoWord - this gives the ControlID of the control which sent the message &lt;br /&gt;
 Local $iCode = BitShift($wParam, 16)     ; HiWord - this gives the submessage that was sent&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
We now know which control sent the message and what the sub-message was - so we check if it matches what we are looking for and if it does then we do whatever we need to do:&lt;br /&gt;
&lt;br /&gt;
Another example:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 GUIRegisterMsg($WM_NOTIFY, &amp;quot;MY_WM_NOTIFY&amp;quot;)&lt;br /&gt;
 ;&lt;br /&gt;
 Func MY_WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)&lt;br /&gt;
 ;&lt;br /&gt;
 	Local $tNMHDR = DllStructCreate(&amp;quot;int;int;int&amp;quot;, $lParam)&lt;br /&gt;
 	If @error Then Return&lt;br /&gt;
 	If DllStructGetData($tNMHDR, 1) = $hLV_Handle Then ; Is it our ListView&lt;br /&gt;
 		If DllStructGetData($tNMHDR, 3) = $NM_DBLCLK Then $fDblClk = True ; Was it a double click&lt;br /&gt;
 	EndIf&lt;br /&gt;
 	$tNMHDR = 0 ; This not strictly necessary but does not hurt!&lt;br /&gt;
 ;&lt;br /&gt;
 	Return $GUI_RUNDEFMSG ; This tells AutoIt to process the message itself&lt;br /&gt;
 ;&lt;br /&gt;
 EndFunc   ;==&amp;gt;MY_WM_NOTIFY&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
This time we are trapping the &#039;&#039;$WM_NOTIFY&#039;&#039; message which lets us know about events like mouse clicks.  In particular we are looking for a double click on a ListView within our GUI.  As above we use &#039;&#039;GUIRegisterMsg&#039;&#039; to intercept the message.  Again we can ignore the GUI and main message and just look for the control and submessage.  In this case we need to do a bit more work on the &#039;&#039;$lParam&#039;&#039; parameter which is actually a &#039;&#039;Struct&#039;&#039;.  However, AutoIt again makes it easy to obtain the handle of the control and the actual submessage - if these are the correct ones, we set a flag to &#039;&#039;True&#039;&#039;.  Why, well keep reading and you will find out!&lt;br /&gt;
&lt;br /&gt;
When we have finished dealing with the message we have intercepted, it gets passed along the chain of all the other message handlers so all the other applications in the system can see if they are interested too.   But in some cases you might actually want to stop the message going further - I wrote a UDF to prevent the system adding the dotted lines around the control when it has focus and passing the message on was exactly what I was trying to prevent!  So in the UDF I added a &#039;&#039;Return&#039;&#039; line to the function to stop it dead - just as here.  Returning the &#039;&#039;$GUI_RUNDEFMSG&#039;&#039; constant tells AutoIt to run its own internal message handler. &lt;br /&gt;
&lt;br /&gt;
Now, what about the use of a flag in the second example?  Well, if you read the Help file for &#039;&#039;GUIRegisterMsg&#039;&#039; you will see the following:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&#039;&#039;Warning: blocking of running user functions which execute Windows messages with commands such as &amp;quot;Msgbox()&amp;quot; can lead to unexpected behavior, the return to the system should be as fast as possible !!!&#039;&#039;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Basically, if you spend too long in your message handling function, the rest of the system gets behind and becomes unstable.  So you should get out of it as quickly as you can - and certainly never create anything that waits for user input.&lt;br /&gt;
&lt;br /&gt;
There are 2 ways we can still run something long and complicated but still leave the handler quickly: either set a flag or action a dummy control.  If we set a flag inside the handler, we can then look for it within our idle loop and run our blocking code from here without affecting the handler at all.  If we action a dummy control then we do not even have to look for the flag!  Here is an example of both methods to show you how to apply them.&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #include&amp;lt;WindowsConstants.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ; Whichever method we use, we need to declare the dummy control or the flag as a Global variable&lt;br /&gt;
 Global $hLeftClick, $fRightClick = False&lt;br /&gt;
 &lt;br /&gt;
 GUICreate(&amp;quot;Click me!&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Create a dummy control for the handler to action&lt;br /&gt;
 $hLeftClick = GUICtrlCreateDummy()&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; Register our messages&lt;br /&gt;
 GUIRegisterMsg($WM_LBUTTONUP, &amp;quot;_WM_LBUTTONUP&amp;quot;)&lt;br /&gt;
 GUIRegisterMsg($WM_RBUTTONUP, &amp;quot;_WM_RBUTTONUP&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             ExitLoop&lt;br /&gt;
         Case $hLeftClick&lt;br /&gt;
             ; Our dummy control was actioned so run the required code&lt;br /&gt;
             MsgBox(0, &amp;quot;Click&amp;quot;, &amp;quot;LEFT CLICK!&amp;quot;)&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 &lt;br /&gt;
     ; Look for the flag&lt;br /&gt;
     If $fRightClick = True Then&lt;br /&gt;
         ; Run the code&lt;br /&gt;
         MsgBox(0, &amp;quot;Click&amp;quot;, &amp;quot;RIGHT CLICK!&amp;quot;)&lt;br /&gt;
         ; Do not forget to reset the flag!&lt;br /&gt;
         $fRightClick = False&lt;br /&gt;
     EndIf&lt;br /&gt;
 &lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _WM_LBUTTONUP($hWnd, $iMsg, $wParam, $lParam)&lt;br /&gt;
     ; Action the dummy control&lt;br /&gt;
     GUICtrlSendToDummy($hLeftClick)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _WM_RBUTTONUP($hWnd, $iMsg, $wParam, $lParam)&lt;br /&gt;
     ; Set the flag&lt;br /&gt;
     $fRightClick = True&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
I hope this short tutorial has made &#039;&#039;GUIRegisterMsg&#039;&#039; a little less complicated.  Now I suggest you go and look at the many examples on the forum to see how they work and how each differs slightly depending on exactly the author is trying to do.&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
	<entry>
		<id>https://www.autoitscript.com/w/index.php?title=Interrupting_a_running_function&amp;diff=10479</id>
		<title>Interrupting a running function</title>
		<link rel="alternate" type="text/html" href="https://www.autoitscript.com/w/index.php?title=Interrupting_a_running_function&amp;diff=10479"/>
		<updated>2012-04-28T15:27:07Z</updated>

		<summary type="html">&lt;p&gt;Melba23: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a common question and this tutorial explains how to do it within the limitations of Autoit.&lt;br /&gt;
&lt;br /&gt;
AutoIt queues function calls in both &#039;&#039;OnEvent&#039;&#039; and &#039;&#039;MessageLoop&#039;&#039; modes.  This means that it waits until a function is finished and the code is back in your idle &#039;&#039;While...WEnd&#039;&#039; loop before running the next.&lt;br /&gt;
&lt;br /&gt;
Here are 2 short scripts in both modes to show this in action.  Start &#039;&#039;Function 1&#039;&#039; by pressing its button and then immediately try to run &#039;&#039;Function 2&#039;&#039; by pressing its button a couple of times.  You will see from the console output that &#039;&#039;Function 2&#039;&#039; will only run &#039;&#039;&#039;AFTER&#039;&#039;&#039; &#039;&#039;Function 1&#039;&#039; has terminated - and then it will run as many times as you pressed the button.&lt;br /&gt;
&lt;br /&gt;
We start with &#039;&#039;MessageLoop&#039;&#039; mode:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 $hButton_1 = GUICtrlCreateButton(&amp;quot;Func One&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
 $hButton_2 = GUICtrlCreateButton(&amp;quot;Func Two&amp;quot;, 10, 50, 80, 30)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
         Case $hButton_1&lt;br /&gt;
             _Func_1()&lt;br /&gt;
         Case $hButton_2&lt;br /&gt;
         _Func_2()&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
     For $i = 1 To 20&lt;br /&gt;
         ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_2()&lt;br /&gt;
     For $i = 1 To 3&lt;br /&gt;
         ConsoleWrite(&amp;quot;+Func 2 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 2 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
And now in &#039;&#039;OnEvent&#039;&#039; mode:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 Opt(&amp;quot;GUIOnEventMode&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 GUISetOnEvent($GUI_EVENT_CLOSE, &amp;quot;_Exit&amp;quot;) &lt;br /&gt;
 &lt;br /&gt;
 $hButton_1 = GUICtrlCreateButton(&amp;quot;Func One&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_1, &amp;quot;_Func_1&amp;quot;)&lt;br /&gt;
 $hButton_2 = GUICtrlCreateButton(&amp;quot;Func Two&amp;quot;, 10, 50, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_2, &amp;quot;_Func_2&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Sleep(10)&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
 For $i = 1 To 20&lt;br /&gt;
     ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_2()&lt;br /&gt;
     For $i = 1 To 3&lt;br /&gt;
         ConsoleWrite(&amp;quot;+Func 2 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 2 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Exit()&lt;br /&gt;
     Exit&lt;br /&gt;
 EndFunc&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
So is it impossible to interrupt a running function?  Of course not or this tutorial would serve no purpose - but there are limitations on the type of function which can be interrupted.  &lt;br /&gt;
&lt;br /&gt;
If you are in &#039;&#039;OnEvent&#039;&#039; mode then there is an easy way to interrupt a running function, as long as the function is started within the main code and not by an &#039;&#039;OnEvent&#039;&#039; call.  This script shows how to do it by using a flag and checking if it is set - in this way the function is started by the main script and can be interrupted.&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ; Declare a flag&lt;br /&gt;
 Global $fRunOne = False&lt;br /&gt;
 &lt;br /&gt;
 Opt(&amp;quot;GUIOnEventMode&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 GUISetOnEvent($GUI_EVENT_CLOSE, &amp;quot;_Exit&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 $hButton_1 = GUICtrlCreateButton(&amp;quot;Func One&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_1, &amp;quot;_Func_1&amp;quot;)&lt;br /&gt;
 $hButton_2 = GUICtrlCreateButton(&amp;quot;Func Two&amp;quot;, 10, 50, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_2, &amp;quot;_Func_2&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Sleep(10)&lt;br /&gt;
     ; Check if the flag has been set by the OnEvent function&lt;br /&gt;
     If $fRunOne Then&lt;br /&gt;
         ; Now start the &amp;quot;real&amp;quot; function from within the main code&lt;br /&gt;
         _Func_1_Run()&lt;br /&gt;
     EndIf&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
     ; Set the flag within the OnEvent function&lt;br /&gt;
     $fRunOne = True&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Func_1&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1_Run()&lt;br /&gt;
     For $i = 1 To 20&lt;br /&gt;
         ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
     Global $fRunOne = False&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Func_1_Run&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_2()&lt;br /&gt;
     For $i = 1 To 3&lt;br /&gt;
         ConsoleWrite(&amp;quot;+Func 2 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 2 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Func_2&lt;br /&gt;
 &lt;br /&gt;
 Func _Exit()&lt;br /&gt;
     Exit&lt;br /&gt;
 EndFunc   ;==&amp;gt;_Exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
However, this method does not work in &#039;&#039;MessageLoop&#039;&#039; mode, not when you want to interrupt a function which was started by an &#039;&#039;OnEvent&#039;&#039; call in &#039;&#039;OnEvent&#039;&#039; mode.  In these cases the function you want to interrupt must have regular checks of a flag which we set when we want to interrupt.  If the function does not have a suitable loop where such a check is easy to make, you might not be able to interrupt it.&lt;br /&gt;
&lt;br /&gt;
Let us now look at the 2 ways an AutoIt script can break into a suitable function: a &#039;&#039;&#039;HotKey&#039;&#039;&#039; and a &#039;&#039;&#039;Windows message handler&#039;&#039;&#039;.  The first is easier to code, but cannot be linked to a control on your GUI; the latter is a little more complicated to code, but can be linked to a control.&lt;br /&gt;
&lt;br /&gt;
How do they work?&lt;br /&gt;
&lt;br /&gt;
Let us start with the &#039;&#039;HotKey&#039;&#039;.  From the AutoIt Help file: &#039;&#039;A hotkey-press *typically* interrupts the active AutoIt function/statement and runs its user function until it completes or is interrupted&#039;&#039;.  So a &#039;&#039;HotKey&#039;&#039; press is designed to interrupt your running function - just what we need.  But the running function will resume after the &#039;&#039;HotKey&#039;&#039; function terminates - so, as explained above, we use the &#039;&#039;HotKey&#039;&#039; function to set a flag which is looked for by our running function.  Remember that this flag must be declared as a &#039;&#039;Global&#039;&#039; variable because it needs to be seen by both functions.&lt;br /&gt;
&lt;br /&gt;
Now many coders do not like using &#039;&#039;HotKey&#039;&#039;s because they remain active while a script is running and can interfere with other apps.  One way to get around this is to use &#039;&#039;Accelerator&#039;&#039; keys - these look very much like &#039;&#039;HotKey&#039;&#039;s to the user, but are only active in the script in which they are declared.  Although &#039;&#039;Accelerator&#039;&#039; keys look like &#039;&#039;HotKey&#039;&#039;s, they are tied to GUI controls and you must use the &#039;&#039;message handler&#039;&#039; method explained below if you want to use them to interrupt a running function.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;Windows message handler&#039;&#039; method is a little more complicated and if you are not used to working with them, you might want to read the [[GUIRegisterMsg]] tutorial first.&lt;br /&gt;
&lt;br /&gt;
What we do here is intercept the message that your GUI control sends when it is activated - the same message that AutoIt queues to run the required code once the running function terminates.  We use our own message to get a sneak preview of this queuing and use it to set a similar flag to that described above.  If our running function sees the flag, it terminates and AutoIt then runs the function waiting in the queue - simple really!&lt;br /&gt;
&lt;br /&gt;
Here are scripts using both methods to show how &#039;&#039;HotKey&#039;&#039;s, &#039;&#039;Accelerator&#039;&#039; keys and GUI controls can interrupt a running function.  Just as before, start &#039;&#039;Function_1&#039;&#039; by pressing its button  - but now you can interrupt it at will!&lt;br /&gt;
&lt;br /&gt;
First in &#039;&#039;MessageLoop&#039;&#039; mode:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;WindowsConstants.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ; Set a HotKey&lt;br /&gt;
 HotKeySet(&amp;quot;x&amp;quot;, &amp;quot;_Interrupt&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Declare a flag&lt;br /&gt;
 $fInterrupt = 0&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 &lt;br /&gt;
 $hButton_1 = GUICtrlCreateButton(&amp;quot;Func One&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
 $hButton_2 = GUICtrlCreateButton(&amp;quot;Func Two&amp;quot;, 10, 50, 80, 30)&lt;br /&gt;
 &lt;br /&gt;
 ; Create a dummy control for the Accelerator to action when pressed&lt;br /&gt;
 $hAccelInterupt = GUICtrlCreateDummy()&lt;br /&gt;
 ; Set an Accelerator key to action the dummy control&lt;br /&gt;
 Dim $AccelKeys[1][2]=[ [&amp;quot;z&amp;quot;, $hAccelInterupt] ]&lt;br /&gt;
 GUISetAccelerators($AccelKeys)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; Intercept Windows command messages with out own handler&lt;br /&gt;
 GUIRegisterMsg($WM_COMMAND, &amp;quot;_WM_COMMAND&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
     Switch GUIGetMsg()&lt;br /&gt;
         Case $GUI_EVENT_CLOSE&lt;br /&gt;
             Exit&lt;br /&gt;
         Case $hButton_1&lt;br /&gt;
             _Func_1()&lt;br /&gt;
         Case $hButton_2&lt;br /&gt;
             _Func_2()&lt;br /&gt;
     EndSwitch&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
     ; Make sure the flag is cleared&lt;br /&gt;
     $fInterrupt = 0&lt;br /&gt;
     For $i = 1 To 20&lt;br /&gt;
         ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         ; Look for the flag&lt;br /&gt;
         If $fInterrupt &amp;lt;&amp;gt; 0 Then&lt;br /&gt;
             ; The flag was set&lt;br /&gt;
             Switch $fInterrupt&lt;br /&gt;
                 Case 1&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by Func 2&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
                 Case 2&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by HotKey&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
                 Case 3&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by Accelerator&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
             EndSwitch&lt;br /&gt;
             Return&lt;br /&gt;
         EndIf&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_2()&lt;br /&gt;
     For $i = 1 To 3&lt;br /&gt;
         ConsoleWrite(&amp;quot;+Func 2 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 2 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Interrupt()&lt;br /&gt;
     ; The HotKey was pressed so set the flag&lt;br /&gt;
     $fInterrupt = 2&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)&lt;br /&gt;
     ; The Func 2 button was pressed so set the flag&lt;br /&gt;
     If BitAND($wParam, 0x0000FFFF) =  $hButton_2 Then $fInterrupt = 1&lt;br /&gt;
     ; The dummy control was actioned by the Accelerator key so set the flag&lt;br /&gt;
     If BitAND($wParam, 0x0000FFFF) =  $hAccelInterupt Then $fInterrupt = 3&lt;br /&gt;
     Return $GUI_RUNDEFMSG&lt;br /&gt;
 EndFunc   ;==&amp;gt;_WM_COMMAND&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
And now in &#039;&#039;OnEvent&#039;&#039; mode:&lt;br /&gt;
-----------------------------------&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;autoit&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;GUIConstantsEx.au3&amp;gt;&lt;br /&gt;
 #include &amp;lt;WindowsConstants.au3&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 ; Set a HotKey&lt;br /&gt;
 HotKeySet(&amp;quot;x&amp;quot;, &amp;quot;_Interrupt_HotKey&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Declare a flag&lt;br /&gt;
 $fInterrupt = 0&lt;br /&gt;
 &lt;br /&gt;
 Opt(&amp;quot;GUIOnEventMode&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 $hGUI = GUICreate(&amp;quot;Test&amp;quot;, 500, 500)&lt;br /&gt;
 GUISetOnEvent($GUI_EVENT_CLOSE, &amp;quot;_Exit&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 $hButton_1 = GUICtrlCreateButton(&amp;quot;Func One&amp;quot;, 10, 10, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_1, &amp;quot;_Func_1&amp;quot;)&lt;br /&gt;
 $hButton_2 = GUICtrlCreateButton(&amp;quot;Func Two&amp;quot;, 10, 50, 80, 30)&lt;br /&gt;
 GUICtrlSetOnEvent($hButton_2, &amp;quot;_Func_2&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 ; Create a dummy control for the Accelerator to action&lt;br /&gt;
 $hAccelInterupt = GUICtrlCreateDummy()&lt;br /&gt;
 GUICtrlSetOnEvent($hAccelInterupt, &amp;quot;_Interrupt_Accel&amp;quot;)&lt;br /&gt;
 ; Set an Accelerator key to action the dummy control&lt;br /&gt;
 Dim $AccelKeys[1][2]=[ [&amp;quot;z&amp;quot;, $hAccelInterupt] ]&lt;br /&gt;
 GUISetAccelerators($AccelKeys)&lt;br /&gt;
 &lt;br /&gt;
 GUISetState()&lt;br /&gt;
 &lt;br /&gt;
 ; Intercept Windows command messages with out own handler&lt;br /&gt;
 GUIRegisterMsg($WM_COMMAND, &amp;quot;_WM_COMMAND&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
 While 1&lt;br /&gt;
 	Sleep(10)&lt;br /&gt;
 WEnd&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_1()&lt;br /&gt;
     ; Make sure the flag is cleared&lt;br /&gt;
     $fInterrupt = 0&lt;br /&gt;
     For $i = 1 To 20&lt;br /&gt;
         ConsoleWrite(&amp;quot;-Func 1 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         ; Look for the flag&lt;br /&gt;
         If $fInterrupt &amp;lt;&amp;gt; 0 Then&lt;br /&gt;
             ; The flag was set&lt;br /&gt;
             Switch $fInterrupt&lt;br /&gt;
                 Case 1&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by Func 2&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
                 Case 2&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by HotKey&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
                 Case 3&lt;br /&gt;
                     ConsoleWrite(&amp;quot;!Func 1 interrrupted by Accelerator&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
             EndSwitch&lt;br /&gt;
             Return&lt;br /&gt;
         EndIf&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 1 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Func_2()&lt;br /&gt;
     For $i = 1 To 3&lt;br /&gt;
         ConsoleWrite(&amp;quot;+Func 2 Running&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
         Sleep(100)&lt;br /&gt;
     Next&lt;br /&gt;
     ConsoleWrite(&amp;quot;&amp;gt;Func 2 Ended&amp;quot; &amp;amp; @CRLF)&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Exit()&lt;br /&gt;
     Exit&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Interrupt_HotKey()&lt;br /&gt;
     ; The HotKey was pressed so set the flag&lt;br /&gt;
     $fInterrupt = 2&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _Interrupt_Accel()&lt;br /&gt;
     ; This is an empty function for the dummy control linked to the Accelerator key&lt;br /&gt;
 EndFunc&lt;br /&gt;
 &lt;br /&gt;
 Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)&lt;br /&gt;
     ; The Func 2 button was pressed so set the flag&lt;br /&gt;
     If BitAND($wParam, 0x0000FFFF) =  $hButton_2 Then $fInterrupt = 1&lt;br /&gt;
     ; The dummy control was actioned by the Accelerator key so set the flag&lt;br /&gt;
     If BitAND($wParam, 0x0000FFFF) =  $hAccelInterupt Then $fInterrupt = 3&lt;br /&gt;
     Return $GUI_RUNDEFMSG&lt;br /&gt;
 EndFunc   ;==&amp;gt;_WM_COMMAND&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-----------------------------------&lt;br /&gt;
So there are the ways available in AutoIt to interrupt a running function.  Remember that you must be in &#039;&#039;OnEvent&#039;&#039; mode and start the function from the main code - or have a function which checks internally whether it ought to allow an interruption.  In all other cases you are are not going to be able to interrupt your function.&lt;/div&gt;</summary>
		<author><name>Melba23</name></author>
	</entry>
</feed>