1

Тема: AHK: классы

Здравствуйте. Дело в том, что класс выполняется сразу после запуска скрипта, даже если перед ним есть еще код. В интернете не смог найти информации на русском о работе с классами в ahk. Нужно чтобы до класса, выполнялся другой код. Пробовал добавить код в сам класс, работает, но все таки это не то что мне нужно. Можно ли как-то поменять приоритет? Чтобы код запускался в нужном мне порядке? ( сначала msgbox, 1 и после него только класс). Спасибо.


msgbox, 1
class DD extends DD_Helper
{
	; Simulate mouse button press
	; param:   1 = LButton Down,    2 = LButton Up
	;          4 = RButton Down,    8 = RButton Up
	;         16 = MButton Down,   32 = MButton Up
	;         64 = Button 4 Down, 128 = Button 4 Up
	;        256 = Button 5 Down, 512 = Button 5 Up
	btn(param) {
		return DllCall(this.dllFile "\DD_btn", "int", param)
	}

	; Simulate mouse move
	mov(x, y) {
		return DllCall(this.dllFile "\DD_mov", "int", x, "int", y)
	}

	; Simulate mouse move (relatively)
	movR(dx, dy) {
		return DllCall(this.dllFile "\DD_movR", "int", dx, "int", dy)
	}

	; Simulate mouse wheel
	; param: 1=upward 2=downward
	whl(param) {
		return DllCall(this.dllFile "\DD_whl", "int", param)
	}

	; Simulate keyboard
	; param1: DD code
	; param2: 1=Down 2=Up
	key(param1, param2) {
		return DllCall(this.dllFile "\DD_key", "int", param1, "int", param2)
	}

	; VKCode to DD code
	todc(VKCode) {
		return DllCall(this.dllFile "\DD_todc", "int", VKCode)
	}

	; Send string
	str(string) {
		return DllCall(this.dllFile "\DD_str", "astr", string)
	}

	; Get hwnd of active window
	GetActiveWindow() {
		; return DllCall(this.dllFile "\DD_GetActiveWindow", "ptr") ; seems not working
		return WinExist("A")
	}

	MouseMove(hwnd, x, y) {
		return DllCall(this.dllFile "\DD_MouseMove", "ptr", hwnd, "int", x, "int", y)
	}

	; The picture is saved to "C:\DD Snap\" folder
	SnapPic(hwnd, x, y, w, h) {
		return DllCall(this.dllFile "\DD_SnapPic", "ptr", hwnd, "int", x, "int", y, "int", w, "int", h)
	}

	PickColor(hwnd, x, y, mode=2) {
		return DllCall(this.dllFile "\DD_PickColor", "ptr", hwnd, "int", x, "int", y, "int", mode)
	}
}

class DD_Helper
{
	static _ := DD_Helper.InitClass()

	InitClass() {
		if !A_IsAdmin {
			Run *RunAs "%A_ScriptFullPath%"  ; Requires v1.0.92.01+
			ExitApp
		}
		this.LoadDll()
	}

	LoadDll() {                    
		if A_Is64bitOS {
			dllFile := (A_PtrSize=8) ? "ddx64.64.dll" : "ddx64.32.dll"
		} else {
			dllFile := "ddx32.dll"
		}
		if !this.hModule := DllCall("LoadLibrary", "Str", dllFile, "Ptr") {
			if !FileExist(dllFile) {
				msgbox,0x40030, , dllFile " not found."
				ExitApp
			}
			msgbox,0x40030, , "LoadLibrary failed. DllFile is " dllFile
			ExitApp
		}
		this.dllFile := dllFile
	}

	UnloadDll() {
		DllCall("FreeLibrary", "Ptr", this.hModule)
	}
	
	; Example: _btn("RButtonDown")
	_btn(sNick, x:="", y:="") {
		static oNick := { LButtonDown: 1, LButtonUp: 2
		                , RButtonDown: 4, RButtonUp: 8
		                , MButtonDown: 16, MButtonUp: 32
		                , 4ButtonDown: 64, 4ButtonUp: 128
		                , 5ButtonDown: 256, 5ButtonUp: 512 }
		if !( n := oNick[sNick] ) {
			msgbox, sNick " is not a valid nick."
		}
		if (x != "") {
			this.mov(x, y)
		}
		this.btn(n)
	}

	; Example: _btn_press("RButton")
	_btn_press(sNick, x:="", y:="", nCount:=1) {
		static oNick := { LButton: {Down: 1, Up: 2}
		                , RButton: {Down: 4, Up: 8}
		                , MButton: {Down: 16, Up: 32}
		                , 4Button: {Down: 64, Up: 128}
		                , 5Button: {Down: 256, Up: 512} }
		if !( o := oNick[sNick] ) {
			msgbox, sNick " is not a valid nick."
		}
		if (x != "") {
			this.mov(x, y)
		}
		Loop, % nCount {
			this.btn( o.Down )
			this.btn( o.Up )
			Sleep, 5
		}
	}

	; Example: _key("F11", "Down")
	;          _key("F11", "Up")
	_key(sKey, sflag) {
		ddCode := this.todc( GetKeyVK(sKey) )
		this.key(ddCode, (sflag="Up") ? 2 : 1 )
	}

	; Example: _key_press("F11")
	;          _key_press("Ctrl", "A")
	_key_press(sKey*) {
		arr_ddCode := []

		for i, k in sKey {
			arr_ddCode[i] := this.todc( GetKeyVK(k) )
			this.key(arr_ddCode[i], 1) ; Down
		}
		for i, ddCode in arr_ddCode {
			this.key(ddCode, 2) ; Up
		}
	}

	_key_pressEx(sKey, nCount := 1) {
		ddCode := this.todc( GetKeyVK(sKey) )

		Loop, % nCount {
			this.key(ddCode, 1) ; Down
			this.key(ddCode, 2) ; Up
		}
	}

	; Example: _whl("down")
	;          _whl("up")
	_whl(sParam) {
		this.whl( (sParam="Up") ? 1 : 2 )
	}
}

2 (изменено: MandarinKa02, 2017-12-21 19:43:32)

Re: AHK: классы

return?

msgbox, 1
return
class DD extends DD_Helper
{
...
}

3

Re: AHK: классы

MandarinKa02
Как его здесь правильно применить ?

4

Re: AHK: классы

Так попробуйте:


msgbox, 1
DD_Helper.InitClass()
class DD extends DD_Helper
{
   ; Simulate mouse button press
   ; param:   1 = LButton Down,    2 = LButton Up
   ;          4 = RButton Down,    8 = RButton Up
   ;         16 = MButton Down,   32 = MButton Up
   ;         64 = Button 4 Down, 128 = Button 4 Up
   ;        256 = Button 5 Down, 512 = Button 5 Up
   btn(param) {
      return DllCall(this.dllFile "\DD_btn", "int", param)
   }

   ; Simulate mouse move
   mov(x, y) {
      return DllCall(this.dllFile "\DD_mov", "int", x, "int", y)
   }

   ; Simulate mouse move (relatively)
   movR(dx, dy) {
      return DllCall(this.dllFile "\DD_movR", "int", dx, "int", dy)
   }

   ; Simulate mouse wheel
   ; param: 1=upward 2=downward
   whl(param) {
      return DllCall(this.dllFile "\DD_whl", "int", param)
   }

   ; Simulate keyboard
   ; param1: DD code
   ; param2: 1=Down 2=Up
   key(param1, param2) {
      return DllCall(this.dllFile "\DD_key", "int", param1, "int", param2)
   }

   ; VKCode to DD code
   todc(VKCode) {
      return DllCall(this.dllFile "\DD_todc", "int", VKCode)
   }

   ; Send string
   str(string) {
      return DllCall(this.dllFile "\DD_str", "astr", string)
   }

   ; Get hwnd of active window
   GetActiveWindow() {
      ; return DllCall(this.dllFile "\DD_GetActiveWindow", "ptr") ; seems not working
      return WinExist("A")
   }

   MouseMove(hwnd, x, y) {
      return DllCall(this.dllFile "\DD_MouseMove", "ptr", hwnd, "int", x, "int", y)
   }

   ; The picture is saved to "C:\DD Snap\" folder
   SnapPic(hwnd, x, y, w, h) {
      return DllCall(this.dllFile "\DD_SnapPic", "ptr", hwnd, "int", x, "int", y, "int", w, "int", h)
   }

   PickColor(hwnd, x, y, mode=2) {
      return DllCall(this.dllFile "\DD_PickColor", "ptr", hwnd, "int", x, "int", y, "int", mode)
   }
}

class DD_Helper
{
   InitClass() {
      if !A_IsAdmin {
         Run *RunAs "%A_ScriptFullPath%"  ; Requires v1.0.92.01+
         ExitApp
      }
      this.LoadDll()
   }

   LoadDll() {                    
      if A_Is64bitOS {
         dllFile := (A_PtrSize=8) ? "ddx64.64.dll" : "ddx64.32.dll"
      } else {
         dllFile := "ddx32.dll"
      }
      if !this.hModule := DllCall("LoadLibrary", "Str", dllFile, "Ptr") {
         if !FileExist(dllFile) {
            msgbox,0x40030, , dllFile " not found."
            ExitApp
         }
         msgbox,0x40030, , "LoadLibrary failed. DllFile is " dllFile
         ExitApp
      }
      this.dllFile := dllFile
   }

   UnloadDll() {
      DllCall("FreeLibrary", "Ptr", this.hModule)
   }
   
   ; Example: _btn("RButtonDown")
   _btn(sNick, x:="", y:="") {
      static oNick := { LButtonDown: 1, LButtonUp: 2
                      , RButtonDown: 4, RButtonUp: 8
                      , MButtonDown: 16, MButtonUp: 32
                      , 4ButtonDown: 64, 4ButtonUp: 128
                      , 5ButtonDown: 256, 5ButtonUp: 512 }
      if !( n := oNick[sNick] ) {
         msgbox, sNick " is not a valid nick."
      }
      if (x != "") {
         this.mov(x, y)
      }
      this.btn(n)
   }

   ; Example: _btn_press("RButton")
   _btn_press(sNick, x:="", y:="", nCount:=1) {
      static oNick := { LButton: {Down: 1, Up: 2}
                      , RButton: {Down: 4, Up: 8}
                      , MButton: {Down: 16, Up: 32}
                      , 4Button: {Down: 64, Up: 128}
                      , 5Button: {Down: 256, Up: 512} }
      if !( o := oNick[sNick] ) {
         msgbox, sNick " is not a valid nick."
      }
      if (x != "") {
         this.mov(x, y)
      }
      Loop, % nCount {
         this.btn( o.Down )
         this.btn( o.Up )
         Sleep, 5
      }
   }

   ; Example: _key("F11", "Down")
   ;          _key("F11", "Up")
   _key(sKey, sflag) {
      ddCode := this.todc( GetKeyVK(sKey) )
      this.key(ddCode, (sflag="Up") ? 2 : 1 )
   }

   ; Example: _key_press("F11")
   ;          _key_press("Ctrl", "A")
   _key_press(sKey*) {
      arr_ddCode := []

      for i, k in sKey {
         arr_ddCode[i] := this.todc( GetKeyVK(k) )
         this.key(arr_ddCode[i], 1) ; Down
      }
      for i, ddCode in arr_ddCode {
         this.key(ddCode, 2) ; Up
      }
   }

   _key_pressEx(sKey, nCount := 1) {
      ddCode := this.todc( GetKeyVK(sKey) )

      Loop, % nCount {
         this.key(ddCode, 1) ; Down
         this.key(ddCode, 2) ; Up
      }
   }

   ; Example: _whl("down")
   ;          _whl("up")
   _whl(sParam) {
      this.whl( (sParam="Up") ? 1 : 2 )
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5

Re: AHK: классы

teadrinker
Спасибо. Можете объяснить как это работает? И не будет ли сбоев работы скрипта из-за того, что убрана строка ?

static _ := DD_Helper.InitClass()

6 (изменено: teadrinker, 2017-08-14 16:51:31)

Re: AHK: классы

powercat пишет:

как это работает

static-переменные инициализируются сразу после загрузки скрипта, до запуска секции автовыполнения. Здесь чтобы инициализировать вспомогательную переменную «_» должен выполниться метод DD_Helper.InitClass(). Это просто такая уловка, чтобы запустить какой-то код перед секцией автовыполнения.

powercat пишет:

И не будет ли сбоев работы скрипта из-за того, что убрана строка

Не должно быть, если перед обращением к классу будет выполнено

DD_Helper.InitClass()

но протестировать не могу.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7

Re: AHK: классы

teadrinker, благодарю за информацию. Все работает.

8 (изменено: serzh82saratov, 2017-08-25 19:37:16)

Re: AHK: классы

То ли забыл, то ли не знал. Нужен массив одинаковый для всех экземпляров, но чтобы в имени не было ClassName. Также чтобы по имени внутри методов можно было к нему обращатся. Само собой не глобальный.


m1 := new ClassName(111)
m2 := new ClassName(222)
; m2.Del()

MsgBox % m1.arr "`n" m2.arr "`n`n" ClassName.Get()

Class ClassName
{
    __New(p)
    {
        ClassName.Arr := p 
    } 
	Del()
    {
		ClassName.Arr := ""
    }
	Get()
    {
		Return ClassName.Arr
    }  
}

This не подходит.


m1 := new ClassName(111)
m2 := new ClassName(222)
; m2.Del()

MsgBox % m1.arr "`n" m2.arr 

Class ClassName
{
    __New(p)
    {
        this.Arr := p 
    } 
	Del()
    {
		this.Arr := ""
    } 
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

9

Re: AHK: классы

По-моему, логичней такой подход:

ClassName.arr := 123
m1 := new ClassName(456)
m2 := new ClassName(789)
m3 := new ClassName

MsgBox % m1.arr "`n" m2.arr "`n" m3.arr

Class ClassName
{
   __New(p)
   {
      this.arr := p
   } 
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

10

Re: AHK: классы

Логичнее для чего? В "This не подходит" тоже самое.
Нужен именно один массив для всех экземпляров.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

11

Re: AHK: классы

serzh82saratov пишет:

Нужен именно один массив для всех экземпляров.

Так задай для него отдельное имя. Смысл создания объектов через new как раз заключается в том, чтобы они были независимые.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

12

Re: AHK: классы

Так в том и вопрос, как его задать?

serzh82saratov пишет:

Нужен массив одинаковый для всех экземпляров, но чтобы в имени не было ClassName.

У меня получается, только если задать его как имя самого класса, а хочется своё название.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

13 (изменено: serzh82saratov, 2017-08-28 14:57:01)

Re: AHK: классы

Вот я приводил пример, __New тут только для назначения значений ключу.

m1 := new ClassName(111)
m2 := new ClassName(222)
; m2.Del()

MsgBox % m1.arr "`n" m2.arr "`n`n" ClassName.Get()

Class ClassName
{
    __New(p)
    {
        ClassName.Arr := p 
    } 
	Del()
    {
		ClassName.Arr := ""
    }
	Get()
    {
		Return ClassName.Arr
    }  
}

Как тут ClassName.Arr переименовать в MyClassName.Arr?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

14 (изменено: teadrinker, 2017-08-28 15:44:59)

Re: AHK: классы

serzh82saratov пишет:

Нужен массив одинаковый для всех экземпляров

ClassName.arr := 123
m1 := new ClassName
m2 := new ClassName

MsgBox % m1.arr "`n" m2.arr

Class ClassName
{ 
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

15

Re: AHK: классы

Не понял тебя, имя тоже самое, и объявление массива требуется в теле класса,  а не из вне.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

16

Re: AHK: классы

А зачем?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

17

Re: AHK: классы

Ну ок, так:

arr := []
m1 := new ClassName(arr, "")
m2 := new ClassName(arr, "Привет!")

MsgBox % m1.arr[1] "`n" m2.arr[1]

Class ClassName
{
   __New(arr, key)
   {
      arr[1] := key
      this.arr := arr
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

18

Re: AHK: классы

Или так:

m1 := new ClassName("Привет!")
m2 := new ClassName("Пока!")

MsgBox % m1.arr[1] "`n" m2.arr[1]

Class ClassName
{
   static arr := []
   __New(key)
   {
      this.arr[1] := key
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

19 (изменено: serzh82saratov, 2017-08-28 17:49:00)

Re: AHK: классы

Как тогда в таком случае по нажатию кнопки получить значение?

m1 := new ClassName("Привет!")
m2 := new ClassName("Пока!")
ToolTip % m1.arr[1] "`n" m2.arr[1]
Return

Class ClassName
{
	static arr := []
	__New(key)
	{
		Gui, Add, Button, Border x1 y1 gClassName.get, Button 
		Gui, Show
		this.arr[1] := key
	}
	get() {
		MsgBox % this.arr[1] 
	}
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

20

Re: AHK: классы

Использовать

GuiControl +g, ControlID, %FuncObj%
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

21

Re: AHK: классы

Ты это имеешь ввиду, и одновременно на это ответил.

m1 := new ClassName("Привет!")
m2 := new ClassName("Пока!") 
ToolTip % m1.arr[1] "`n" m2.arr[1]
Return

Class ClassName
{
	static arr := []
	__New(key) { 
		obj := ObjBindMethod(This, "get")
		Gui, Add, Button, Border x1 y1 hwndhButton, Button 
		GuiControl +g, %hButton%, %obj%
		Gui, Show
		this.arr[1] := key
	}
	get() {
		MsgBox % this.arr[1] 
	}
}

Ок, а как по OnMessage получить?

m1 := new ClassName("Привет!")
m2 := new ClassName("Пока!") 
ToolTip % m1.arr[1] "`n" m2.arr[1]
Return

Class ClassName
{
	static arr := []
	__New(key) {
		OnMessage(WM_LBUTTONDOWN := 0x201, this.OnButtonDown.Bind(""))
		Gui, Show, w222 h222
		this.arr[1] := key
	}
	OnButtonDown(wp, lp, msg, hwnd) {
		MsgBox % this.arr[1]
	}
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

22

Re: AHK: классы

m1 := new ClassName("Привет!")
m2 := new ClassName("Пока!") 
ToolTip % m1.arr[1] "`n" m2.arr[1]
Return

Class ClassName
{
   static arr := []
   __New(key) {
      OnMessage(WM_LBUTTONDOWN := 0x201, this.OnButtonDown.Bind(this))
      Gui, Show, w222 h222
      this.arr[1] := key
   }
   OnButtonDown(wp, lp, msg, hwnd) {
      MsgBox % this.arr[1]
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

23

Re: AHK: классы

Убедил.
Кстати почему вызывается 2 раза, и почему надо что то биндить, иначе первым идёт не wp а lp?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

24

Re: AHK: классы

serzh82saratov пишет:

Кстати почему вызывается 2 раза

Так создаются же два объекта, соответственно OnMessage() вызывается 2 раза, а в этом случае должна срабатывать функция каждого из них.

serzh82saratov пишет:

почему надо что то биндить

В статье SetTimer это объясняется, но даже лучше использовать ObjBindMethod, там ещё понятнее объяснено.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

25

Re: AHK: классы

В SetTimer после переводчика ничего не понял, а в ObjBindMethod даже не нашёл что переводить.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

26 (изменено: serzh82saratov, 2017-08-29 02:43:48)

Re: AHK: классы

serzh82saratov пишет:

Так создаются же два объекта, соответственно OnMessage() вызывается 2 раза, а в этом случае должна срабатывать функция каждого из них.

Так нехорошо, а если в WM_LBUTTONDOWN нужна будет одиночная обработка?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

27

Re: AHK: классы

Class ClassName
{
   static arr := []
   __New(key) {
      OnMessage(WM_LBUTTONDOWN := 0x201, ObjBindMethod(this, "OnButtonDown"))
      Gui, Show, w222 h222
      this.arr[1] := key
   }
   OnButtonDown(wp, lp, msg, hwnd) {
      MsgBox % this.arr[1]
   }
}

Creates a BoundFunc object which calls a method of a given object.

BoundFunc := ObjBindMethod(Obj, Method, Params)

Создаёт BoundFunc объект который вызывает метод данного объекта.
В данном случае объект (Obj) — это this, Method — это OnButtonDown, Params — привязанные параметры, их у нас нет, но можно привязать, в этом случае они будут идти перед основными параметрами wp, lp, msg, hwnd:

m1 := new ClassName("Привет!")
m2 := new ClassName("Пока!") 
ToolTip % m1.arr[1] "`n" m2.arr[1]
Return

Class ClassName
{
   static arr := []
   __New(key) {
      OnMessage(WM_LBUTTONDOWN := 0x201, ObjBindMethod(this, "OnButtonDown", MyParam := "Hello!"))
      Gui, Show, w222 h222
      this.arr[1] := key
   }
   OnButtonDown(param, wp, lp, msg, hwnd) {
      MsgBox % param "`n" this.arr[1]
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

28 (изменено: serzh82saratov, 2017-08-29 03:10:48)

Re: AHK: классы

Ну про ObjBindMethod понятно, я не пойму когда без него, что происходит. Или ну его, ObjBindMethod просто писать...

Про выключение множественных сообщений, вижу только такой костыль:


m1 := new ClassName("Привет!")
m2 := new ClassName("Пока!") 
ToolTip % m1.arr[1] "`n" m2.arr[1]
Return

Class ClassName
{
   static arr := []
   __New(key) {
		static Start
		If !Start
			Class := This.__Class, Start := 1
			, OnMessage(WM_LBUTTONDOWN := 0x201, ObjBindMethod(%Class%, "OnButtonDown"))
		Gui, Show, w222 h222
		this.arr[1] := key
   }
   OnButtonDown(wp, lp, msg, hwnd) {
		MsgBox % this.arr[1]
   }
}

На случай если будет вопрос, почему %Class% а не This.

+ открыть спойлер

m1 := new ClassName("Привет!")
m2 := new ClassName("Пока!") 
m1.Destroy()
ToolTip % m1.arr[1] "`n" m2.arr[1]
Return

Class ClassName
{
   static arr := []
   __New(key) {
		static Start
		If !Start
			Start := 1
			, OnMessage(WM_LBUTTONDOWN := 0x201, ObjBindMethod(This, "OnButtonDown"))
		Gui, Show, w222 h222
		this.arr[1] := key
   }
   OnButtonDown(wp, lp, msg, hwnd) {
		MsgBox % this.arr[1]
   }
   	Destroy() {   
		This.Base := ""
	}
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

29

Re: AHK: классы

serzh82saratov пишет:

Про выключение множественных сообщений, вижу только такой костыль

Опять ты пытаешься вместо предоставленного удобного интерфейса навязать свой. Я ж говорю, должно срабатывать два раза, поскольку ты два раза вызываешь OnMessage(). В твоём примере OnMessage() срабатывает только от первого объекта:


m1 := new ClassName("Привет!", "Hello")
m2 := new ClassName("Пока!", "Hi") 
ToolTip % m1.arr[1] "`n" m2.arr[1]
Return

Class ClassName
{
   static arr := []
   __New(key, param) {
      static Start
      If !Start
         Class := This.__Class, Start := 1
         , OnMessage(WM_LBUTTONDOWN := 0x201, ObjBindMethod(%Class%, "OnButtonDown", param))
      Gui, Show, w222 h222
      this.arr[1] := key
   }
   OnButtonDown(param, wp, lp, msg, hwnd) {
      MsgBox % param "`n" this.arr[1]
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

30

Re: AHK: классы

На примере часов из коллекции, зачем мне 10 сообщений по факту одного клика?
Что мне даст перебор всех экземпляров, если мне только интересно по какому элементу кликнули.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

31

Re: AHK: классы

serzh82saratov пишет:

На случай если будет вопрос, почему %Class% а не This.


m1 := new ClassName("Привет!")
m2 := new ClassName("Пока!") 
m1.Destroy()
ToolTip % m1.arr[1] "`n" m2.arr[1]
Return

Class ClassName
{
   static arr := [], Start
   __New(key) {
      If !Start
         Start := 1
         , OnMessage(WM_LBUTTONDOWN := 0x201, ObjBindMethod(This, "OnButtonDown"))
      Gui, Show, w222 h222
      this.arr[1] := key
   }
   OnButtonDown(wp, lp, msg, hwnd) {
      MsgBox % this.arr[1]
   }
      Destroy() {   
      This.Base := ""
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

32

Re: AHK: классы

serzh82saratov пишет:

Что мне даст перебор всех экземпляров, если мне только интересно по какому элементу кликнули.

Так сообщение получит только первый объект.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

33

Re: AHK: классы

А, нет, предыдущее неправильно.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

34 (изменено: serzh82saratov, 2017-08-29 03:26:15)

Re: AHK: классы

31 пост, ты видимо ошибся, у тебя OnMessage 2 раза вызывается.

teadrinker пишет:

Так сообщение получит только первый объект.

Какой такой объект?


m1 := new ClassName("Привет!",222)
m2 := new ClassName("Пока!",555) 
 
ToolTip % m1.arr[1] "`n" m2.arr[1]
Return

Class ClassName
{
   static arr := [], Start
   __New(key,x) { 
      If !Start
         Start := 1
         , OnMessage(WM_LBUTTONDOWN := 0x201, ObjBindMethod(This, "OnButtonDown"))
	Gui, New
      Gui, Show, w222 h222 x%x%
      this.arr[1] := key
   }
   OnButtonDown(wp, lp, msg, hwnd) {
      MsgBox % this.arr[1]
   }
      Destroy() {   
      This.Base := ""
   }
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

35

Re: AHK: классы

Там 2 окна, я поправил, ато не очевидно было.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

36

Re: AHK: классы

Так правильно:


m1 := new ClassName("Привет!")
m2 := new ClassName("Пока!")
Hotkey, F10, Label, On
Return

Label:
   MsgBox, % "m1.Clicked = " m1.Clicked "`nm2.Clicked = " m2.Clicked
   Return

Class ClassName
{
   static arr := [], Start := []
   __New(key) {
      If this.Start[1] != 1
         this.Start[1] := 1
         , OnMessage(WM_LBUTTONDOWN := 0x201, ObjBindMethod(This, "OnButtonDown"))
      Gui, Show, w222 h222
      this.arr[1] := key
   }
   OnButtonDown(wp, lp, msg, hwnd) {
      SoundBeep
      this.Clicked := true
   }
}
serzh82saratov пишет:

Какой такой объект?

Кликни по окну и нажми F10, будет понятно.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

37

Re: AHK: классы

Не пойму твой посыл. И заморочку с this.Start[1] != 1, чем просто static Start в методе не торт?

Так что это даёт, и что показывает? Мне нужны клики в окнах, в 28 под спойлером наглядно, также и в твоём, я m1 удалю, и кликов вообще не станет.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

38

Re: AHK: классы

serzh82saratov пишет:

Так что это даёт, и что показывает?

То, что сообщение будет получать только один объект.

serzh82saratov пишет:

Мне нужны клики в окнах

Если объектов много, то о том, что клик был, узнает только первый объект. Если просто нужна одна реакция на клик, то функцию клика логичнее вынести за пределы класса.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

39

Re: AHK: классы


m1 := new ClassName("Привет!")
m2 := new ClassName("Пока!") 
m1.Destroy()
ToolTip % m1.arr[1] "`n" m2.arr[1]
Return

Class ClassName
{
   static arr := [], var := OnMessage(WM_LBUTTONDOWN := 0x201, "OnButtonDown")
   __New(key) {
      Gui, Show, w222 h222
      this.arr[1] := key
   }
   OnButtonDown(wp, lp, msg, hwnd) {
      MsgBox % this.arr[1]
   }
      Destroy() {   
      This.Base := ""
   }
}

OnButtonDown()  {
   SoundBeep
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

40

Re: AHK: классы

teadrinker пишет:

То, что сообщение будет получать только один объект.

Так если я потом этот объект (экземпляр) удалю, я сообщения перестану получать.

Если объектов много, то о том, что клик был, узнает только первый объект. Если просто нужна одна реакция на клик, то функцию клика логичнее вынести за пределы класса.

Почему логичнее, если решение теперь есть. Если пишешь класс, то как то не по фен шую что то выводить за его пределы.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

41

Re: AHK: классы

Тогда пусто.

m1 := new ClassName("Привет!")
m2 := new ClassName("Пока!") 
m1.Destroy()
ToolTip % m1.arr[1] "`n" m2.arr[1]
Return

Class ClassName
{
   static arr := [], var := OnMessage(WM_LBUTTONDOWN := 0x201, "OnButtonDown")
   __New(key) {
      Gui, Show, w222 h222
      this.arr[1] := key
   }
   OnButtonDown(wp, lp, msg, hwnd) {
      MsgBox % this.arr[1]
   }
      Destroy() {   
      This.Base := ""
   }
}

OnButtonDown()  {
   MsgBox % this.arr[1]
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

42

Re: AHK: классы

serzh82saratov пишет:

Так если я потом этот объект (экземпляр) удалю, я сообщения перестану получать.

Этого не понял, зачем тогда вообще его создавать?

serzh82saratov пишет:

Если пишешь класс, то как то не по фен шую что то выводить за его пределы

Нет, внутри конструктора имеет смысл писать то, что будет иметь отношение ко всем экземплярам объектов. Вообще в принципе нелогично писать внутри метода __New

Gui, Show, w222 h222

если в реальности нужно только одно окно, а объектов может быть много. Получается, что команда Show выполняется всякий раз, как создаётся новый объект. А какой в этом смысл?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

43

Re: AHK: классы

serzh82saratov пишет:

Тогда пусто.

Ну так а откуда в функции за пределами класса возьмётся this?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

44

Re: AHK: классы

Я тебе пытался привести как пример часы. В моём случае, или в других подобных, каждый экземпляр это новое окно (был пример и с двумя окнами п.34), создали окна, потом понадобилось какое то удалить, естественно удаляем вместе с экземпляром.

teadrinker пишет:

Нет, внутри конструктора имеет смысл писать то, что будет иметь отношение ко всем экземплярам объектов.

Думаю надо писать то, что необходимо для конкретного функционала.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

45

Re: AHK: классы

teadrinker пишет:

Ну так а откуда в функции за пределами класса возьмётся this?

А зачем мне такая функция, если нет доступа к нужным мне данным?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

46

Re: AHK: классы

serzh82saratov пишет:

Думаю надо писать то, что необходимо для конкретного функционала.

serzh82saratov пишет:

А зачем мне такая функция, если нет доступа к нужным мне данным?

Мне собственно изначально надо было внутри класса, так как речь идёт про как бы общий массив используемый в классе, и если что то написано вопреки тезису - "иметь отношение ко всем экземплярам объектов" то я просто варвар. Хотя - массив общий для всех экземпляров, вроде ему соответсвует.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

47 (изменено: teadrinker, 2017-08-29 04:29:58)

Re: AHK: классы

Так ты зададачу не можешь чётко сформулировать.

serzh82saratov пишет:

каждый экземпляр это новое окно

Ну а у тебя

Gui, Show, w222 h222

Подразумевается, что это одно и то же окно Gui, 1:. Если это разные окна, их нужно создавать

Gui, New, +hwndhGui

А потом, чтобы не было лишних срабатываний OnMessage, проверять параметр hwnd:

m1 := new ClassName("Привет!", 300)
m2 := new ClassName("Пока!", 600) 
ToolTip % m1.arr[1] "`n" m2.arr[1]
Return

Class ClassName
{
   static arr := []
   __New(key, x) {
      Gui, New, +hwndhGui
      Gui, Show, x%x% w222 h222
      this.arr[1] := key
      OnMessage(WM_LBUTTONDOWN := 0x201, ObjBindMethod(this, "OnButtonDown", hGui))
   }
   OnButtonDown(hGui, wp, lp, msg, hwnd) {
      if (hGui = hwnd)
         MsgBox % this.arr[1]
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

48

Re: AHK: классы

А лучше даже так:

m1 := new ClassName("Привет!", 300)
m2 := new ClassName("Пока!", 600) 
ToolTip % m1.arr[1] "`n" m2.arr[1]
Return

Class ClassName
{
   static arr := []
   __New(key, x) {
      Gui, New, +hwndhGui
      Gui, Show, x%x% w222 h222
      this.arr[1] := key
      OnMessage(WM_LBUTTONDOWN := 0x201, ObjBindMethod(this, "OnButtonDown", hGui))
   }
   OnButtonDown(hGui, wp, lp, msg, hwnd) {
      if (hGui = A_Gui)
         MsgBox % this.arr[1]
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

49

Re: AHK: классы

Формулировки честно говоря не было, от одного вопроса плавно перешли к другому.
С A_Gui лучше, а то в hwnd контрол может быть. Спасибо, сам недогадался, способ хороший, если сообщение требует привязки к конкретному окну. В моём случае это тоже требуется, но всё же не нравится дёргать OnProc по несколько раз при каждом клике или движении колёсика. При 10 окнах, 10 кликов вызовут очередь из 100 сообщений. Пока остановлюсь на своём решении передачи самого класса с одним OnMessage.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

50

Re: AHK: классы

С одним OnMessage:

m1 := new ClassName("Привет!", 300)
m2 := new ClassName("Пока!", 600) 
ToolTip % m1.arr[1] "`n" m2.arr[1]
OnMessage(WM_LBUTTONDOWN := 0x201, ObjBindMethod(ClassName, "OnButtonDown"))
Return

Class ClassName
{
   static arr := []
   __New(key, x) {
      Gui, New, +hwndhGui
      Gui, Show, x%x% w222 h222
      this.arr[1] := key
   }
   OnButtonDown(wp, lp, msg, hwnd) {
      MsgBox % this.arr[1]
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

51 (изменено: serzh82saratov, 2017-08-29 09:48:39)

Re: AHK: классы

Согласись не красиво,  предоставляя класс,  объснять пользователю что ему надо (в моем случае) прописывать еще 5 замысловатых строк.

		OnMessage(This.WM_LBUTTONDOWN, ObjBindMethod(Class, "OnButtonDown"))
		OnMessage(This.WM_LBUTTONDBLCLK, ObjBindMethod(Class, "OnButtonDown"))
		OnMessage(This.WM_RBUTTONDOWN, ObjBindMethod(Class, "OnButtonDown"))
		OnMessage(This.WM_RBUTTONDBLCLK, ObjBindMethod(Class, "OnButtonDown"))
		OnMessage(This.WM_MOUSEWHEEL, ObjBindMethod(Class, "OnMouseWheel"))
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

52

Re: AHK: классы

А где ему придётся это прописывать?

53

Re: AHK: классы

Так лучше наверное нигде. В классе должно быть такое.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

54

Re: AHK: классы

Ну а если там и прописать? Вот так ведь вроде работает.


m1 := new ClassName("Привет!", 300)
m2 := new ClassName("Пока!", 600) 
ToolTip % m1.arr[1] "`n" m2.arr[1]
Return

Class ClassName
{
   static arr := [], var := OnMessage(WM_LBUTTONDOWN := 0x201, ObjBindMethod(ClassName, "OnButtonDown"))
   __New(key, x) {
      Gui, New, +hwndhGui
      Gui, Show, x%x% w222 h222
      this.arr[1] := key
   }
   OnButtonDown(wp, lp, msg, hwnd) {
      MsgBox % this.arr[1] . "`n" . hwnd
   }
}

55

Re: AHK: классы

Там имя класса прописывается, мне это не нравится. Типа если захотел поменять имя, то чтобы лезть больше никуда не надо. В 28 есть решение, также переделал часы из коллекции.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui