Sign in to follow this  
Followers 0
aommaster

What's wrong with this loop?

21 posts in this topic

#1 ·  Posted (edited)

Hey guys!

So, I have a user input a number (which is the grid-size). The program will take that numbrer, and generate a GUI with buttons spanning that gridsize horizontally and vertically. E.g. if the user inputs 5, the program will generate a 5x5 set of buttons. However, I want to assign a name for each of the buttons so I'm using the following loop:

for $i=0 to $gridsize-1
    $coordsx=0
    for $j=0 to $gridsize-1
        assign("n" & $i & "n" & $j, guictrlcreatebutton("n" & $i & "n" & $j, $coordsx, $coordsy, $boxsize, $boxsize))
        $coordsx+=$boxsize
    Next
    $coordsy+=$boxsize
Next

And now, I want to use a GUICTRLSetOnEvent so that when any of the buttons are pressed, the program will call a function called 'Guess'. In guess, it will find out the name of the button that called it and work accordingly (but that's currently not my problem). The loop for the GUICTRLSetOnEvent is below:

for $i=0 to $gridsize-1
    for $j=0 to $gridsize-1
        $varname="n" &  $i & "n" & $j
        guictrlsetonevent($varname, "guess")
    Next
Next

But for some reason, only the first few buttons (if any) are able to call the function when I use these two loops. What am I doing wrong?

Thanks guys!

Edited by aommaster

Share this post


Link to post
Share on other sites



Part of the problem is that you are attempting to start a variable name with a number. Don't do that.

Share this post


Link to post
Share on other sites

Part of the problem is that you are attempting to start a variable name with a number. Don't do that.

Okay... I fixed that in my original program (I stuck a letter n in from of the variable name). What else could be going wrong here?

Also, what problems occur if I start a variable name with a number?

Share this post


Link to post
Share on other sites

I don't see where you fixed anything. You have a letter 'n' in the middle of the variable, but it still starts with a number.

Variables aren't supposed to start with a number. It says that clearly in the help file.

Share this post


Link to post
Share on other sites

I don't see where you fixed anything. You have a letter 'n' in the middle of the variable, but it still starts with a number.

Ahh... I think you misunderstood me. I fixed that in the script on my computer (I didn't re-edit the post, the first edit was because of a typo).

I've editted it now.

Thanks again for your time

Share this post


Link to post
Share on other sites

Variables aren't supposed to start with a number. It says that clearly in the help file.

Where does it say that?

Variables with numbers work fine and as far as I can see there's no reason to insist on variable names starting with a letter.

Eg

$112n = 34
consolewrite($112n & @CRLF)

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

That's the only limitations mentioned in the help file:

Each variable has a name (again, similar to a mailbox) and must start with the $ character and may only contain letters, numbers and the underscore _ character.

Share this post


Link to post
Share on other sites

Hey guys!

I think we're getting a *little* off topic :P

I've stuck in an "n" at the front anyway, just to make sure Autoit doesn't yell at me for whatever reason.

But as far as I can see, there's nothing wrong with the loop I've made. Apparently, Autoit thinks otherwise :)

Share this post


Link to post
Share on other sites

Hey guys!

So, I have a user input a number (which is the grid-size). The program will take that numbrer, and generate a GUI with buttons spanning that gridsize horizontally and vertically. E.g. if the user inputs 5, the program will generate a 5x5 set of buttons. However, I want to assign a name for each of the buttons so I'm using the following loop:

for $i=0 to $gridsize-1
    $coordsx=0
    for $j=0 to $gridsize-1
        assign("n" & $i & "n" & $j, guictrlcreatebutton("n" & $i & "n" & $j, $coordsx, $coordsy, $boxsize, $boxsize))
        $coordsx+=$boxsize
    Next
    $coordsy+=$boxsize
Next

And now, I want to use a GUICTRLSetOnEvent so that when any of the buttons are pressed, the program will call a function called 'Guess'. In guess, it will find out the name of the button that called it and work accordingly (but that's currently not my problem). The loop for the GUICTRLSetOnEvent is below:

for $i=0 to $gridsize-1
    for $j=0 to $gridsize-1
        $varname="n" &  $i & "n" & $j
        guictrlsetonevent($varname, "guess")
    Next
Next

But for some reason, only the first few buttons (if any) are able to call the function when I use these two loops. What am I doing wrong?

Thanks guys!

The problem is that you are create a string to represent the variable and trying to set an event for the string. Because the string evaluates to a number which by luck might correspond to the Control ID of some of the buttons, some of the buttons might work. It has nothing to do with having varible name which start with a number which IMO is quite acceptable.

Since you only posted parts of your code I can't run it, and I don't want to add the missing bits, so here is my guess as to what you need

for $i=0 to $gridsize-1
    $coordsx=0
    for $j=0 to $gridsize-1
        assign("n" & $i & "n" & $j, guictrlcreatebutton("n" & $i & "n" & $j, $coordsx, $coordsy, $boxsize, $boxsize))
        guictrlsetonevent(-1, "guess")
        $coordsx+=$boxsize
    Next
    $coordsy+=$boxsize
Next

If that doesn't work, although I think it will, then do this

for $i=0 to $gridsize-1
    $coordsx=0
    for $j=0 to $gridsize-1
        assign("n" & $i & "n" & $j, guictrlcreatebutton("n" & $i & "n" & $j, $coordsx, $coordsy, $boxsize, $boxsize))
        guictrlsetonevent(_GUIGetLastCtrlID(), "guess")
        $coordsx+=$boxsize
    Next
    $coordsy+=$boxsize
Next

.
.
.
.
Func _GUIGetLastCtrlID()
    
    Local $aRet = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", GUICtrlGetHandle(-1))
    Return $aRet[0]
    
EndFunc ;==>_GUIGetLastCtrlID

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Martin, that is pure genius! Your first bit of code was good enough, and autoit is all happy again :)

I have one last question (not relating to this loop):

Is there a way of getting the ID (the variable name) of the GUI control that called the function? Or do I have to use the @GUI_CTRLID and then apply relevant calculations/logic to work out what the variable name is?

Thanks again for your help Martin!

Share this post


Link to post
Share on other sites

I suppose I was just thinking of other languages then. I didn't know AutoIt supported numbers are the first character in a variable name.

No, you can't get the variable name because any number of variables may contain the same value. The value returned by the create function doesn't even need to be stored.

Share this post


Link to post
Share on other sites

My way,working script,just take what you need:

#include <GUIConstants.au3>

Global $GridSize = 10
Global $BoxSize = 50
Global $GridButtons[$GridSize][$GridSize] = [[0]]

Opt("GUIOnEventMode",1)
GUICreate("",500,500)
GUISetOnEvent($GUI_EVENT_CLOSE,"Close")

For $i=0 to $GridSize-1
    For $j = 0 to $GridSize-1
        $GridButtons[$i][$j] = GuiCtrlCreateButton("n" & $i & "n" & $j, $BoxSize*$j, $BoxSize *$i, $BoxSize, $BoxSize)
        GUICtrlSetOnEvent(-1,"Guess")
    Next
Next

GUISetState()
While 1
    Sleep(100)
WEnd

Func Guess()
    MsgBox(0,0,"GUESS")
EndFunc

Func Close()
    Exit
EndFunc

Share this post


Link to post
Share on other sites

No, you can't get the variable name because any number of variables may contain the same value. The value returned by the create function doesn't even need to be stored.

Hi Richard! I'm afraid I didn't quite understand that. I'm currently using the assign function to assign a string to the GUICTRLCreate function, which is working fine.

Doesn't that mean that each of the GUI buttons have a name assigned to them? And from that, is there a way to obtain the name of the button that called the function?

Share this post


Link to post
Share on other sites

Martin, that is pure genius! Your first bit of code was good enough, and autoit is all happy again :)

I have one last question (not relating to this loop):

Is there a way of getting the ID (the variable name) of the GUI control that called the function? Or do I have to use the @GUI_CTRLID and then apply relevant calculations/logic to work out what the variable name is?

Thanks again for your help Martin!

With my version you can use ArraySearch for this,or,like i do in most of my scripts,store a WinAPI_MakeLong'ed integer with the 'i' and 'j' of the button in it's private data, retrieve it with WinApi_HiWord and LoWord,fast and clean,no need for lenghty array searches.

Share this post


Link to post
Share on other sites

My way,working script,just take what you need

Thanks for your script! It's always nice to see another (shorter) alternative to the current script I am using :)

Share this post


Link to post
Share on other sites

With my version you can use ArraySearch for this,or,like i do in most of my scripts,store a WinAPI_MakeLong'ed integer with the 'i' and 'j' of the button in it's private data, retrieve it with WinApi_HiWord and LoWord,fast and clean,no need for lenghty array searches.

My approach would be to take the control ID, subtract 2, and then divide it by gridsize. If you truncate the number at the decimal point, you get teh j value. The i value can easily be calculated after that :)

Share this post


Link to post
Share on other sites

My approach would be to take the control ID, subtract 2, and then divide it by gridsize. If you truncate the number at the decimal point, you get teh j value. The i value can easily be calculated after that :)

This way only works with AU3 native controls,doesn't work with other kinds of associated data,depends on the order you create controls,etc.

I tried lots of ways to associate multiple controls with arrays,and this was the best one i found.

Share this post


Link to post
Share on other sites

Ahh.. agreed. That is why I took a relatively simple way of assigning the names, so that if anything happens along the lines of me not being able to obtain the variable name (as expected), I could easily calculate them :)

Thanks again danielkza, I'll certainly keep your methodology in mind while I work on this project :P

Share this post


Link to post
Share on other sites

This way only works with AU3 native controls,doesn't work with other kinds of associated data,depends on the order you create controls,etc.

I tried lots of ways to associate multiple controls with arrays,and this was the best one i found.

Subtracting 2 is unreliable I think. Better to have a variable, say $FirstBtn , like this

Global $FirstBtn = 0
for $i=0 to $gridsize-1
    $coordsx=0
    for $j=0 to $gridsize-1
        assign("n" & $i & "n" & $j, guictrlcreatebutton("n" & $i & "n" & $j, $coordsx, $coordsy, $boxsize, $boxsize))
         guictrlsetonevent(-1, "guess")
         If $FirstBtn = 0 Then $FirstBtn = _GetLastCtrlID()
        $coordsx+=$boxsize
    Next
    $coordsy+=$boxsize
Next



Func Guess()
 Local $BtnNo = @GUI_CtrlId - $FirstBtn;  (first Btn will be 0)
 Local $brow,$bcol
 $brow = Int($BtnNo/$gridsize) + 1
 $bcol = Mod($BtnNo/$gridsize) + 1
 MsgBox(0,0,"GUESS. (row = " & $brow & ", column = " & $bcol & ")" )
EndFunc


;=========; _GUIGetLastCtrlID ==============================================
;returns the last ctrlID referenced                                         
;From MsCreaTor                                                             
;Internal Use                                                               
;===========================================================================
Func _GUIGetLastCtrlID()
    
    Local $aRet = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", GUICtrlGetHandle(-1))
    Return $aRet[0]
    
EndFunc ;==>_GUIGetLastCtrlID

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Thanks Martin!

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  
Followers 0