Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

AHK 1.1 OOP HowTo's


  • This topic is locked This topic is locked
4 replies to this topic
IsNull
  • Moderators
  • 990 posts
  • Last active: May 15 2014 11:56 AM
  • Joined: 10 May 2007

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 icon_razz.gif 

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



IsNull
  • Moderators
  • 990 posts
  • Last active: May 15 2014 11:56 AM
  • Joined: 10 May 2007

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()
   }
}


IsNull
  • Moderators
  • 990 posts
  • Last active: May 15 2014 11:56 AM
  • Joined: 10 May 2007

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


IsNull
  • Moderators
  • 990 posts
  • Last active: May 15 2014 11:56 AM
  • Joined: 10 May 2007

3.



IsNull
  • Moderators
  • 990 posts
  • Last active: May 15 2014 11:56 AM
  • Joined: 10 May 2007

4.