Obsolete test build - Functions and Objects as Labels (etc.)

Community news and information about new or upcoming versions of AutoHotkey
guest3456
Posts: 3462
Joined: 09 Oct 2013, 10:31

Re: New test build - Functions and Objects as Labels (and m

13 Jan 2015, 23:20

lexikos wrote:GeekDude, guest3456: I don't know what you're talking about. Why should it make the code more or less easy to predict?
Just the inconsistency for when its possible to do that.. only works Hotkey labels but not normal labels or hotstrings, and the differences for when things fall thru to new labels. I dont know if I even fully understand it so my opinion probably doesn't matter. I'm all for experimenting and trying new things. I just don't see why this is needed in the language. Just added complexity and more rules and rule exceptions to learn for not much benefit. I will probably never use it for those reasons so perhaps others should be consulted

lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test build - Functions and Objects as Labels (and m

14 Jan 2015, 01:56

guest3456 wrote:Just the inconsistency for when its possible to do that.. only works Hotkey labels but not normal labels or hotstrings,
I find it hard to believe anyone would have trouble "predicting" that. The syntax for hotkeys is different to the syntax for labels and the syntax for hotstrings. It's not like the script will behave differently if you point a label or hotstring at a function - the program won't allow you to make that mistake.

I expect some users would use the new syntax, or any equivalent which allows local variables as easily, almost exclusively. I often avoid using variables in hotkeys because they're global, and defining and calling a function is too verbose. Defining the hotkey as a function also encourages self-documenting code, like ^a:: select_all() {....
and the differences for when things fall thru to new labels.
(I'll assume you meant "fall through labels", because "fall through to new labels" makes no sense to me.)

With normal hotkeys, labels and hotstrings, execution always falls through the label, and this commonly causes problems because it doesn't also fall through the commands below the label. The exception is that the first hotkey or hotstring acts like return; this inconsistency already exists, and the new feature does not change it at all.

Similarly, execution always falls through function definitions. This also hasn't changed. The only thing that has changed is that hotkey:: followed by function_definition() is interpreted as assigning that function to the hotkey, instead of raising an error.
I just don't see why this is needed in the language.
Don't you see the benefit of using functions? Requiring a function call and return for each hotkey is not conducive to using functions for every hotkey.
I will probably never use it for those reasons so perhaps others should be consulted
Considering only the opinions of users who would use the feature would bias the result rather unreasonably.

I'm not dead set on including the feature; as I said, it's experimental. I'm just very surprised to see such direct opposition to it, or any opposition to it.

I also considered something like ^a::(), but it looks weird and doesn't make a lot of sense, since the hotkey never passes parameters (but some could be defined). It also wouldn't allow assigning several hotkeys or hotkey variants, or calling the hotkey-function from elsewhere.
guest3456
Posts: 3462
Joined: 09 Oct 2013, 10:31

Re: New test build - Functions and Objects as Labels (and m

14 Jan 2015, 11:43

lexikos wrote:I often avoid using variables in hotkeys because they're global, and defining and calling a function is too verbose. Defining the hotkey as a function also encourages self-documenting code, like ^a:: select_all() {....
This is a good reason, I agree, and perhaps this would be an instance where I'd use it. Like most I prefer avoiding globals, but in a script big enough where it matters, I'm usually just calling a func directly from the hotkey with something like ^a::ctrl_a_func()

I also have another concern about this type of confusion:

Code: Select all

^a::
    pressing_ctrl_a_calls_this_function() {
        if (A_Day = "Monday")
            return 1
        else
            return 2
    }
    msgbox, 3
return
I assume in the above codeblock, the hotkey ends at the } closing brace of the function, rather than the first return? Actually would there ever be reason to have a return value from this hotkey func? Since the value would never 'return' anywhere. And therefore msgbox, 3 never fires?
I'm not dead set on including the feature; as I said, it's experimental. I'm just very surprised to see such direct opposition to it, or any opposition to it.
You've changed my mind on some things with your response, so I don't know that I'd say I oppose it anymore. I guess I'm just concerned simply because AHK already has a reputation for having very quirky syntax, and I think this addition just compounds that.

lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test build - Functions and Objects as Labels (and m

14 Jan 2015, 19:18

I assume in the above codeblock, the hotkey ends at the } closing brace of the function
Hotkeys neither "begin" nor "end". Subroutines end, but this hotkey is associated with a function, not a subroutine. Like Hotkey ^a, pressing_ctrl_a_calls_this_function.
Actually would there ever be reason to have a return value from this hotkey func?
Yes, but only if the function is also called directly by the script.

Another way of implementing it would have been to make ^a:: func(){ imply func() return, but I thought the resulting behaviour was even less intuitive; i.e. if execution falls through the hotkey label from above, it calls the function!
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: New test build - Functions and Objects as Labels (and m

23 Jan 2015, 18:38

Lex, could you tell me if it is possible to do something like this without using a global function to route through?

Code: Select all

#SingleInstance force
mc1 := new MyClass("one")
mc2 := new MyClass("two")
Gui, Show
return

Class MyClass {
	__New(name){
		this.name := name
		Gui Add, Button, w75        , TestA
		fn := bind(this, "TestA")	; Call TestA method of this class instance on button press
		GuiControl +g, TestA, %fn%

		Gui Add, Button, w75        , TestB
		fn := bind(this, "TestB")	; Call TestB method of this class instance on button press
		GuiControl +g, TestB, %fn%

	}
	
	TestA(){
		msgbox % "You pressed A button for " this.name
	}

	TestB(){
		msgbox % "You pressed B button for " this.name
	}

}
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test build - Functions and Objects as Labels (and m

23 Jan 2015, 19:08

Use fn := bind(this.TestA, this) (note the parameter order, and passing a reference to the method).

With your example code, GuiControl will not modify the second set of buttons because the first set have the same text. You should refer to them by HWND instead.
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test build - Functions and Objects as Labels (and m

24 Jan 2015, 02:19

Update

OnMessage now accepts function and object references.
  • If you only ever pass OnMessage() function names, it acts as before.
  • If the previous message monitor is a non-function object, the return value is a reference to the object.
  • If the second parameter is a reference to an object or function, the behaviour changes as follows:
    • If a memory allocation fails (only possible the first time a message monitor is added), or if there are already 500 message monitors, an exception is thrown. The old behaviour was to return an empty string. v2 always throws in these cases.
    • If the previous message monitor was a normal function, it is returned by reference instead of by name. (For backward-compatibility, this only occurs if you pass the new function by reference.)
    • If there was no previous message monitor, an empty string is returned. The old behaviour was to return the new function's name (to differentiate it from failure). Example of where this helps:

      Code: Select all

      old := OnMessage(msg, "newfunc")
      ;...
      if (old != "newfunc")   ; This check is not needed if you use Func("newfunc").
          OnMessage(msg, old)
      v2 always returns an empty string if there was no previous function.
I've reverted the change adding WIN_10 as a possible value for A_OSVersion. Instead, Windows 10 and any new Windows versions are reported using the v2 format. For example, the Windows 10 Technical Preview is 6.4.9841.

I've also removed the supportedOS entry for Windows 10 TP from the manifest. Instead, A_OSVersion uses RtlGetVersion(), which unlike GetVersionEx(), doesn't appear to be deprecated and doesn't lie on Windows 8.1 or Windows 10. (It may or may not lie on Windows 11 but that's too bad.) However, both RtlGetVersion() and GetVersionEx() lie if AutoHotkey.exe is set to run in compatibility mode.

This build is v1.1.19.01-17+g68e80cd.
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test build - Functions and Objects as Labels (and m

24 Jan 2015, 16:52

GeekDude wrote:Will it ever be possible to set multiple handlers for the same message?
It's already possible if you manage them yourself. [Edit: GeekDude's post was moved to Wish List.]
evilC wrote:[...] does this mean we can have OnMessage call a class method without Bind, or are we going to need to use Bind?
It's the same as with all of the other commands already covered in this thread. If you pass just a method, it will call method.Call(wParam, ...), so don't do that. Obviously if you pass just a method, you aren't telling it which object is this.
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: New test build - Functions and Objects as Labels (and m

24 Jan 2015, 20:23

lexikos wrote:It's the same as with all of the other commands already covered in this thread. If you pass just a method, it will call method.Call(wParam, ...), so don't do that. Obviously if you pass just a method, you aren't telling it which object is this.
Right, that was what I would have guessed, but I tried

Code: Select all

fn := Bind(this.MessageHandler, this)
OnMessage(0x00FF, fn)
and got no joy.

Oh hold on, I am a retard.
Installing the new test build might help :/
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: New test build - Functions and Objects as Labels (and m

24 Jan 2015, 20:31

Nope, running g68e80cd and still no joy.

Here is the code:

Code: Select all

#include <AHKHID>
#SingleInstance force
mh := new MHandler()

Class MHandler {
	__New(){
		msgbox % A_AHKVersion
		global RIDEV_INPUTSINK
		AHKHID_AddRegister(1)
		AHKHID_AddRegister(1,2,A_ScriptHwnd,RIDEV_INPUTSINK)
		AHKHID_Register()
		fn := Bind(this.Handler, this)
		;OnMessage(0x00FF, "MessageHandler")
		OnMessage(0x00FF, fn)
	}
	
	Handler(wParam, lParam){
		global II_DEVTYPE, RIM_TYPEMOUSE, II_MSE_BUTTONFLAGS, II_MSE_LASTX, II_MSE_LASTY
		r := AHKHID_GetInputInfo(lParam, II_DEVTYPE)
		If (r = RIM_TYPEMOUSE) {
			flags := AHKHID_GetInputInfo(lParam, II_MSE_BUTTONFLAGS)
			if (!flags){
				x := AHKHID_GetInputInfo(lParam, II_MSE_LASTX)
				y := AHKHID_GetInputInfo(lParam, II_MSE_LASTY) 
				if (x != 0 || y != 0){
					s := "x: " x ", y: " y
					Tooltip % s
				}
			}
		}
	}
}
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test build - Functions and Objects as Labels (and m

24 Jan 2015, 20:58

Oops, forgot to AddRef(). You'll need to store fn somewhere to prevent it from being deleted, or update to v1.1.19.01-19+ga3104d4.
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test build - Functions and Objects as Labels (and m

24 Jan 2015, 21:04

You probably couldn't replicate it without AHKHID and ga3104d4, but you can try.
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: New test build - Functions and Objects as Labels (and m

24 Jan 2015, 21:07

Replicated.

Code: Select all

#SingleInstance force
OnExit, GuiClose


Gui, Add, Text,,Hello
Gui, Show

mh := new MHandler()
return

Esc::ExitApp
GuiClose:
ExitApp

Class MHandler {
	__New(){
		;msgbox % A_AHKVersion
		fn := Bind(this.MessageHandler, this)
		;OnMessage(0x201, "MessageHandler")
		OnMessage(0x201, fn)
	}
	
	MessageHandler(wParam, lParam){
		soundbeep
	}
}

MessageHandler(wParam, lParam){
	soundbeep
}
Click inside the GUI with normal func = fine.
Switch to class method = nothing.
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test build - Functions and Objects as Labels (and m

24 Jan 2015, 21:10

I should clarify: the version of bind() that I posted does not pass parameters along.
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test build - Functions and Objects as Labels (and m

24 Jan 2015, 21:48

To save further derailing the topic, I've moved the OnMessage discussion to Wish List.

evilC: Use bind v1.2 from the top post.

Return to “Announcements”

Who is online

Users browsing this forum: No registered users and 23 guests