Under Construction!
In diesem Thread geht es um AHK 1.1 Features und Beispiele wie man diese nutzt. Der Fokus liegt neben Arrays vorallem auf Objekten, und allem, was dazugehört.
Um hier Ordnung zu halten, ist der Thread gesperrt - aber bei Fragen/Kritik und natürlich auch bei Beiträgen die ihr hier reinstellen möchtet - eröffnet einfach einen neuen Thread oder schreibt mir eine PN. Egal wo ihr das macht, ich werds sicher sehen
Scite Editor für AHK 1.1
Fincs hat den Scite Editor für AHK_L schon sehr schön angepasst.
Installiere den aktuellsten Scite4AHK Editor, damit alle neuen Keywords richtig erkannt werden.
Inhalt
Grundlagen
Arrays
Klassen Syntax
Collections/Listen
Klassen - Vererbung und Polymorphismus
Für alle, die etwas tiefer in die Materie einsteigen wollen, kann ich nur folgendes E-Book empfehlen:
OOP - OpenBook Galileo
AHK 1.1 OOP HowTo's
OOP Grundlagen
Vorkenntnisse
Du solltest AHK einigermassen beherrschen, d.h. Funktionen, globale/lokale Variablen sollten dir nicht fremd sein. Grundsätzlich solltest du strukturiert programmieren können, wissen wann man Funktionen/Subs zur Code-Gliederung nutzt.
Objekt Orientierte Programmierung (OOP)
An der Stelle sei erstmal klargestellt, dass eine vollwertige Einführung in OOP weder hier gemacht werden kann, noch dass es angebracht wäre. Stattdessen picke ich einzelne Elemente aus OOP heraus, und versuche die Vorteile davon darzulegen.
Man kann bei den Möglichkeiten von AHK 1.1 auch nicht von einer OOP fähigen Sprache sprechen. Weiter hat AHK 1.1 im Unterbau den Style von Prototypisierter Objektorientierung, wurde aber im Release auf 1.1 mit Klassen basierter Syntax erweitert.
Allgemeine Einführung (nicht AHK bezogen)
OOP hat das Ziel, Code besser lesbar, erweiterbar, und wartbar zu machen. Grundsätzlich geht es darum, Zusammenhängede Daten und Methoden in einem Objekt zu sammeln, und gegen aussen möglichst wenig preiszugeben. Im alltäglichen Leben haben wir es mit einer Menge von Objekten zu tun, Objekte haben Eigenschaften und können gewisse Dinge tun - Ein Auto ist z.B. Rot, hat 4 Räder und kann die Scheiben hoch und runter lassen. - Wollen wir in Code nun mit Autos arbeiten, modelieren wir also aus der Realität ein Objekt, welches alle Eigenschaften und Funktionen hat, die wir benötigen.
Man definiert dazu mit Klassen, wie Objekte (Instanzen von Klassen) ausschauen, welche Daten sie enthalten und welche Methoden (Funktionalität) sie anbieten.
Objekte müssen aber nicht immer etwas sein, was es wirklich im Leben gibt. Häufig konstruiert man auch Klassen, die nicht / oder nur sehr abstrakt etwas mit der Wirklichkeit zu tun haben.
Erstmal ein kurzes Code-Snippet, damit du eine Vorstellung von einem Objekt bez. der Handhabung bekommst:
Folgender Code ist immer Pseudo-Code, d.h. nicht lauffähiger Code und auch Syntakitsch nicht übereinstimmend mit irgendeiner existierenden Sprache.
Ein Objekt ist durch Eigenschaften(= Properties -> Variablen) und Aktionen (= Methoden -> Funktionen) definiert. Diese Definition ist im Source Code in einer Klasse gehalten.
Im folgenden gehen wir davon aus, dass es eine Klasse 'Fenster' gibt. Ein Fenster Objekt repräsentiert ein Software Fenster (User Interface) - Objekte werden können also auch nicht reale Dinge darstellen.
Code
aktivesFenster := FindForeGroundWindow() ;// Gibt ein 'Fenster' Objekt zurück msgbox % aktivesFenster.Titel ;// Gibt den Titel des Fensters aus aktivesFenster.Minimize() ;// Minimiert das Fenster
Die Variable 'aktivesFenster' hällt eine Referenz auf eine Instanz der Fenster Klasse.
Ein Objekt (hier das Fenster) hat Daten. öffentlich sichbare Daten werden in public Feldern/Properties zugänglich gemacht. Das Property "Titel" ist ein Beispiel eines Feldes.
Ebenfalls hat unser Fenster Objekt Methoden, Minimize ist eine davon. Merke: Würden wir strukturiert programmieren, müssen wir der Funktion Minimize als Parameter angeben, welches Fenster. IM OOP-Design holen wir uns ein Objekt das ein Fenster repräsentiert und rufen dann für dieses Fenster die Methode Minimize auf. Der Aufruf bezieht sich damit auf eine Instanz unserer Fenster Klasse und eine Instanz repräsentiert genau ein Fenster.
Einer der Vorteile von OOP ist nun, dass wir Objekte vom gleichen typ auch gleich behandeln können: Nemen wir an, wir haben eine Liste von Fenstern, und wollen z.B. alle Titel davon in einen string schreiben und dann minimieren:
Code
titelSammlung := "" ;// unser string der alle Titel enthalten soll fensterList := GetWindowList() ;// gibt eine Liste von 'Fenster' Objekten zurück ;// geht die Liste durch, und stellt in jedem Loop-Durchgang das nächste Fenster Objekt in die Variable 'fenster' for each fenster in fensterList { titelSammlung .= fenster.Titel "`n" ;// Titel des aktuellen Fensters in string schreiben fenster.Minimize() ;// aktuelles Fenster minimieren }
Ein Fenster ist ein Fenster, und daher ist es uns egal welches es denn nun genau ist. Jedes Fenster hat die Eigenschaft 'Titel' und die Methode 'Minimize()'.
Eine Frage - die du dir vielleich gerade stellst - woher kommt eigentlich das 'Fenster'. Fenster ist der Name des Objektes, der Klasse. Man schreibt anstatt eine Funktionsbibliotek Klassen-Definitionen. Und in den Klassen definiert man dann die Eigenschaften/Methoden; unsere Fenster-Klasse würde ca so aussehen, wenn man sie als AHK Wrapper sieht -
Code
class Fenster { Title := "" ;// Eigenschaft Titel ;// Methode Minimize um das Fenster zu minimieren Minimize(){ WinMinimize, % this.Title } }
Ich empfehle nun, den Wiki Artikel hier zu überfliegen - http://de.wikipedia...._Programmierung
OOP und AHK 1.1
Wie man das ganze nun verwenden kann, zeigt folgendes Skript:
Car Objekt Demo
Code
/*************************************************** Definiert unser Objekt Car ************************************************ */ class Car { ; Klassen Felder Name := "" Number := "" ;Methoden ToString(){ return "Car: " . this.Name . "`nNumber: " this.Number } ;// erstellt eine neue Instanz vom Car Objekt ;// durch klonen/prototypen des original Car Objektes __New(myname, mynumber){ this.Name := myname this.Number := mynumber } } ;************************************************* ;// Erstellen von 3 Instanzen bmw := new Car("BMW", "27346") audi := new Car("Audi", "62316") mercedes := new Car("Mercedes", "895762") ;// Liste die alle unsere Cars enthällt cars := [bmw, audi, mercedes] ShowCars(cars) return /* Diese Methode zeigt alle Cars an, es ist ihr vollkommen egal, wie die variabeln heissen wo car überall referenziert ist. */ ShowCars(mycars){ for each, car in mycars { MsgBox % car.ToString() } }
Arrays
Arrays sind spezielle Variablen Container, also eine Ansammlung/Liste von Felder. Das Konzept dieser Mehrdimensionalen Variablen ist in allen Programmiersprachen ähnlich, hier kann man sich die Details dazu anschauen.
AHK_L / 1.1 bietet echte Arrays, eigentlich sind es schon eher Collections/Listen. Ich werde in diesem Post das wichtigste hervorheben.
Original Help findet man hier: Arrays
Arrays definieren
Arrays sind in AHK Objekte. D.h. um einen Array nutzen zu können, muss man zunächst einen Array erstellen/definieren.
Leeren Array erstellen
myArray := []
Array mit Elementen erstellen
myArray := ["Apfel", "Birne", 350, "Haus"]
Die Arrays in AHK sind nicht so strikte wie man sie in anderen Sprachen kennt. Wird auf einen Index zugegriffen, der nicht existiert, wird er erstellt:
myArray := [] myArray[1] := "Hello World" ;// An Stelle (Index) 1 wird "Hello World" gesetzt
Auf Arrays zugreifen
Index
(Der Index fängt bei 1 an!)
msgbox % myArr[1] ;// Element an erster Stelle zurückgeben myArr[2] := "new value" ;// stellt einen neuen String in das zweite Element, wenn der Index 2 noch nicht existiert, wird er erstellt.
for each Loop
Sehr häufig will man eine "Aktion" mit jedem Element in einem Array durchführen: Alle Elemente anzeigen, alle Element speichern etc.
for each, item in myArray { MsgBox % item }
Ein For each Schlaufe geht jedes Element im Array durch. Das "each" gehärt nicht zur syntax und ist eine Variable, welche mit dem aktuellen Key/Index des aktuellen Elementes gefällt wird.
Beispiel
myarr := ["Apfel", 200, "Birne"] myarr[4] := "Haus" myarr[5] := 550 MsgBox % "Im Array befinden sich " myarr.MaxIndex() " Elemente" for each, item in myarr { MsgBox % item } exitapp
3.
4.