Jump to content

Selecting from an array of buttons - (Moved)


Recommended Posts

For purposes of a brief explanation, I am creating a two dimensional array of buttons in frame_X.  The code is below.  Later on in the application, I want the enduser to be able to click on any of the buttons in the array, and I want to be able to identify which member of the array was clicked.  I'm very new to AutoIT, and I am trying to figure out how to code this without recreating all 85x8 buttons.  Note that I am using zero based arrays.  By Frame_x, Deactivate I can make the buttons available for clicking, I just can't figure out how to capture the button clicked.  Below this original code is my attempt at identifying the button clicked.

Func Frame_x()
$Width =  15
$Hight =  30
$Top =  100
$Left =  10
$N =  1
$Number =  1
$CabinsAcross =  85
$CabinRows =  8
$Y =  1
Dim $Side_Array[$CabinsAcross][$CabinRows]  ;=ArrayFill($CabinsAcross,$CabinRows)
;set value of all cabins to zero
    $CabinRowsMax = $CabinRows - 1
    $CabinsAcrossMax = $CabinsAcross - 1
    $CabinRows = 0
    While ($CabinRows < $CabinRowsMax)
        For $i = 0 to $CabinsAcrossMax
            ;MsgBox(0,"CabinAcross", $i&$CabinRows)
            $Side_Array[$i][$CabinRows] = $Zero

        Next
        ;MsgBox(0,"CabinRows", $CabinRows)
        $CabinRows = $CabinRows + 1
    WEnd


;_ArrayDisplay($Side_Array)
$Frame_x_Top = 250
$Frame_x_Left = 5
$Frame_x = GUICtrlCreateLabel ("Cabins", $Frame_x_Left, $Frame_x_Top, 1300, 900, -1, $SS_BLACKFRAME)
;GUICtrlSetState ( $Frame_x, $GUI_DISABLE)
$Left = $Frame_x_Left
$Top = $Frame_x_Top
While $Y < ($CabinRows + 1)
    GUISetFont($Font)
    For $N =  1 to $CabinsAcross
    GUICtrlCreateButton($Number,$Left,$Top,$Width,$Hight,-1,-1)
    $Left =  $Left + $Width
    $Number = $Number +  1
    Next
    $Top =  $Top +  $Hight
    $Number =  1
    $Left =  10
    $Y =  $Y + 1
WEnd
EndFunc

Here is my attempt at finding the clicked button

Func Find_Cabins($Color)
    GUICtrlSetState($Frame_m, $GUI_ENABLE)
    GUICtrlSetState($Frame_p, $GUI_ENABLE)
    GUICtrlSetState ( $Frame_x, $GUI_DISABLE)  ;enable cabin boxes
    $Number =  1
    $CabinsAcross =  85
    $CabinRows =  8
    $Y =  0
    $CabinRowsMax = $CabinRows - 1
    $CabinsAcrossMax = $CabinsAcross - 1
    $X = 0
    $msg =  GUIGetMsg()
    For $Y = 0 to $CabinRowsMax  ;=ArrayFill($CabinsAcross,$CabinRows)
;search for clicked cabin
        For $X = 0 to $CabinsAcrossMax
        If  $Side_Array[$X][$Y] = $msg Then
        MsgBox(-1,"array",$X&$Y)
        EndIf
        Next
    Next

    MsgBox(-1, "msg", $msg)

    EndFunc

 

Edited by JLogan3o13
Link to comment
Share on other sites

  • Moderators

Moved to the appropriate forum, as the Developer General Discussion forum very clearly states:

Quote

General development and scripting discussions. If it's super geeky and you don't know where to put it - it's probably here.


Do not create AutoIt-related topics here, use the AutoIt General Help and Support or AutoIt Technical Discussion forums.

Moderation Team

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

From what I can see you need a second 2 dimensional array to keep track of the buttons that you create and then use the guigetmsg() to wait for a button to be pressed, then display your message based on the button.   I'm doing this from a phone but you need array $button[$rows][$col]= guictrlcreatebutton("args", etc) 

Then when a button is pressed associate it with the action using a case statement.   Running the $sidearray through a loop after the buttons are created essentially does nothing.   The message in the guigetmsg() is when the gui pops off an event bc a button is pressed if that button isn't associated with a variable (not the original array) then theres no link to the desired action.  (Using a variable inside the parameters of the button being created doesNT make the button associated with that element in the array!)

 

You should probably be starting with 1 non array button and getting that to work the correct way then move up to the array scenario. 

Also when shuffling through arrays use Ubound()

 

 

Edited by markyrocks
zdf
Link to comment
Share on other sites

In a script I wrote some time ago, I needed a way to quickly and easily select one of many options. To do this I wrote a simple function (not very tested and perhaps to be improved) to create an array of controls (not just buttons) and I used the below way to check which control was clicked. Maybe it may interest you.
Here is the script if it can be of help.

#include <EditConstants.au3>

Example()

Func Example()

    GUICreate("Matrix of controls", 415, 350)
    GUISetState()

    ; create a matrix of controls (see function header for parameters details)
    Local $aMyMatrix = _GuiControlPanel("Button", 10, 13, 40, 20, 3, 75)

    ; create a "console" to view click action
    $hConsole = GUICtrlCreateEdit('Hello', 3, 3, 408, 70, BitOR($ES_READONLY, $ES_MULTILINE))
    GUICtrlSetBkColor(-1, 0)
    GUICtrlSetColor(-1, 0x00FF00)
    GUICtrlSetFont(-1, 12, 0, 0, "Courier New")

    ; Main loop - check which control was clicked
    ; ---------
    Do
        $GUIGetMsg = GUIGetMsg()

        ; scan all buttons to check if one was pressed
        For $i = 1 To UBound($aMyMatrix) - 1
            If $GUIGetMsg = $aMyMatrix[$i] Then
                GUICtrlSetData($hConsole, "Click on button " & $i & @CRLF & GUICtrlRead($hConsole))
            EndIf
        Next

    Until $GUIGetMsg = -3 ; -3 = $GUI_EVENT_CLOSE
EndFunc   ;==>Example


;
; #FUNCTION# ====================================================================================================================
; Name...........: _GuiControlPanel
; Description ...: Creates a rectangular panel with adequate size to contain the required amount of controls
;                  and then fills it with the same controls by placing them according to the parameters
; Syntax.........: _GuiControlPanel( $ControlType, $nrPerLine, $nrOfLines, $ctrlWidth, $ctrlHeight, $xPos = 0, $yPos = 0, $xBorder, $yBorder, $xSpace = 1, $ySpace = 1)
; Parameters ....: $ControlType  - Type of controls to be generated ("Button"; "Text"; .....
;                  $nrPerLine  - Nr. of controls per line in the matrix
;                  $nrOfLines - Nr. of lines in the matrix
;                  $ctrlWidth - Width of each control
;                  $ctrlHeight - Height of each control
;                  $xPanelPos - x Position of panel in GUI
;                  $yPanelPos - y Position of panel in GUI
;                  $xBorder - distance from lateral panel's borders to the matrix (width of left and right margin) default = 0
;                  $yBorder - distance from upper and lower panel's borders to the matrix (width of upper and lower margin) default = 0
;                  $xSpace - horizontal distance between the controls
;                  $ySpace - vertical distance between the controls
;                  $Group - if you want to group the controls (true or false)
;                  $sGrpTitle - title of the group (ignored if above is false)
; Return values .: an 1 based 1d array containing references to each control
;                  element [0] contains an 1d array containing various parameters about the panel
; Author ........: Gianni Addiego (Chimp)
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================

Func _GuiControlPanel($ControlType, $nrPerLine, $nrOfLines, $ctrlWidth, $ctrlHeight, $xPanelPos = 0, $yPanelPos = 0, $xBorder = 0, $yBorder = 0, $xSpace = 1, $ySpace = 1, $Group = False, $sGrpTitle = "")

    Local Static $sAllowedControls = "|Label|Input|Edit|Button|CheckBox|Radio|List|Combo|Pic|Icon|Graphic|"
    If Not StringInStr($sAllowedControls, '|' & $ControlType & '|') Then Return SetError(1, 0, "Unkown control")

    Local $PanelWidth = (($ctrlWidth + $xSpace) * $nrPerLine) - $xSpace + ($xBorder * 2)
    Local $PanelHeight = (($ctrlHeight + $ySpace) * $nrOfLines) - $ySpace + ($yBorder * 2)

    Local $hGroup

    If $Group Then
        If $sGrpTitle = "" Then
            $xPanelPos += 1
            $yPanelPos += 1
            $hGroup = GUICtrlCreateGroup("", $xPanelPos - 1, $yPanelPos - 7, $PanelWidth + 2, $PanelHeight + 8)
        Else
            $xPanelPos += 1
            $yPanelPos += 15
            $hGroup = GUICtrlCreateGroup($sGrpTitle, $xPanelPos - 1, $yPanelPos - 15, $PanelWidth + 2, $PanelHeight + 16)
        EndIf
    EndIf

    ; create the controls
    Local $aGuiGridCtrls[$nrPerLine * $nrOfLines + 1]
    Local $aPanelParams[14] = [ _
            $ControlType, $nrPerLine, $nrOfLines, $ctrlWidth, $ctrlHeight, _
            $xPanelPos, $yPanelPos, $xBorder, $yBorder, $xSpace, $ySpace, $PanelWidth, $PanelHeight, $hGroup]

    For $i = 0 To $nrPerLine * $nrOfLines - 1
        ; coordinates 1 based
        $col = Mod($i, $nrPerLine) + 1 ; Vertical position within the grid (row) $iVtab
        $row = Int($i / $nrPerLine) + 1 ;  Horizontal position within the grid (column) $iHtab
        $left = $xPanelPos + ((($ctrlWidth + $xSpace) * $col) - $xSpace) - $ctrlWidth + $xBorder
        $top = $yPanelPos + ((($ctrlHeight + $ySpace) * $row) - $ySpace) - $ctrlHeight + $yBorder
        $text = $i + 1 ; "*" ; "." ; "(*)"

        $aGuiGridCtrls[$i + 1] = Execute("GUICtrlCreate" & $ControlType & "($text, $left, $top, $ctrlWidth, $ctrlHeight)")
    Next

    If $Group Then GUICtrlCreateGroup("", -99, -99, 1, 1) ; close group
    $aGuiGridCtrls[0] = $aPanelParams
    Return $aGuiGridCtrls
EndFunc   ;==>_GuiControlPanel

 

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

as @markyrockssayd using 2d arrays you may complicate things (expecially if you are not familiar with arrays)
anyway if you like that way, here a possible way to go

good luck

#include <GUIConstantsEx.au3>
Global $aBtnIds[3][3] ; <- I suppose you need a 3 x 3 buttons grid
; change the above dimensions for a larger/smaller grid

Local $Rows = UBound($aBtnIds)
Local $Cols = UBound($aBtnIds, 2)
Local $Element
$hGui = GUICreate('Buttontest', 110, 110)
; $j = 0
; While $j <= 2
For $j = 0 To $Rows - 1
    For $i = 0 To $Cols - 1
        $Element = $j * $Cols + $i
        $aBtnIds[$j][$i] = GUICtrlCreateButton($j + 1 & ':' & $i + 1, 10 + (Mod($Element, $Cols) * 30), 10 + (Int($Element / $Cols) * 30), 25, 25)
    Next
Next
; $j = $j + 1
; WEnd
GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
            ; Case $aBtnIds[0][0] To $aBtnIds[3][3] ; <-- wrong use of 2d array
    EndSwitch

    For $j = 0 To $Rows - 1
        For $i = 0 To $Cols - 1
            If $msg = $aBtnIds[$j][$i] Then
                MsgBox(0, 'Button', 'Row ' & $j + 1 & '  Col ' & $i + 1 & ' was clicked') ; , 0, $hGui)
            EndIf
        Next
    Next
WEnd

 

Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

#include <GUIConstants.au3>

Global $aBtnIds[3][3]
$hGui = GUICreate('Buttontest', 110, 110)
$iNum = 0
For $y = 0 To 2
  For $x = 0 To 2
    $iNum += 1
    $aBtnIds[$x][$y] = GUICtrlCreateButton($iNum, 10 + $x * 30, 10 + $y * 30, 25, 25)
  Next
Next
GUISetState()

While 1
  $msg = GUIGetMsg()
  Switch $msg
    Case $GUI_EVENT_CLOSE
      Exit
    Case $aBtnIds[0][0] To $aBtnIds[2][2]
      MsgBox(0, 'Button', 'No. ' & GUICtrlRead($msg) & ' was clicked', 0, $hGui)
  EndSwitch
WEnd

The max is $aBtnIds[2][2] !

Edited by Nine
Link to comment
Share on other sites

Thanks, everyone.  I'm used to coding in C#, and I've been using 2d arrays for about 30 years.  It may be that I am just not used to autoIT reserve words and functions yet, so I appreciate the help.  Nine, your solution/fix works great.  Appreciated!

So I made the changes necessary to bring it back into my original application, and, for some reason, the focus is not on the array, so the $msg=GUIGetMsg() never executes. I'm guessing it is because I changed GUICreate to GUICtrlCreateLabel to reuse the frame on the same page.  How do I bring focus back to Frame_x so I can finish the function?

 

Func Select_Cabins($Color)
    Global $aBtnIds[8][85]
;$hGui = GUICreate('Buttontest', 510, 910)
    $iNum = 0
    $Frame_x_Top = 250
    $Frame_x_Left = 5
    $Frame_x = GUICtrlCreateLabel ("Cabins", $Frame_x_Left, $Frame_x_Top, 1300, 900, -1, $SS_BLACKFRAME)
;GUICtrlSetState ( $Frame_x, $GUI_DISABLE)
    $Left = $Frame_x_Left
    $Top = $Frame_x_Top
    ;$Frame_x = GUICreate ("Cabins", 1300, 900)
    ;$Frame_x = GUICtrlCreateLabel ("Cabins", $Frame_x_Left, $Frame_x_Top, 1300, 900, -1, $SS_BLACKFRAME)
    GUICtrlSetState ( $Frame_x, $GUI_DISABLE)
    $Width =  15
    $Hight =  30
    ;$Top =  100
    ;$Left =  10
For $x = 0 To 7
    For $y = 0 To 84
    $iNum += 1
    $aBtnIds[$x][$y] = GUICtrlCreateButton($iNum,$Left,$Top,$Width,$Hight,-1,-1)
    $Left =  $Left + $Width
    Next
    $Top =  $Top +  $Hight
    $Left =  10
Next
GUISetState()
While 1
  $msg = GUIGetMsg()
  Switch $msg
    Case $GUI_EVENT_CLOSE
      Exit
    Case $aBtnIds[0][0] To $aBtnIds[7][84]
      MsgBox(0, 'Button', 'No. ' & GUICtrlRead($msg) & ' was clicked', 0, $Frame_x)
  EndSwitch
WEnd
    EndFunc
 

Edited by BGarr33434
still debugging
Link to comment
Share on other sites

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>

Select_Cabins("Blue")



Func Select_Cabins($Color)
    Global $aBtnIds[8][85]
$hGui = GUICreate('Buttontest', @DesktopWidth, @DesktopHeight)
    $iNum = 0
    $Frame_x_Top = 250
    $Frame_x_Left = 5
    ;$Frame_x = GUICtrlCreateLabel ("Cabins", $Frame_x_Left, $Frame_x_Top, 1300, 900, -1, $SS_BLACKFRAME)
;GUICtrlSetState ( $Frame_x, $GUI_DISABLE)
    $Left = $Frame_x_Left
    $Top = $Frame_x_Top
    ;$Frame_x = GUICreate ("Cabins", 1300, 900)
    ;$Frame_x = GUICtrlCreateLabel ("Cabins", $Frame_x_Left, $Frame_x_Top, 1300, 900, -1, $SS_BLACKFRAME)
;~     GUICtrlSetState ( $Frame_x, $GUI_DISABLE)
    $Width =  15
    $Hight =  30
    ;$Top =  100
    ;$Left =  10
For $x = 0 To 7
    For $y = 0 To 84
    $iNum += 1
    $aBtnIds[$x][$y] = GUICtrlCreateButton($iNum,$Left,$Top,$Width,$Hight,-1,-1)
    $Left =  $Left + $Width
    Next
    $Top =  $Top +  $Hight
    $Left =  10
Next
GUISetState()
While 1
  $msg = GUIGetMsg()
  Switch $msg
    Case $GUI_EVENT_CLOSE
      Exit
    Case $aBtnIds[0][0] To $aBtnIds[7][84]
      MsgBox(0, 'Button', 'No. ' & GUICtrlRead($msg) & ' was clicked',1)
  EndSwitch
WEnd
    EndFunc

from what i can tell you must have been making a label the same size as the original gui and disabling it.  for future reference post code that has all the includes ect so people don't have to track that kinda stuff down so the variables don't kickoff errors.  but what i posted works.  

Link to comment
Share on other sites

Yes, because frame_x is one of three frames on the screen.  I enable the other two frames so that the buttons on those frames are not active.  I'm enjoying learning AutoIT.  My reserve word knowledge is minimal at this point.

Edited by BGarr33434
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...