Classes in AHK, Basic tutorial.

Helpful script writing tricks and HowTo's
Pall Parker
Posts: 2
Joined: 24 Jul 2018, 09:34

Re: Classes in AHK, Basic tutorial.

24 Jul 2018, 09:40

Thanks for the tutorial!!!
Galaxis
Posts: 73
Joined: 04 Feb 2016, 20:09

Re: Classes in AHK, Basic tutorial.

30 Jul 2018, 15:34

classes remind me of ARRAYS
User avatar
Sabestian Caine
Posts: 550
Joined: 12 Apr 2015, 03:53

Re: Classes in AHK, Basic tutorial.

01 Jan 2019, 01:58

Great tutorial on Classes. :bravo: :bravo: :bravo:

But, still I am not getting how to use classes in simple stuffs?? :roll: :roll: :roll:
I don't normally code as I don't code normally.
Albireo
Posts: 1821
Joined: 16 Oct 2013, 13:53

Re: Classes in AHK, Basic tutorial.

27 Jan 2019, 03:44

Thank's!
I like the simplicity of the lesson of Class above.
I think even, that the description / comments is good when the complexity increases.

However, there are still parts that I do not understand. (eg. this.ID - is there more similar "variables" like this.?)
Searched in AHK help file but did not find anything.

Another thing that I didn't get to operate, as I desire, is the calculator. Wrong windows can be activated.
(for example, Explorer can become active instead of the Calculator - Maybe it is the programscript / Win 10 / Swedish version?)
How can I be sure that the right window is activated (Now it was so - most of time - but I just had luck?)
Perhaps the example had worked better if the instruction WinActivate had been supplemented with which window to be activated?.

Another problem that arose was when the Notepad were opened. Notepad were opened so quickly that it became a wrong header.
I solved this with the following code .:

Code: Select all

...
IfWinNotExist ahk_class Notepad
{	Run Notepad
	WinWait ahk_class Notepad
}
...
Finally, although the example does not handle problems, is it perhaps important?
If a code doesn't work as intended (for various reasons)
For example, if nothing happens, an error management can give tips on what went wrong?

I think the example shows that Class can add details that cannot be done otherwise (eg. __New)
Thanks again! :bravo:
User avatar
YoucefHam
Posts: 372
Joined: 24 Aug 2015, 12:56
Location: Algeria
Contact:

Re: Classes in AHK, Basic tutorial.

08 Jun 2019, 03:23

samardac wrote:
20 Jan 2015, 12:24
Thank You, :salute:

You make my life a lot easy, before I was just afraid when I see Class in any script, now because of you I am not.
Thank you. :thumbup: :thumbup: :thumbup:

I tried to practice on Class, here what I get, well just basic shooter game. :D

Code: Select all

;############################################################
;#======================= Commands =========================#
;############################################################ ;{
if Not A_IsAdmin AND A_OSVersion <> WIN_XP
{
	Run *RunAs "%A_ScriptFullPath%"
	ExitApp
}
Process, Priority,, High
SetWorkingDir %A_ScriptDir%
#NoEnv
#KeyHistory 0
SendMode Input
CoordMode, ToolTip, client
CoordMode, Mouse, client
CoordMode, Pixel, client
;}

;############################################################
;#======================= Initialise =======================#
;############################################################ ;{
i := 1
me := new Player

W1 := new Weapon, W1.setID("W" i++), W1.setName("M416"), W1.setFireMode(1)
				  W1.setClipSize(30), W1.setClipMagazine(30), W1.setAmmo(160)
				  W1.setFireRate(0.90)

W2 := new Weapon, W2.setID("W" i++), W2.setName("AK47"), W2.setFireMode(1)
				  W2.setClipSize(30), W2.setClipMagazine(30), W2.setAmmo(120)
				  W2.setFireRate(1.20)

W3 := new Weapon, W3.setID("W" i++), W3.setName("GLOCK"), W3.setFireMode(0)
				  W3.setClipSize(15), W3.setClipMagazine(15), W3.setAmmo(90)
				  W3.setFireRate(2.50)

me.setActiveWeapon(W1)
me.setFireMode(me.getActiveWeapon())
;}

;############################################################
;#====================== Main Window =======================#
;############################################################ ;{

Gui, Color, Black
Gui, Font, s10 cWhite q5, Verdana

Gui, Add, Picture, x522 y480 w-1 h90 vfmOSD, AUTO.png
Gui, Add, Picture, x200 y480 w-1 h90 vwOSD, M416.png

Gui, Add, GroupBox, x200 y405 w400 h50 vW, Weapons [1] [2] [3]
Gui, Add, Radio, x222 y429 vW1 gsetActiveWeapon Checked, M416
Gui, Add, Radio, x372 y429 vW2 gsetActiveWeapon, AK47
Gui, Add, Radio, x522 y429 vW3 gsetActiveWeapon, Glock

Gui, Add, GroupBox, x310 y350 w180 h50, Fire Mode [B]
Gui, Add, Radio, x322 y370 gChangeFireMode vFM1 Checked, Auto
Gui, Add, Radio, x412 y370 gChangeFireMode vFM0, Single

Gui, Font, s32 cGreen q5, Verdana
Gui, Add, Text, x200 y350 vClipMagazine, % me.getActiveWeapon().getClipSize()
Gui, Add, Text, x522 y350 vAmmo Right, % me.getActiveWeapon().getAmmo()

Gui, Show, w830 h615, Weapon Simulator
return
;}

;############################################################
;#======================== HotKeys =========================#
;############################################################ ;{
#IfWinActive, Weapon Simulator
;#####################################
*~LButton::
if (me.getActiveWeapon().getFireMode())
{
	Loop
	{
		me.FireWeapon(me.getActiveWeapon())
		Sleep, % (me.getActiveWeapon().getFireRate() * 100)
	}until !GetKeyState("LButton")
}
else
	me.FireWeapon(me.getActiveWeapon())
return
;#####################################
*$r::
me.ReloadWeapon(me.getActiveWeapon())
Sleep, % (me.getActiveWeapon().getFireRate() * 8)
return
;#####################################
*$VK31::
me.setActiveWeapon(W1)
me.setFireMode(me.getActiveWeapon())
return
;#####################################
*$VK32::
me.setActiveWeapon(W2)
me.setFireMode(me.getActiveWeapon())
return
;#####################################
*$VK33::
me.setActiveWeapon(W3)
me.setFireMode(me.getActiveWeapon())
return
;#####################################
*$x::
return
;#####################################
*$b::
me.ChangeFireMode(me.getActiveWeapon())
return
;#####################################
;}

;############################################################
;#======================= Functions ========================#
;############################################################ ;{
class Weapon {
	;~ static WeaponFireMode := 1, ID := W1, Name := "M416", ClipSize := 30, ClipMagazine := 30, Ammo := 160, FireRate := 0.02
	;#####################################
	getID() {
		return this.ID
	}
	setID(newID) {
		this.ID := newID
		return
	}
	;#####################################
	getName() {
		return this.Name
	}
	setName(Name) {
		this.Name := Name
		return
	}
	;#####################################
	getFireMode() {
		return this.WeaponFireMode
	}
	setFireMode(newWeaponFireMode) {
		this.WeaponFireMode := newWeaponFireMode
		return
	}
	;#####################################
	getClipSize() {
		return this.ClipSize
	}
	setClipSize(value) {
		this.ClipSize := value
		return
	}
	;#####################################
	getClipMagazine() {
		return this.ClipMagazine
	}
	setClipMagazine(value) {
		this.ClipMagazine := value
		return
	}
	;#####################################
	getAmmo() {
		return this.Ammo
	}
	setAmmo(value) {
		this.Ammo := value
		return
	}
	;#####################################
	getFireRate() {
		return this.FireRate
	}
	setFireRate(value) {
		this.FireRate := value
		return
	}
}

;#####################################
;#####################################
class Player {
	;~ static ActiveWeapon := W1, ActiveFireMode := 1, obj, ID
	;#####################################
	getID(ActiveWeapon) {
		return ActiveWeapon.getID()
	}
	;#####################################
	setActiveWeapon(ActiveWeapon) {
		this.ActiveWeapon := ActiveWeapon
		GuiControl,, % ActiveWeapon.getID(), 1
		GuiControl,, wOSD, % ActiveWeapon.getName() ".png"
		GuiControl,, ClipMagazine, % ActiveWeapon.getClipMagazine()
		GuiControl,, Ammo, % ActiveWeapon.getAmmo()
		return
	}
	getActiveWeapon() {
		return this.ActiveWeapon
	}
	;#####################################
	getFireMode() {
		return this.ActiveFireMode
	}
	setFireMode(ActiveWeapon) {
		this.ActiveFireMode := ActiveWeapon.getFireMode()
		GuiControl,, % "FM" ActiveWeapon.getFireMode(), 1
		GuiControl,, fmOSD, % (ActiveWeapon.getFireMode() ? "AUTO.png" : "SINGLE.PNG")
		return
	}
	ChangeFireMode(ActiveWeapon) {
		this.ActiveFireMode := ActiveWeapon.getFireMode()
		ActiveWeapon.setFireMode(!this.ActiveFireMode)
		GuiControl,, % "FM" !this.ActiveFireMode, 1
		GuiControl,, fmOSD, % (ActiveWeapon.getFireMode() ? "AUTO.png" : "SINGLE.PNG")
		return
	}
	;#####################################
	FireWeapon(ActiveWeapon) {
		if (ActiveWeapon.getClipMagazine() > 0)
		{
			ActiveWeapon.setClipMagazine(ActiveWeapon.getClipMagazine() - 1)
			GuiControl,, ClipMagazine, % ActiveWeapon.getClipMagazine()
		}
	}
	ReloadWeapon(ActiveWeapon) {
		Sleep, % ActiveWeapon.getFireRate() * 5
		if (ActiveWeapon.getAmmo() > 0)
		{
			dClip := ActiveWeapon.getClipSize() - ActiveWeapon.getClipMagazine()
			if (ActiveWeapon.getAmmo() - dClip > 0 )
			{
				ActiveWeapon.setAmmo(ActiveWeapon.getAmmo() - dClip)
				goto, Step1
			}
			else if (ActiveWeapon.getAmmo() - dClip = 0 )
			{
				ActiveWeapon.setAmmo(0)
				goto, Step1
			}
			else if (ActiveWeapon.getAmmo() - dClip < 0 )
				if (ActiveWeapon.getAmmo() >= 0 )
				{
					ActiveWeapon.setClipMagazine(ActiveWeapon.getClipMagazine()+ActiveWeapon.getAmmo())
					ActiveWeapon.setAmmo(0)
					GuiControl,, Ammo, % ActiveWeapon.getAmmo()
					Sleep, 320
					GuiControl,, ClipMagazine, % ActiveWeapon.getClipMagazine()
					return
				}
			return
			Step1:
			GuiControl,, Ammo, % ActiveWeapon.getAmmo()
			Sleep, 320
			ActiveWeapon.setClipMagazine(ActiveWeapon.getClipMagazine()+dClip)
			GuiControl,, ClipMagazine, % ActiveWeapon.getClipMagazine()
			return
		}
	}
	;#####################################
}
;#####################################
setActiveWeapon:
me.setActiveWeapon(%A_GuiControl%)
me.setFireMode(me.getActiveWeapon())
return
;#####################################
ChangeFireMode:
me.ChangeFireMode(me.getActiveWeapon())
return
;#####################################
GuiClose:
ExitApp
;##################################### ;}
Image

Script + Pictures:
Weapon Simulator.rar
Script + Pictures
(903.37 KiB) Downloaded 478 times
:wave: There is always more than one way to solve a problem. ;)
carno
Posts: 266
Joined: 20 Jun 2014, 16:48

Re: Classes in AHK, Basic tutorial.

08 Jan 2020, 18:05

This is a great tutorial to learn the Class in AHK. :)
thebbandit
Posts: 45
Joined: 02 Jul 2019, 11:34

Re: Classes in AHK, Basic tutorial.

26 Jan 2020, 00:16

Thank you for the time you put into this demonstration. It was very helpful.
LeSeb
Posts: 17
Joined: 25 Oct 2017, 14:50

Re: Classes in AHK, Basic tutorial.

30 Apr 2020, 08:14

jethrow wrote:
20 Jan 2015, 14:01
I wanted to make sure it is understood that a class is not only a plan (or blueprint) for an Instance, but the class is an object itself. See Keyword Prototype instead of Class for more discussion.

Code: Select all

class MyClass {
	SayHello() {
		MsgBox Hello
	}
}

MyClass.SayHello()
Hey,

If you do want to use the class (as the object that it is and not as a blueprint) then you will have to add the word static before each variable you add in the object.
Example : this will work :

Code: Select all

class note {
	static executable := "C:\Windows\notepad.exe"
	
	dire() {
		MsgBox % this.executable
	}
}

MsgBox % note.executable
this will not :

Code: Select all

class note {
	executable := "C:\Windows\notepad.exe"
	
	dire() {
		MsgBox % this.executable
	}
}

MsgBox % note.executable
ryandh94
Posts: 3
Joined: 19 Aug 2020, 21:13

Re: Classes in AHK, Basic tutorial.

28 Nov 2020, 07:24

so would this work? or am i thinking about it wrong?

Code: Select all

myclass
{
var1()
     {
        }
}

myotherclass
{
var1()
     {
        }
}
then to call it just got

myclass.var1()??
User avatar
Epialis
Posts: 858
Joined: 02 Aug 2020, 22:44

Re: Classes in AHK, Basic tutorial.

31 Dec 2020, 22:56

Great tutorial, thank you.
minhthanh91
Posts: 1
Joined: 22 Nov 2021, 08:31

Re: Classes in AHK, Basic tutorial.

22 Nov 2021, 08:41

when u want to call the constructor __New() of the mother-class: use base.__New() in child's:

Code: Select all

#SingleInstance force

;Declare Class
Class Window{
	__New(){
        this.task1 := "eat"
    }	
}

Class Notepad extends Window{
	__New(){	
		base.__New()
	}	
}

;Create Instance
SomeNote:= New Notepad
MsgBox, % SomeNote.task1 ;"eat"
return
:dance: thanks u very much
I leave something here for you all, for the reference:

Code: Select all

;Declare Class
Class A{
    food:="rice"
	__New(a,b){
        this.task1 := a
        this.task2 := b
    }	
    class C{
      drink1:="milk"
      static drink2:="coffe"
    }
}

Class B extends A{
	__New(c){	
		base.__New(c,c)
	}
    wannaEat()	{
        MsgBox, % this.food A_Space A.C.drink2
    }
}

;Create Instance
note:= New B("eat")
MsgBox, % note.task2 ;"eat"
note.wannaEat() ;"rice coffe"

MsgBox, % note.C.drink2 ;"coffe"
MsgBox, % A.C.drink2 ;"coffe" // u dont need to create an instance to use static property

wantToDrink:=new A.C
MsgBox, % wantToDrink.drink1 ;"milk"
return
I think the biggest benefit of using classes is that we can handle the method/function really good:

Code: Select all

#SingleInstance, force

Class B {
    __New(a){
        this.food:=a
    }
    wannaEat()	{
        MsgBox, % this.food
    }   
    saySomething(message)   {
        MsgBox, % message
    }    
}

Class A { 
    wannaEat()	{     ; use the same name of class B 
        MsgBox, % "this is class A"
    }  
    crossCall(){
        B.saySomething("this is class B") ; using class B's method
    }
}

B.wannaEat() ;""   // haven't call the constructor __NEW()

; create an instance
food := new B("rice")
food.wannaEat() ;"rice"

A.wannaEat() ;"this is class A"
A.crossCall() ;"this is class B"
Last edited by minhthanh91 on 23 Nov 2021, 03:01, edited 5 times in total.
User avatar
Joe Glines
Posts: 772
Joined: 30 Sep 2013, 20:49
Location: Dallas
Contact:

Re: Classes in AHK, Basic tutorial.

22 Nov 2021, 11:27

@DRocks I don't think you should use a class (if you don't need one). I've been using AutoHotkey for 10+ years and haven't written one (although when I stumble upon other people's I really struggle to use them) so that is why I'm wanting to learn them.

I think if you work with GUIs then they become very helpful!
Sign-up for the 🅰️HK Newsletter

ImageImageImageImage:clap:
AHK Tutorials:Web Scraping | | Webservice APIs | AHK and Excel | Chrome | RegEx | Functions
Training: AHK Webinars Courses on AutoHotkey :ugeek:
YouTube

:thumbup: Quick Access Popup, the powerful Windows folders, apps and documents launcher!
User avatar
Chunjee
Posts: 1589
Joined: 18 Apr 2014, 19:05
Contact:

Re: Classes in AHK, Basic tutorial.

08 Mar 2022, 22:02

Question: How can I add methods to a class without extending it?

Code: Select all

class example {
	static Var1 := 1
}
class example extends example {
	myCoolMethod() {

     }
}
; Error: Duplicate class definition.

Answer: create another class, add the classes together

Code: Select all

class example{
	static Var1 := 1
}
class example2 {
	myCoolMethod() {
		return this.Var1 * 100
	}
}

example.base := example2
msgbox, % example.myCoolMethod()
; => 100

better answers welcome
User avatar
lmstearn
Posts: 714
Joined: 11 Aug 2016, 02:32
Contact:

Re: Classes in AHK, Basic tutorial.

10 Mar 2022, 08:29

Hi Chunjee! :wave:
The first example works with a different class, it's a thing under current rules class can't extend itself. AFAIK. :)
Yeah, without extending it how do you get inheritance, there are ways- perhaps an idea here.

Code: Select all

class example {
	static Var1 := 1
}
class example1 extends example {
	myCoolMethod() {
	return this.Var1 * 100
	}
}
msgbox, % example1.myCoolMethod()
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH
User avatar
Chunjee
Posts: 1589
Joined: 18 Apr 2014, 19:05
Contact:

Re: Classes in AHK, Basic tutorial.

10 Mar 2022, 12:20

lmstearn wrote:
10 Mar 2022, 08:29

Code: Select all

msgbox, % example1.myCoolMethod()
Thank you for your time, sadly I want to add methods without changing the class name, like a "plugin" idea.
User avatar
lmstearn
Posts: 714
Joined: 11 Aug 2016, 02:32
Contact:

Re: Classes in AHK, Basic tutorial.

10 Mar 2022, 21:26

Ah, okay, might be possible one day with partial classes, mentioned for v2 back in the day, or with Namespaces as in this wish. :)
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH

Return to “Tutorials (v1)”

Who is online

Users browsing this forum: No registered users and 17 guests