BGarr33434 Posted December 30, 2019 Share Posted December 30, 2019 (edited) 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. expandcollapse popupFunc 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 December 30, 2019 by JLogan3o13 Link to comment Share on other sites More sharing options...
Moderators JLogan3o13 Posted December 30, 2019 Moderators Share Posted December 30, 2019 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 More sharing options...
markyrocks Posted December 30, 2019 Share Posted December 30, 2019 (edited) 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 December 31, 2019 by markyrocks zdf Spoiler "I Believe array math to be potentially fatal, I may be dying from array math poisoning" Link to comment Share on other sites More sharing options...
BGarr33434 Posted December 31, 2019 Author Share Posted December 31, 2019 Thank you. I’ll work through that. Link to comment Share on other sites More sharing options...
Gianni Posted December 31, 2019 Share Posted December 31, 2019 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. expandcollapse popup#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 Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
BGarr33434 Posted December 31, 2019 Author Share Posted December 31, 2019 This doesn't work as a two dimensional array Global $aBtnIds[3][3] $hGui=GUICreate('Buttontest', 110, 110) $j=0 While $j <= 2 For $i = 0 To 2 $aBtnIds[$i][$j] = GUICtrlCreateButton($i + 1, 10 + Mod($i,3) * 30, 10 + Int($i/3) * 30, 25, 25) 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] MsgBox(0, 'Button', 'No. ' & $msg - $aBtnIds[0] + 1 & ' was clicked',0,$hGui) EndSwitch WEnd Link to comment Share on other sites More sharing options...
markyrocks Posted December 31, 2019 Share Posted December 31, 2019 Which part isn't working? The other question is why exactly does it need to be 2d? Spoiler "I Believe array math to be potentially fatal, I may be dying from array math poisoning" Link to comment Share on other sites More sharing options...
Gianni Posted December 31, 2019 Share Posted December 31, 2019 (edited) 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 December 31, 2019 by Chimp Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
Nine Posted December 31, 2019 Share Posted December 31, 2019 (edited) #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 December 31, 2019 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
BGarr33434 Posted December 31, 2019 Author Share Posted December 31, 2019 (edited) 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 December 31, 2019 by BGarr33434 still debugging Link to comment Share on other sites More sharing options...
Nine Posted December 31, 2019 Share Posted December 31, 2019 (edited) Please use this tool when you post code. Again, your code is not greatly written... Edited December 31, 2019 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
markyrocks Posted December 31, 2019 Share Posted December 31, 2019 expandcollapse popup#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. Spoiler "I Believe array math to be potentially fatal, I may be dying from array math poisoning" Link to comment Share on other sites More sharing options...
BGarr33434 Posted January 1, 2020 Author Share Posted January 1, 2020 (edited) 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 January 1, 2020 by BGarr33434 Link to comment Share on other sites More sharing options...
BGarr33434 Posted January 3, 2020 Author Share Posted January 3, 2020 At the end of the day, at 50,000 ft in the air, I decided it was much easier to use a one dimensional array. I only needed to display on 2 axis . but I really do appreciate the education. Thanks and happy new year to all markyrocks 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now