Jump to content
Sign in to follow this  
LondonNDIB

Bug? Or just ambiguous? Or just I don't understand :)

Recommended Posts

LondonNDIB

From the helpfile entry for HotKeySet:

The called function can not be given parameters. They will be ignored.

Ok, so what exactly does "ignored" mean?

Consider this code:

HotKeySet ( "+t", "Test" )
Opt ( "TrayOnEventmode", 1 )
$tray_menu = TrayCreateMenu ( "Menu" )
$tray_menu_item = TrayCreateItem ( "Run Test", $tray_menu )
TrayItemSetOnEvent ( $tray_menu_item, "MenuTest" )
TraySetState ()

Func MenuTest ()
    Test ( "foobar" )
EndFunc

Func Test ( $var = "hello" )
    MsgBox ( "", $var, "success" )
EndFunc

Ok, I'm sure the code is somewhat pointless... but it pretty much is a simplified version of what I am trying to do. The idea here is that a tray menu gets created. The user can either run the Test function via the tray menu (indirectly via MenuTest since I want to pass a specified parameter), or they can run it by the HotKey, in which case I would EXPECT the default parameter value to be used, since I can't pass one with the HotKey (as per the help file).

Instead, I get an error saying that $var is being used without being declared!!

I realize it states that any parameters passed would be "ignored", but shouldn't the function's default parameter value be respected?

Is this a bug? (or oversight?) or is there some reason that the parameter get DESTROYED (not ignored)? I understand that parameters can't be passed by the HotKeySet function, but that's the HotKeySet function's problem... that should have no impact on the function that it is calling.

In other words... it should operate exactly as though I called the function like so:

Test ()
instead of what it is doing, which is forcing $var to be undeclared instead of undefined.

Thoughts?

LD

Edited by LondonNDIB

Share this post


Link to post
Share on other sites
LondonNDIB

Huh?

Are you saying I asked the same question before? Because I didn't. If it double-posted (doesn't look like it did though??) then sorry.

Otherwise, I don't get what your comment meant.

Unless you meant post #7, not 8... about the TraySetOnEvent... which is completely different. Though I could see how someone casually reading could miss the distinction.

There, I was questioning why one couldn't pass parameters (it never was answered... just work arounds provided - but it sufficed).

In this case, its a different behavior. The parameter is being destroyed, rather than ignored. Its limiting the function that is being called, not a limitation of the function doing the calling (which was the case with TraySet...)

LD

Edited by LondonNDIB

Share this post


Link to post
Share on other sites
Valuater

#NoTrayIcon
Opt("TrayMenuMode", 1)
Opt("TrayOnEventMode", 1)

HotKeySet ( "+t", "MenuTest"  )

$tray_menu = TrayCreateMenu ( "Menu" )
$tray_menu_item = TrayCreateItem ( "Run Test", $tray_menu )
TrayItemSetOnEvent ( $tray_menu_item, "MenuTest" )
TraySetState ()

While 1
    Sleep(10)
WEnd

Func MenuTest ()
    Test ( "foobar" )
EndFunc

Func Test ( $var = "hello" )
    MsgBox ( "", $var, "success", 2 )
EndFunc

; The closest I can figure by your discussion is you would like

; TrayItemSetOnEvent ( $tray_menu_item, "MenuTest" ) to equal HotKeySet ( "+t", "Test" )

; than it would be th same as TrayItemSetOnEvent ( $tray_menu_item, "MenuTest" ) is equal to HotKeySet ( "+t", "MenuTest"  )

8)


NEWHeader1.png

Share this post


Link to post
Share on other sites
LondonNDIB

One or both of us is confused.

I can't tell if you are attempting to help or mocking me... lol.

I'll just elaborate more and hope for the best.

I have a script that starts a tray menu, has a whole bunch of entries that call various functions. Thanks to TrayItemSetOnEvent not taking parameters, I have to use the workaround and check the @Tray_ID values once inside the called function(s). That's fine... except...

I also want (some subset of) those functions to be triggered by a HotKey. The problem now is, I still can't pass paramaters, but even worse the code craps out because @Tray_ID is an invalid macro since the tray menu items weren't called.

In this case, however... IF the function is being called by the HotKey, I don't really need a paramter - it will just use a default value. Parameters are really only required if called from the Tray. Since I don't want to (nor should I have to if this is to be a real scripting language) write multiple copies of the same function... so Test() needs to be called with an optional parameter. If HotKey, then default... if Menu, then act on the @Tray_ID (via the wrapper function MenuTest). Unfortunately, this isn't possible because HotKey destroys the default parameter value.

Now, I could write yet ANOTHER wrapper function... something like this:

Func HotKeyTest ()
Test ()
EndFunc

and I suppose since this discussion only ever leads to ugly-code-work-arounds... this works. Not very elegant, but it works.

I maintain it would be much better to just have the ability to pass the paramters as one would expect. "Wrapper" functions like these are (or should be) tedious, redundant... ugly and useless. The makings of a good Yo Mamma joke.

LD

Share this post


Link to post
Share on other sites
PsaltyDS

I maintain it would be much better to just have the ability to pass the paramters as one would expect. "Wrapper" functions like these are (or should be) tedious, redundant... ugly and useless. The makings of a good Yo Mamma joke.

Your posted code needs tweaking to run because it has not loop to keep it running, and the TrayAutoPause option prevents the tray event from being used. This is besides the point and an easy fix:

Opt("TrayOnEventmode", 1)
Opt("TrayAutoPause", 0)
$tray_menu = TrayCreateMenu("Menu")
$tray_menu_item = TrayCreateItem("Run Test", $tray_menu)
TrayItemSetOnEvent($tray_menu_item, "MenuTest")
HotKeySet("+t", "Test")
TraySetState()

While 1
    Sleep(20)
WEnd

Func MenuTest()
    Test("foobar")
EndFunc   ;==>MenuTest

Func Test($var = "hello")
    MsgBox("", $var, "success")
EndFunc   ;==>Test

I agree with the AutoIt developers that there is no point to GuiSetOnEvent, GuiCtrlSetOnEvent, HotKeySet, etc. accepting parameters.

I also agree with you, though, that parameters in the Func declaration with default values should be allowed. This so that the same function can be reused for both event-based and regular programatic calls. There may be some hard limit C++ reason why that can't be done. Calling "Test" via an event is somehow totally different from Test() in the normal course of the script.

This idea belongs in the Feature Requests forum. You won't find any sympathy there for passing parameters via events, but there may be either a fix or an explanation available for the defaulted parameters part.

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites
LondonNDIB

I'll do that, thanks Psalty

Curious... I've never gotten a good explanation for why parameters aren't passed. You say you agree, so maybe you could clue me in? Is it simply because there is "another way" (@Tray_ID)? Because in some situations, that "other way" isn't very nice. Really, it still presents a problem when you are trying to share a function with event-based and programatic calls, since the function pukes on @Tray_ID unless it came from the tray.. thereby forcing you to use at a minimum a small wrapper function, which could so easily be avoided by simply allowing parameters.

Unless its not so "simply".

But all the "non-sypathetic" responses I've ever gotten just wax "don't care, cause it works how I want it to work for my situation and I'm the dev so STFU" instead of, "well, there's a technical reason why...."

Maybe they'll tell me when I post this time :) :holding breath:

LD

Share this post


Link to post
Share on other sites
PsaltyDS

Curious... I've never gotten a good explanation for why parameters aren't passed. You say you agree, so maybe you could clue me in? Is it simply because there is "another way" (@Tray_ID)? Because in some situations, that "other way" isn't very nice. Really, it still presents a problem when you are trying to share a function with event-based and programatic calls, since the function pukes on @Tray_ID unless it came from the tray.. thereby forcing you to use at a minimum a small wrapper function, which could so easily be avoided by simply allowing parameters.

Well, I'm neither a programmer, nor an AutoIt developer, but for me the deciding issue is that NOTHING available to the event is not also available to the called function. Every macro, every Global variable and data structure that you might pass, including which GUI/Control/HotKey/Item/etc. triggered it (i.e. @HotKeyPressed for HotKeySet) is already there -- so what's left to pass?

As an exercise, try to create a hypothetical HotKeySet("X", "MyFunc(???)") and find something to put in ??? that isn't available to MyFunc() anyway.

I can only speculate on what the C++ issues might be on the back end, but they probably have to do with proliferating data structures and pointers to keep track of, when there's no reason for it. HotKeySet, for example registers the event with Windows, not just inside AutoIt. When the event hits, that's all Windows has to say -- the event hit. Adding parameters to the event would require AutoIt to do it for you after Windows notified of the event. Why wouldn't your function just do that for itself?

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites
LondonNDIB

See, that's the problem that I think prevails. "I don't need it, so nobody else will either".

Your challenge is easy. Let's use a backup program as a hypothetical application. I'm not going to actually generate proper code here... just follow along with the logic.

You have a tray menu running with this hierarchy.

Backup
   All
   Documents
   Pictures

Now... "all" has the hotkey +A assigned to it, Documents as +D and Pictures has +P. As well, a user can call the program directly with a parameter such that the Tray may or may not even be used ie. "BackupScript Pictures" from the command line.

So, I want the function like this (again, just psuedo code here):

Func Backup ( $job = "all" )

...

EndFunc

So if the user either uses the +A hotkey, selects ALL from the menu, or calls the program from the command line without any parameters, it will end up running the Backup function with the default "all. However, choosing a job (eg. Pictures) from the menu, using +P hotkey, or passing that parameter at the command line will run it with $job being "Pictures"

With the functions the way they work now, my "Backup" function can't be the same for all calling methods! I am forced to use "wrapper" functions. Why? Because @TRAY_ID is available ONLY if called from the menu, @HotKeyPressed is available ONLY if called from the hotkey (I think, I haven't tested to the same extent as TRAY_ID). If I try to make use of either macro within the function, I get an error because the macro is undefined. Similarly, if I do use either of the event calls, the default "$job" variable pukes because it hasn't been declared (it has!! In the Func statement).

Whether or not there is some convoluted way around it using wrappers and cross-referencing via some macro generated ID... it would be FAR better incases like these if I could call my function directly like (hypothetically as challenged)

HotKeySet("+P", "Backup("Pictures")")

Obviously, that's not how the syntax would be used though.

I hope that illustrates WHY it would be useful. If it doesn't, its because I haven't explained it well enough, not because the argument doesn't have merit. I've seen it requested/suggested so many times I think its clear there is call for it. And I myself have run around in circles finding ways around the lack fo the functionality so many times that I'm certain it is the best way to achieve what I am trying to.

Again... there are work arounds. But what is a work around? Its a way of getting past a bug. At least I wish it was treated that way.

I shouldn't have to make 3 or more functions to get one function to work intuitively.

LD

Edited by LondonNDIB

Share this post


Link to post
Share on other sites
PsaltyDS

I had thought you could simply test the macros and know exactly which type of event called the function.

Well, I'll have to surrender. I tried to code some examples and found things don't work the way I thought they did:

1. Using the wrong macro kicks an error and kills the script, like using @TRAY_ID while handling a HotKey.

2. The macros don't clear after the function is called. The macro @HotKeyPressed is "" before you hit the HotKey. If the HotKey is 'x' and the HotKey is pressed, it stays 'x' forever or until a different HotKey gets pressed.

3. Neither IsDeclared() nor IsKeyword() will allow you to test for which macros are currently valid.

Those things do, in fact, prevent you from re-using the event function for other events.

:) I don't really know everything after all...! :)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites
LondonNDIB

Thank you for taking some time with it.

I'm not a programmer, so I don't think I know how to word things in such a way that makes my point come across to programmers... so it helps having someone else look at it like you did.

- Steven

Share this post


Link to post
Share on other sites
TurionAltec

Uhh I also ran into the same problem.

Sample code like this:

#include <GUIConstants.au3>
opt("GUIOnEventMode",1)
$Form1 = GUICreate("Form1", 306, 199, 193, 125)
$Button1 = GUICtrlCreateButton("Button1", 64, 64, 105, 33, 0)
GUISetState(@SW_SHOW)
GUICtrlSetOnEvent ( $Button1, "_msgbox" )
Hotkeyset("#t","_msgbox")

$i=1
_msgbox()

While 1
    sleep(2500)
    _msgbox("Called from loop "&$i)
    $i+=1
WEnd
Func _msgbox($msg="No message set")
    msgbox(0,"Msgbox",$msg)
EndFunc

This causes the program to barf if you press the hotkey (Win+t), or press Button1 in the GUI.

My interpretation of the help file (HotkeySet)

"The called function can not be given parameters. They will be ignored."

Is that you can't pass on special parameters, not that the default parameters will be ignored.

I couldn't figure out why I was getting "variable not declared" errors until I ran into this post: #415835

Now if there's some technical reason why the default variables aren't being respected, fine, it can be worked around with dummy functions or IsDeclared(), but I think this comment in the help file should be clarified, ditto GUICtrlSetOnEvent() or any other functions that may have the same "feature".

Worthy of a bug report to fix the help file?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×