AutoIt/Nietypowe techniki programowania
Metaprogramowanie, metajęzyk, refleksyjność
edytujMetaprogramowanie - technika umożliwiająca programom tworzenie lub modyfikację kodu innych programów (lub ich samych). Język umożliwiający stosowanie tej techniki nazywamy metajęzykiem.
Jeżeli metajęzyk umożliwia modyfikację własnego kodu, nazywany jest metajęzykiem refleksyjnym, a proces programowanie z użyciem tego mechanizmu, programowaniem refleksyjnym.
W Autoit istnieje możliwość użycia zmiennej łańcuchowej (stringu) jako elementu treści programu. Dzięki temu sam kod programu może być traktowany w sposób podobny jak zawarte w nim dane i modyfikowany dynamicznie w trakcie wykonywania.
Technika ta, rzadko realizowana w innych językach programowania, umożliwia w pewnych przypadkach uzyskanie efektów, których osiągnięcie innym sposobem byłoby trudne i pracochłonne.
Stringami mogą być:
- nazwy zmiennych
- nazwy funkcji
- wyrażenia (ten przypadek jest szczególnie interesujący)
W dalszej części rozdziału opiszę jak osiągnąć taki efekt i jakie korzyści można z niego mieć.
Jak to w AutoIt przeważnie bywa, wszystko jest realizowane za pomocą odpowiednich funkcji.
String jako nazwa zmiennej
edytujFunkcja Assign
edytujAssign ("nazwa_zmiennej", wartość_zmiennej [, flaga])
Funkcja nadaje wartość (i ewentualnie tworzenie) zmiennej o podanej nazwie. Zwraca 1 gdy sukces, lub 0 gdy wystąpił błąd.
"nazwa_zmiennej" - nazwa zmiennej musi być utworzona zgodnie z ogólnymi zasadami tworzenie nazw zmiennych, należy jednak pominąć prefiks $ (np. zmienna_1 a nie $zmienna_1). Można nadawać wartości zmiennym wcześniej utworzonym w sposób klasyczny. Zmienna nie może być tablicą.
wartość_zmiennej - wartość nadawana tworzonej zmiennej
flaga - określa sposób tworzenia zmiennej
0 - zmienna jest tworzona jeżeli nie istnieje (wartość domyślna) 1 - tworzenie zmiennej o zakresie lokalnym 2 - tworzenie zmiennej o zakresie globalnym 4 - błąd jeżeli zmienna nie istnieje
Funkcja Eval
edytujEval ("nazwa_zmiennej")
Funkcja zwraca wartość zmiennej o nazwie podanej jako parametr. Jeżeli wystąpił błąd funkcja zwraca pusty string "", a makro @error przyjmuje wartość 1.
"nazwa_zmiennej" - nazwa zmiennej zgodna z ogólnymi zasadami tworzenie nazw zmiennych, należy jednak pominąć prefiks $ (np. zmienna_1 a nie $zmienna_1). Można odczytywać wartości zmiennych wcześniej utworzonym w sposób klasyczny. Zmienna nie może być tablicą.
Przykład zastosowania:
Przypuśćmy, że musimy utworzyć 99 zmiennych wg schematu $x1=1, $x2=2 ... $x99=99. W klasyczny sposób trzeba by 99 razy użyć instrukcji przypisania.
Było by to bardzo pracochłonne i rozwlekłe. Można jednak inaczej:
For $i=1 to 99
Assign("x"&$i, $i, 1)
Next
MsgBox(0, "", Eval("x66"))
Od wersji 3.3.12 możliwe jest odczytanie tak utworzonych zmiennych w sposób klasyczny (próba klasycznego odczytania wartości zmiennej dla wcześniejszych wersji AutoIt'a powodowała błąd):
For $i=1 to 99
Assign("x" & $i, $i)
Next
MsgBox(0, "", $x66) ;błąd niezadeklarowanej zmiennej
Dla wcześniejszych wersji niż 3.3.12 trzeba było użyć dyrektywy #forcedef:
For $i=1 to 99
Assign("x" & $i, $i)
Next
#forcedef $x66
MsgBox(0, "", $x66)
Funkcja Assign bez problemu nadaje wartość zmiennym utworzonym w sposób klasyczny:
Local $txt
Assign("txt", "wasta")
MsgBox(0, "", $txt)
a funkcja Eval odczytuje te zmienne:
$txt = "wasta"
MsgBox(0, "", Eval("txt"))
Funkcja IsDeclared
edytujIsDeclared ("nazwa_zmiennej")
Funkcja sprawdza czy została utworzona zmienna o podanej nazwie. Zwraca:
1 - gdy zmienna jest globalna
-1 - gdy zmienna jest lokalna
0 - gdy zmienna nie została utworzona
Działa ze zmiennymi utworzonymi klasycznie, jak i utworzonymi przez funkcję Assign.
Przykład:
For $i=1 to 99
Assign("x" & $i, $i)
Next
MsgBox(0, "", IsDeclared("x66")) ;wyświetli 1
test() ;wyświetli -1
MsgBox(0, "", IsDeclared("b")) ;wyświetli 0
Func test()
Local $a
MsgBox(0, "", IsDeclared("a"))
EndFunc
String jako nazwa funkcji
edytujStringu jako nazwy funkcji można użyć tylko przy jej wywołani, lecz nie przy jej deklarowaniu. Służy do tego:
Funkcja Call
edytujCall ( "nazwa_funkcji" [, param1 [, param2 [, paramN]]] )
Funkcja wywołuje funkcję o podanej nazwie i opcjonalnie przekazuje do niej parametry. Jeżeli sukces to zwraca wartość zwracaną przez wywołaną funkcję (makra @error i @extended mogą być także przez nią ustawione).
W przypadku błędu makro @error przyjmuje wartość 0xDEAD, a makro @extended 0xBEEF (jeśli funkcja nie istnieje lub podano niewłaściwą ilość parametrów).
Uwaga: Wywoływana funkcja od wersji 3.3.10.2 może być funkcją wbudowaną translatora, parametry mogą być przekazywane przez referencję.
Przykład:
MsgBox(0,"",Call("test",1,2,3))
Func test($a, $b, $c)
Return $a+$b+$c
EndFunc
String jako wyrażenie
edytujO ile trudno znaleźć sensowne zastosowanie dla funkcji Call, to użycie stringu jako wyrażenia ma duży potencjał programistyczny.
Wyrażeniem jest w zasadzie wszystko to, czemu możemy wyliczyć jakąś wartość. Może ono zawierać liczby, zmienne, stałe, operatory arytmetyczne i logiczne, operatory relacji oraz wywołania funkcji tak wbudowanych jak i zdefiniowanych przez programistę. Do wartościowania wyrażenia opisanego za pomocą stringu służy:
Funkcja Execute
edytujExecute ( "string" )
Funkcja zwraca wartość wyrażenia opisanego stringiem. Jeżeli wystąpił błąd to zwraca pusty łańcuch, a makro @error przyjmuje wartość różną od zera.
"string" - string z opisem wyrażenia
Ponieważ string z opisem wyrażenia może pochodzić z zewnątrz programy, jest możliwe wykonanie wewnątrz programu fragmentu kodu wczytanego z dysku lub wpisanego bezpośrednio z klawiatury.
Kilka przykładów, które zaprezentują możliwości funkcji Execute.
$ex='MsgBox(0, "Test Execute:", "Ala ma Asa")'
Execute($ex)
$ex = "(1+2)^2-5/3"
MsgBox(0, "Test 2:", Execute($ex))
$a=2
$b=3
MsgBox(0, "Test 3:", Execute("$a=$b"))
MsgBox(0, "Test 4:", Execute("sin($a)+cos($a+$b)"))
MsgBox(0, "Test 5:", Execute("test($a, $b)"))
Func test($p1, $p2)
Return $p1+$p2
EndFunc
Zmienna zawierająca nazwę funkcji
edytujOd wersji 3.10.2 w AutoIt wprowadzono możliwość przechowywania w zmiennej nazwy funkcji.
Przykład:
$vFunc = MsgBox
$vFunc(0, "Test", "To działa!")
FuncName
edytujFuncName ( $Functionvariable )
Funkcja zwraca w postaci stringu nazwę funkcji przechowywanej w zmiennej, lub string pusty gdy wystąpił błąd.
$Functionvariable - zmienna przechowująca nazwę funkcji
Przykład:
$hFunc = MsgBox
MsgBox(0, "Test", "Nazwa funkcji to: " & FuncName($hFunc))
IsFunc
edytujIsFunc ( $Variable )
Funkcja sprawdza czy zmienna zawiera nazwę funkcji. Zwraca 1 gdy funkcja jest zdefiniowana przez użytkownika, 2 gdy funkcja jest funkcją wbudowaną translatora, lub 0 gdy zmienna nie zawiera nazwy funkcji.
$Variable - sprawdzana zmienna
Przykład:
$hFunc = MsgBox
MsgBox(0, "Test", "Jaki to rodzaj funkcji: " & IsFunc($hFunc))
Na koniec użyteczny przykład, kalkulator zapamiętujący wzór funkcji i obliczający jej wartość dla różnych argumentów:
#include <GUIConstantsEx.au3>
GUICreate("Wprowadź wartość zmiennej i wzór funkcji", 360, 120, -1, 300)
$f1 = GUICtrlCreateInput(0, 50, 5, 200, 20)
GUICtrlCreateLabel("$x=", 25, 8, 20, 20)
$f2 = GUICtrlCreateInput("", 50, 35, 200, 20)
GUICtrlCreateLabel("f(x)=", 22, 38, 30, 20)
$btn = GUICtrlCreateButton("Oblicz", 40, 75, 60, 20)
GUISetState()
Do
$msg = GUIGetMsg()
$txt1 = GUICtrlRead($f1)
$txt2 = GUICtrlRead($f2)
If $msg = $btn Then
$x=Execute($txt1)
$res = Execute($txt2)
MsgBox(4096, "Wynik:", $res)
EndIf
Until $msg = $GUI_EVENT_CLOSE
Niestandardowe struktury danych
edytujStruktura danych (ang. data structure) - sposób uporządkowania informacji w komputerze. Na strukturach danych operują algorytmy.
W zasadzie AutoIt posiada standardowo tylko dwie struktury danych, zmienne proste przechowujące pojedynczą wartość i tablice.
W rozdziale o bibliotekach DLL omówiona została także struktura (rekord), do której dostęp jest możliwy za pomocą stosownych funkcji.
Czasami jednak z pewnych względów optymalne będzie użycie innych struktur danych. Podczas tworzenia skryptu programista musi dokonać wyboru odpowiedniej struktury, aby uzyskać pożądany efekt. Niewłaściwy wybór może niekorzystnie wpłynąć na złożoność obliczeniową, co przekłada się na szybkość działania programu. Jest to szczególnie ważne przy operowaniu dużymi zbiorami danych. Z drugiej strony należy także uwzględnić łatwość implementacji danej struktury w konkretnym przypadku.
Tablica asocjacyjna
edytujTablica asocjacyjna: (tablica skojarzeniowa, mapa, słownik, ang. associative array, map, dictionary) – nazwa dla powszechnie stosowanego w informatyce abstrakcyjnego typu danych, który przechowuje pary (unikatowy klucz, wartość) i umożliwia dostęp do wartości poprzez podanie klucza.
Standardowo AutoIt nie posiada możliwości posługiwania się tego typu tablicami. Można jednak używać tablic asocjacyjnych za pośrednictwem znajdującego się w systemie operacyjnym obiektu Scripting.Dictionary. Obiekt ten posiada kilka metod umożliwiających tworzenie i manipulowanie tablicami asocjacyjnymi.
Tworzenie tablicy
edytuj$nazwa_tablicy = ObjCreate("Scripting.Dictionary")
Dodawanie elementów do tablicy (metoda .Add)
edytuj$nazwa_tablicy.Add($nazwa_klucza, $wartosc_klucza)
Usunięcie elementu tablicy (metoda .Remove)
edytuj$nazwa_tablicy.Remove($nazwa_klucza)
Usunięcie wszystkich elementów tablicy (metoda .RemoveAll)
edytuj$nazwa_tablicy.RemoveAll
Odczyt elementu tablicy (metoda .Item)
edytuj$wartosc_klucza = $nazwa_tablicy.Item($nazwa_klucza)
lub w skrócie:
$wartosc_klucza = $nazwa_tablicy($nazwa_klucza)
Nadanie wartości elementowi tablicy (metoda .Item)
edytuj$nazwa_tablicy.Item($nazwa_klucza) = $wartosc_klucza
lub w skrócie:
$nazwa_tablicy($nazwa_klucza) = $wartosc_klucza
Odczytanie w postaci 1-wymiarowej tablicy wszystkich wartości tablicy asocjacyjnej (metoda .Items)
edytuj$array = $nazwa_tablicy.Items
Odczytanie w postaci 1-wymiarowej tablicy wszystkich kluczy tablicy asocjacyjnej (metoda .Keys)
edytuj$array = $nazwa_tablicy.Keys
Zmiana nazwy klucza (metoda .Key)
edytuj$nazwa_tablicy.Key($stary_klucz) = $nowy_klucz
Sprawdzenie czy istnieje klucz o podanej nazwie (metoda .Exists)
edytuj$i = $nazwa_tablicy.Exists($nazwa_klucza)
Zwraca True gdy klucz istnieje, lub False gdy nie istnieje.
Ilość elementów tablicy asocjacyjnej (metoda .Count)
edytuj$i = $nazwa_tablicy.Count
UWAGA: Nazwa klucza może być stringiem lub dowolną liczbą, wartość może być dowolnego typu. W nazwach kluczy obiekt rozpoznaje wielkość liter, tak więc np. Klucz1 i klucz1 to dwie różne nazwy.
Przykład:
#include <array.au3>
$dane = ObjCreate("Scripting.Dictionary") ;tworzenie tablicy asocjacyjnej
;dodawanie kolejnych pól w tablicy
$dane.Add("nazwisko", "Kowalski")
$dane.Add("imię", "Jan")
$dane.Add("wiek", 61)
$dane.Add("wzrost", 170)
$dane.Add("kolor_oczu", "niebieskie")
$dane.Add(6.66, "wyższe")
;odczyt danych z poszczególnych pól tablicy
MsgBox(64, "Tablica asocjacyjna", _
"Pan " & $dane.Item("imię") & " " & $dane.Item("nazwisko") & _
" ma lat " & $dane.Item("wiek") & _
", " & $dane.Item("wzrost") & " cm wzrostu" & _
" i oczy " & $dane.Item("kolor_oczu") & ".")
;odczytanie w postaci tablicy, wartości wszystkich pól tablicy
$arr = $dane.Items
_ArrayDisplay($arr)
;odczytanie w postaci tablicy, wszystkich kluczy tablicy
$arr = $dane.Keys
_ArrayDisplay($arr)
$dane("kolor_oczu") = "zielone" ;zmiana wartości
MsgBox(0, "Kolor oczu", $dane("kolor_oczu"))
;zmiana nazwy klucza
$dane.Key(6.66) = "wykształcenie"
;sprawdzenie czy istnieje podany klucz
MsgBox(0, 'Klucz "wykształcenie"', $dane.Exists("wykształcenie"))
MsgBox(0, "Ilość elementów", $dane.Count)
$dane.Remove("wykształcenie") ;usunięcie podanego klucza
MsgBox(0, 'Klucz "wykształcenie"', $dane.Exists("wykształcenie"))
UWAGA: Pozostałe struktury danych wymagają .NET Framework 4.5
Tablica mieszająca
edytujZa Wiki:
Tablica mieszająca lub tablica z haszowaniem (ang. hash table) to struktura danych, która jest jednym ze sposobów realizacji tablicy asocjacyjnej, tj. abstrakcyjnego typu danych służącego do przechowywania informacji, w taki sposób aby możliwy był do nich szybki dostęp. Tablica mieszająca umożliwia również szybkie porównywanie danych, np. fragmentów tekstów, plików, itp.
Elementy tablicy mieszającej są indeksowane liczbowymi indeksami generowanym przez funkcję mieszającą. Odwołania do przechowywanych obiektów dokonywane są na podstawie klucza, który dany obiekt (informację) identyfikuje. Na podstawie klucza funkcja mieszająca generuje indeks, po którym przeszukiwana jest tablica. Przy dużych tablicach taka metoda jest o wiele szybsza niż bezpośrednie wyszukiwanie po kluczu, jak w tablicy asocjacyjnej.
Ponieważ cały proces tworzenia indeksów i przeszukiwania jest przeprowadzany w tle przez procedury systemu operacyjnego, dla programisty samo operowanie tablicami asocjacyjnymi i mieszającymi w zasadzie niczym się nie różni.
Tworzenie tablicy mieszającej
edytuj$nazwa_tablicy = ObjCreate("System.Collections.Hashtable")
Dodawanie elementów do tablicy (metoda .Add)
edytuj$nazwa_tablicy.Add($nazwa_klucza, $wartosc_klucza)
Usuwanie elementu tablicy (metoda .Remove)
edytuj$nazwa_tablicy.Remove($nazwa_klucza)
Usunięcie wszystkich elementów tablicy (metoda .Clear)
edytuj$nazwa_tablicy.Clear
Odczyt elementu tablicy
edytuj$wartosc_klucza = $nazwa_tablicy($nazwa_klucza)
Nadanie wartości elementowi tablicy
edytuj$nazwa_tablicy($nazwa_klucza) = $wartosc_klucza
Sprawdzenie czy istnieje klucz o podanej nazwie (metoda .Contains)
edytuj$i = $nazwa_tablicy.Contains($nazwa_klucza)
Sprawdzenie czy istnieje podana wartość (metoda .ContainsValue)
edytuj$i = $nazwa_tablicy.ContainsValue($nazwa_klucza)
Zwraca True gdy klucz istnieje, lub False gdy nie istnieje.
Ilość elementów tablicy mieszającej (metoda .Count)
edytuj$i = $nazwa_tablicy.Count
Przykład:
$hash = ObjCreate("System.Collections.Hashtable") ;tworzenie tablicy mieszającej
;dodawanie elementów do tablicy mieszającej
$hash.Add("Polska", "Kraków")
$hash.Add("Niemcy", "Berlin")
$hash.Add("Francja", "Paryż")
$hash.Add("Rosja", "Moskwa")
$hash.Add("Czechy", "Praga")
;zmiana wartości klucza
$hash("Polska") = "Warszawa"
MsgBox(0, "Count", "W bazie jest " & $hash.Count & " pozycji.") ;ilość elementów w tablicy
$country = "Polska"
MsgBox(0, "Odczyt", "Państwo: " & $country & @LF & _
"Stolica: " & $hash($country)) ;odczyt elementu z tablicy
;czy w tablicy jest dana wartość
MsgBox(0, "ContainsValue", "Czy w bazie jest Paryż: " & $hash.ContainsValue("Paryż"))
;czy w tablicy jest dany klucz
MsgBox(0, "Contains", "Czy w bazie jest Francja: " & $hash.Contains("Francja"))
$hash.Remove("Francja") ;usunięcie z tablicy elementu o zadanym kluczu
MsgBox(0, "ContainsValue", "Czy w bazie jest Paryż: " & $hash.ContainsValue("Paryż"))
SortedList
edytujJest to odmiana tablicy asocjacyjnej, która w momencie tworzenia i modyfikacji jest domyślnie sortowana po kluczu. Zwiększa to czas tworzenia tablicy, lecz zmniejsza czas wyszukiwania informacji. Dostęp do tablicy może być realizowany po kluczu lub po indeksie.
Tworzenie SortedList
edytuj$nazwa_tablicy = ObjCreate("System.Collections.SortedList")
Dodanie wartości do SortedList (metoda .Add)
edytuj$nazwa_tablicy.Add($nazwa_klucza, $wartosc_klucza)
Usunięcie elementu o podanym kluczu (metoda .Remove)
edytuj$nazwa_tablicy.Remove($nazwa_klucza)
Usunięcie elemenu o podanym indeksie (metoda .RemoveAt)
edytuj$nazwa_tablicy.RemoveAt($indeks)
Usunięcie wszystkich elementów tablicy (metoda .Clear)
edytuj$nazwa_tablicy.Clear
Odczyt elementu tablicy
edytuj$wartosc_klucza = $nazwa_tablicy($nazwa_klucza)
Nadanie wartości elementu tablicy
edytuj$nazwa_tablicy($nazwa_klucza) = $wartosc_klucza
Sprawdzenie czy istnieje klucz o podanej nazwie (metoda .Contains)
edytuj$i = $nazwa_tablicy.Contains($nazwa_klucza)
Zwraca True gdy klucz istnieje, lub False gdy nie istnieje.
Sprawdzenie czy istnieje podana wartość (metoda .ContainsValue)
edytuj$i = $nazwa_tablicy.ContainsValue($nazwa_klucza)
Zwraca True gdy wartość istnieje, lub False gdy nie istnieje.
Ilość elementów tablicy (metoda .Count)
edytuj$i = $nazwa_tablicy.Count
Indeks elementu o podanym kluczu (metoda .IndexOfKey)
edytuj$indeks = $nazwa_tablicy.IndexOfKey($nazwa_klucza)
Indeks pierwszego elementu o podanej wartości (metoda .IndexOf Value)
edytuj$indeks = $nazwa_tablicy.IndexOfValue($wartosc_klucza)
Odczyt klucza o zadanym indeksie (metoda .GetKey)
edytuj$nazwa_klucza = $nazwa_tablicy.GetKey($indeks)
Odczyt wartości o zadanym indeksie (metoda .GetByIndex)
edytuj$wartosc_klucza = $nazwa_tablicy.GetByIndex($indeks)
Zmiana wartości pod zadanym indeksem (metoda .SetByIndex)
edytuj$nazwa_tablicy.SetByIndex($indeks, $wartosc)
Przykład:
$SList = ObjCreate("System.Collections.SortedList") ;tworzenie tablicy mieszającej
;dodawanie elementów do tablicy mieszającej
$SList.Add("Polska", "Kraków")
$SList.Add("Niemcy", "Berlin")
$SList.Add("Francja", "Paryż")
$SList.Add("Rosja", "Moskwa")
$SList.Add("Czechy", "Praga")
;zmiana wartości klucza
$SList("Polska") = "Warszawa"
MsgBox(0, "Count", "W bazie jest " & $SList.Count & " pozycji.") ;ilość elementów w tablicy
$country = "Polska"
MsgBox(0, "Odczyt", "Państwo: " & $country & @LF & _
"Stolica: " & $SList($country)) ;odczyt elementu z tablicy
;czy w tablicy jest dana wartość
MsgBox(0, "ContainsValue", "Czy w bazie jest Paryż: " & $SList.ContainsValue("Paryż"))
;czy w tablicy jest dany klucz
MsgBox(0, "Contains", "Czy w bazie jest Francja: " & $SList.Contains("Francja"))
$SList.Remove("Francja") ;usunięcie z tablicy elementu o zadanym kluczu
MsgBox(0, "ContainsValue", "Czy w bazie jest Paryż: " & $SList.ContainsValue("Paryż"))
;odczyt indeksu klucza
MsgBox(0,"IndexOfKey", "Indeks dla klucza 'Polska': " & $SList.IndexOfKey("Polska"))
;odczyt indeksu podanej wartości
MsgBox(0,"IndexOfValue", "Indeks dla wartości 'Praga': " & $SList.IndexOfValue("Praga"))
;odczyt klucza dla zadanego indeksu
MsgBox(0,"GetKey", "Klucz dla indeksu 2: " & $SList.GetKey(2))
;odczyt wartości dla zadanego indeksu
MsgBox(0,"GetByIndex", "Wartość dla indeksu 2: " & $SList.GetByIndex(2))
Lista
edytujLista – struktura danych służąca do reprezentacji zbiorów dynamicznych, w której elementy ułożone są w liniowym porządku. Elementy listy są indeksowane (indeksy rozpoczynają się od 0, podobnie jak w tablicach).
Także i ten typ danych nie jest standardowo dostępny w AutoIt, dlatego musimy posłużyć się obiektem System.Collections.ArrayList.
Podstawową zaletą używania list zamiast tablic jest wzrost wydajności. Dostęp do elementów listy jest o wiele szybszy.
Tworzenie listy
edytuj$nazwa_listy = ObjCreate("System.Collections.ArrayList")
Dodawanie elementów na końcu listy (metoda .Add)
edytuj$nazwa_listy.Add($wartosc)
Dodawanie elementu na pozycji o zadanym indeksie (metoda .Insert)
edytuj$nazwa_listy.Insert($indeks, $wartosc)
Indeksy pozostałych elementów są zwiększane o 1.
Usunięcie pierwszego elementu o zadanej wartości (metoda .Remove)
edytuj$nazwa_listy.Remove($wartosc)
Indeksy pozostałych elementów są zmniejszane o 1.
Usunięcie elementu o zadanym indeksie (metoda .RemoveAt)
edytuj$nazwa_listy.RemoveAt($indeks)
Indeksy pozostałych elementów są zmniejszane o 1.
Usunięcie elementów o zadanym zakresie indeksów (metoda .RemoveRange)
edytuj$nazwa_listy.RemoveRange($indeks, $ilosc_elementow_do_usuniecia)
Indeksy pozostałych elementów są zmniejszane o $ilosc_elementow_do_usuniecia.
Tworzenie nowej listy z elementów o zadanym zakresie indeksów (metoda .GetRange)
edytuj$nowa_lista = $nazwa_listy.GetRange($indeks, $ilosc_elementow_do_kopiowania)
Usunięcie wszystkich elementów listy (metoda .Clear)
edytuj$nazwa_listy.Clear
Odczyt elementu listy o zadanym indeksie (metoda .Item)
edytuj$wartosc = $nazwa_listy.Item($indeks)
Zmiana wartości elementu listy o zadanym indeksie (metoda .Item)
edytuj$nazwa_listy.Item($indeks) = $wartosc
Odwrócenie kolejności elementów listy (metoda .Reverse)
edytuj$nazwa_listy.Reverse
Odczytanie ilości elementów listy (metoda .Count)
edytuj$i = $nazwa_listy.Count
Kopiowanie zawartości listy do jednowymiarowej tablicy (metoda .ToArray)
edytuj$array = $nazwa_listy.ToArray
Sprawdzenie czy istnieje element o zadanej wartości (metoda .Contains)
edytuj$i = $nazwa_listy.Contains($wartosc)
Zwraca True gdy dana wartość jest w liście, w przeciwnym razie zwraca False.
Przykład:
$aList = ObjCreate("System.Collections.ArrayList") ;tworzenie listy
;dodawanie elementów na końcu listy
$aList.Add("a")
$aList.Add("b")
$aList.Add("c")
$aList.Add("d")
$aList.Add("a")
$aList.Add(3.1415)
$aList.Add("wasta")
ViewList($aList, "LISTA")
$aList.Insert(3,"ble, ble, ble") ;wstawienie elementu na pozycji o indeksie 3
ViewList($aList, "Insert(3)")
$aList.Item(3) = 666
ViewList($aList, "Item(3)")
$aList.Reverse
ViewList($aList, "Reverse")
$aList.Remove("a")
ViewList($aList, "Remove 'a'")
$aList.RemoveAt(2)
ViewList($aList, "RemoveAt(2)")
$aList.RemoveRange(2, 3)
ViewList($aList, "RemoveRange(4,3)")
$str = $aList.ToArray
MsgBox(0, "LISTA", "Element o indeksie 1 = " & $str[1])
;szukanie elementu o zadanej wartości
MsgBox(0,"LISTA", "Czy jest element o wartości 'wasta': " & $aList.Contains("wasta"))
$aList.Clear ;usunięcie wszystkich elementów listy
MsgBox(0, "LISTA", "Ilość elementów = " & $aList.Count) ;ilość elementów listy
;funkcja wyświetlająca zawartość listy
Func ViewList($aList, $title="")
Local $n = $aList.Count ;ilość elementów listy
Local $txt = "Indeks | Wartość" & @LF
For $i=0 To $n-1
$txt &= "---------------------" & @LF
$txt &= $i & " | " & $aList.Item($i) & @LF ;odczyt elementu o zadanym indeksie
Next
MsgBox(0, $title, $txt)
EndFunc
Kolejka
edytujKolejka (ang. queue) – liniowa struktura danych, w której nowe dane dopisywane są na końcu kolejki, a z początku kolejki pobierane są dane do dalszego przetwarzania (bufor typu FIFO, First In, First Out; pierwszy na wejściu, pierwszy na wyjściu).
Tworzenie kolejki
edytuj$nazwa_kolejki = ObjCreate("System.Collections.Queue")
Dodawanie elementu do końca kolejki (metoda .Enqueue)
edytuj$nazwa_kolejki.Enqueue($wartość)
Odczyt elementu z początku kolejki i jego usunięcie (metoda .Dequeue)
edytuj$wartosc = $nazwa_kolejki.Dequeue
Odczyt elementu z początku kolejki bez jego usunięcia (metoda .Peek)
edytuj$wartosc = $nazwa_kolejki.Peek
Usunięcie wszystkich elementów kolejki (metoda .Clear)
edytuj$nazwa_kolejki.Clear
Odczytanie ilości elementów kolejki (metoda .Count)
edytuj$i = $nazwa_kolejki.Count
Kopiowanie zawartości kolejki do jednowymiarowej tablicy (metoda .ToArray)
edytuj$array = $nazwa_kolejki.ToArray
Sprawdzenie czy istnieje element o zadanej wartości (metoda .Contains)
edytuj$i = $nazwa_kolejki.Contains($wartosc)
Zwraca True gdy dana wartość jest w liście, w przeciwnym razie zwraca False.
Przykład:
#include <array.au3>
$queue = ObjCreate("System.Collections.Queue") ;tworzenie kolejki
;dopisywanie elementów do kolejki
$queue.Enqueue(3.1415)
$queue.Enqueue("a")
$queue.Enqueue("b")
$queue.Enqueue("c")
$queue.Enqueue("wasta")
ViewQueue($queue)
;odczyt elementu bez usuwania
MsgBox(0, "Peek", "Początek kolejki = " & $queue.Peek)
MsgBox(0, "Count", "Ilość elementów kolejki = " & $queue.Count)
;odczyt elementu z usunięciem z kolejki
MsgBox(0, "Dequeue", "Początek kolejki = " & $queue.Dequeue)
MsgBox(0, "Count", "Ilość elementów kolejki = " & $queue.Count)
;czy element o zadanej wartości jest w kolejce
MsgBox(0, "Contains", "Czy 'wasta' jest w kolejce: " & $queue.Contains("wasta"))
;usunięcie wszystkich elementów kolejki
$queue.Clear
MsgBox(0, "Clear", "Ilość elementów kolejki = " & $queue.Count)
;wyświetlenie zawartości kolejki
Func ViewQueue($queue, $title="KOLEJKA")
Local $Array = $queue.ToArray ;kopiowanie kolejki do tablicy
_ArrayDisplay($Array, $title)
EndFunc
Stos
edytujStos (ang. Stack) – liniowa struktura danych, w której dane dokładane są na wierzch stosu i z wierzchołka stosu są pobierane (bufor typu LIFO, Last In, First Out; ostatni na wejściu, pierwszy na wyjściu).
Tworzenie stosu
edytuj$nazwa_stosu = ObjCreate("System.Collections.Stack")
Dodawanie elementu na górę stosu (metoda .Push
edytuj$nazwa_stosu.Push($wartość)
Odczyt elementu z góry stosu i jego usunięcie (metoda .Pop)
edytuj$wartosc = $nazwa_stosu.Pop
Odczyt elementu z góry stosu bez jego usunięcia (metoda .Peek)
edytuj$wartosc = $nazwa_stosu.Peek
Usunięcie wszystkich elementów stosu (metoda .Clear)
edytuj$nazwa_stosu.Clear
Odczytanie ilości elementów stosu (metoda .Count)
edytuj$i = $nazwa_stosu.Count
Kopiowanie zawartości stosu do jednowymiarowej tablicy (metoda .ToArray)
edytuj$array = $nazwa_stosu.ToArray
Sprawdzenie czy istnieje element o zadanej wartości (metoda .Contains)
edytuj$i = $nazwa_stosu.Contains($wartosc)
Zwraca True gdy dana wartość jest w liście, w przeciwnym razie zwraca False.
Przykład:
#include <array.au3>
$stack = ObjCreate("System.Collections.Stack") ;tworzenie stosu
;dodawanie elementów na wierzch stosu
$stack.Push(3.1415)
$stack.Push("a")
$stack.Push("b")
$stack.Push("c")
$stack.Push("wasta")
ViewStack($stack)
;odczyt elementu z wierzchu stosu bez usuwania
MsgBox(0, "Peek", "Wierzch stosu = " & $stack.Peek)
MsgBox(0, "Count", "Ilość elementów stosu = " & $stack.Count)
;odczyt elementu z usunięciem ze stosu
MsgBox(0, "Pop", "Wierzch stosu = " & $stack.Pop)
MsgBox(0, "Count", "Ilość elementów stosu = " & $stack.Count)
;czy element o zadanej wartości jest na stosie
MsgBox(0, "Contains", "Czy 'wasta' jest na stosie: " & $stack.Contains("wasta"))
;usunięcie wszystkich elementów stosu
$stack.Clear
MsgBox(0, "Clear", "Ilość elementów stosu = " & $stack.Count)
;wyświetlenie zawartości stosu
Func ViewStack($stack, $title="STOS")
Local $Array = $stack.ToArray ;kopiowanie stosu do tablicy
_ArrayDisplay($Array, $title)
EndFunc
Uruchamianie skryptu
edytujSkrypty AutoIt można uruchamiać spod edytora SciTe wciskając klawisz F5. Po skompilowaniu skrypt uruchamia się jak każdy plik wykonywalny Windows.
Oprócz tych standardowych sposobów, są możliwe także inne mniej typowe.
Uruchamianie skryptów z wiersza poleceń
edytujSkompilowane skrypty AutoIt'a można uruchomić z wiersza poleceń (linii komend). Możliwe jest także przekazywanie parametrów do tak uruchamianych skryptów.
Służy do tego zdefiniowana w translatorze globalna tablica o nazwie $CmdLine. Tablica jest tylko do odczytu, inicjowana w momencie uruchomienia skryptu. Ma ona następującą strukturę:
$CmdLine[0] - ilość parametrów przekazanych w wierszu poleceń $CmdLine[1] - wartość 1 parametru ... $CmdLine[n] - wartość n-tego paramatru
Należy pamiętać, że wszystkie parametry przekazywane z wiersza poleceń są tekstami. Separatorem między parametrami są spacje. Jeżeli chcemy przekazać parametr zawierający spacje, należy ująć go w cudzysłowy.
Można maksymalnie przekazać 63 parametry.
Przykład wywołania skryptu:
myprog.exe 1 2 "Autoit to jest to!" Wasta
Tablica $CmdLine będzie zawierać następujące wartości
$CmdLine[0] = 4 (ilość parametrów) $CmdLine[1] = 1 (string 1 parametru) $CmdLine[2] = 2 (string 2 parametru) $CmdLine[3] = Autoit to jest to! (string 3 parametru) $CmdLine[4] = Wasta (string 4 parametru)
Przykład skryptu wypisującego w konsoli listę parametrów, a w okienku MsgBox ich ilość (skrypt należy skompilować):
#AutoIt3Wrapper_Change2CUI=y
$iIL = $CmdLine[0]
If $iIL>0 Then
For $i=1 To $iIL
ConsoleWrite($CmdLine[$i] & @LF)
Next
EndIf
MsgBox(64, "Ilość parametrów:", $CmdLine[0])
Oprócz tablicy $CmdLine zdefiniowana jest także globalna zmienna $CmdLineRaw, która przechowuje listę parametrów w postaci stringu. Ta zmienna jest także tylko do odczytu, inicjowana w momencie uruchomienia skryptu.
Przykład skryptu wypisującego w okienku MsgBox listę wprowadzonych parametrów (skrypt należy skompilować):
MsgBox(64, "Lista parametrów:", $CmdLineRaw)
Uruchamianie pojedynczej linii kodu z wiersza poleceń
edytujMożna wykonać pojedynczą linię kodu bezpośrednio z wiersza poleceń:
AutoIt3.exe [/komunikat błędu] /AutoIt3ExecuteLine "wiersz kodu do wykonania"
Przykład:
AutoIt3.exe /AutoIt3ExecuteLine "MsgBox(4096, 'Witaj świecie!', 'Cześć!')"
Sposób ten jest możliwy także wewnątrz skryptu:
Run(@AutoItExe & ' /AutoIt3ExecuteLine "MsgBox(0, ''Witaj świecie!'', ''Cześć!'')"')
Uruchomienie skryptu AutoIt z wnętrza innego skryptu
edytujMetoda ta umożliwia uruchomienie nieskompilowanego skryptu z wnętrza innego skryptu AutoIt. Skrypt uruchamiający może być skompilowany lub nie. Dla skryptu skompilowanego niezbędne jest użycie dyrektywy #pragma compile(AutoItExecuteAllowed, True). Domyślnie dyrektywa ta jest ustawiona na False, co blokuje możliwość uruchamiania skryptów w ten sposób.
Jeżeli skrypt uruchamiający nie jest skompilowany, to dyrektywa #progma nie jest konieczna (zostanie zignorowana).
Jeżeli skrypt uruchamiający jest skompilowany, to w systemie nie musi być zainstalowany AutoIt, jednak uruchamiany skrypt musi mieć dostęp w swoim bieżącym folderze, do wszystkich UDF'ów dołączanych dyrektywą #include.
Przykład (skrypt uruchamiający):
#pragma compile(AutoItExecuteAllowed, True)
$sFile = "test.au3"
$iProcess = Run(@AutoItExe & ' /AutoIt3ExecuteScript "' & $sFile & '"')
Skrypt uruchamiany (plik ze skryptem uruchamianym musi mieć nazwę taką jaką podano w skrypcie uruchamiającym, w naszym przypadku jest to test.au3):
MsgBox(0,"","Działa!")
MsgBox(64,"","HURA!!!")