Jump to content

Need to dynamically create buttons and take actions.


 Share

Recommended Posts

I need to have a dynamically created set of GUI buttons and have actions taken based on a number that will be corresponding to each button press. I have created buttons dynamically before by assigning array entries to them so that I can manipulate the buttons colour and placement, but I have never made those dynamically created buttons have an actual function. I thought about doing a case for $nMsg for anything above 0 but I am not sure if that will always only correspond with the buttons that I create.

So do you know of a good way that I could acomplish this or will my idea work? The first button seems to throw a 3 always, then the second button send out a 4... So can I just take a > 2 value and subtract 2 from it and use that to access resources stored in an array corresponding to that number?

Link to comment
Share on other sites

For example, to put it simply, is there anything wrong with doing things this way?

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Global $Button[2], $iValueToWorkWith
#Region ### START Koda GUI section ### Form=
$hGUI = GUICreate("Test", 205, 106, -1, -1)
$Button[0] = GUICtrlCreateButton("Button1", 16, 16, 75, 25)
$Button[1] = GUICtrlCreateButton("Button2", 16, 56, 97, 25)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
    $nMsg = GUIGetMsg()
    Select
        Case $nMsg = $GUI_EVENT_CLOSE
            ConsoleWrite($nMsg & @CRLF)
            Exit

        Case $nMsg > 2
            ConsoleWrite(GUICtrlRead($nMsg) & ' ' & 'was pressed' & @CRLF)
            $iValueToWorkWith = $nMsg - 3
            GUIDelete($hGUI)
            ExitLoop

    EndSelect
WEnd

ConsoleWrite('The value to use in the rest of our script now is: ' & $iValueToWorkWith & @CRLF)
Link to comment
Share on other sites

  • Moderators

Morthawt,

personally, i always do it this way:

#include <GUIConstantsEx.au3>

Global $Button[2], $iValueToWorkWith

$hGUI = GUICreate("Test", 205, 106, -1, -1)
$iStart = GUICtrlCreateDummy() ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$Button[0] = GUICtrlCreateButton("Button1", 16, 16, 75, 25)
$Button[1] = GUICtrlCreateButton("Button2", 16, 56, 75, 25)
$iEnd = GUICtrlCreateDummy() ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            ConsoleWrite($nMsg & @CRLF)
            Exit

        Case $iStart To $iEnd ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            ConsoleWrite(GUICtrlRead($nMsg) & ' ' & 'was pressed' & @CRLF)
            $iValueToWorkWith = $nMsg - $iStart ; Adjust as required
            GUIDelete($hGUI)
            ExitLoop

    EndSwitch
WEnd

ConsoleWrite('The value to use in the rest of our script now is: ' & $iValueToWorkWith & @CRLF)
No need for hard-coded values this way. ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Morthawt,

personally, i always do it this way:

#include <GUIConstantsEx.au3>

Global $Button[2], $iValueToWorkWith

$hGUI = GUICreate("Test", 205, 106, -1, -1)
$iStart = GUICtrlCreateDummy() ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$Button[0] = GUICtrlCreateButton("Button1", 16, 16, 75, 25)
$Button[1] = GUICtrlCreateButton("Button2", 16, 56, 75, 25)
$iEnd = GUICtrlCreateDummy() ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            ConsoleWrite($nMsg & @CRLF)
            Exit

        Case $iStart To $iEnd ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            ConsoleWrite(GUICtrlRead($nMsg) & ' ' & 'was pressed' & @CRLF)
            $iValueToWorkWith = $nMsg - $iStart ; Adjust as required
            GUIDelete($hGUI)
            ExitLoop

    EndSwitch
WEnd

ConsoleWrite('The value to use in the rest of our script now is: ' & $iValueToWorkWith & @CRLF)
No need for hard-coded values this way. ;)

M23

 

Oh my.. I believe I understand what is going on there. Very sneaky indeed :D I love it!

Link to comment
Share on other sites

Now, building on this idea. That idea works directly if all I am doing is creating the buttons continually without break. What if I have other controls being created like tabs to break the buttons into sections? Then the next button no longer follows the track because the tab that was created now has an ID assigned to it so the button ends up getting the one after that. What would you suggest to negate the existence of the tabs so that the buttons still have their ID be a continuous number stream?

Link to comment
Share on other sites

Just working with concepts before I jump into my real coding. Are there any technical issues with this method?

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <TabConstants.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 615, 437, 192, 124)
$Main = GUICtrlCreateTab(16, 64, 577, 313)
GUICtrlCreateTabItem('Main')
$button = GUICtrlCreateButton("Button1", 24, 88, 75, 25)
Assign(GUICtrlGetHandle(-1), 1)
$button1p5 = GUICtrlCreateButton("Button1.5", 24, 120, 75, 25)
Assign(GUICtrlGetHandle(-1), 1.5)
$test = GUICtrlCreateTabItem('Secondary')
$button2 = GUICtrlCreateButton("Button2", 24, 88, 75, 25)
Assign(GUICtrlGetHandle(-1), 2)
GUICtrlCreateTabItem('Tertiary')
$button3 = GUICtrlCreateButton("Button3", 24, 88, 75, 25)
Assign(GUICtrlGetHandle(-1), 3)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

ConsoleWrite(GUICtrlGetHandle($test) & @CRLF)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

        Case $Main To $button3
            If IsDeclared(GUICtrlGetHandle($nMsg)) Then MsgBox(0, 0, Eval(GUICtrlGetHandle($nMsg)))

    EndSwitch
WEnd
Link to comment
Share on other sites

  • Moderators

Morthawt,

Why not use GUISwitch and so keep the buttons in a single block? ;)

#include <GUIConstantsEx.au3>

$Form1 = GUICreate("Form1", 615, 437, 192, 124)

$Main = GUICtrlCreateTab(16, 64, 577, 313)
$cTab_Main = GUICtrlCreateTabItem('Main')
$cTab_Sec = GUICtrlCreateTabItem('Secondary')
$cTab_Ter = GUICtrlCreateTabItem('Tertiary')
GUICtrlCreateTabItem('') ; Close the tab item structure <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
GUISetState(@SW_SHOW)

$iStart = GUICtrlCreateDummy()
GUISwitch($Form1, $cTab_Main) ; Select the tab to use <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$button1 = GUICtrlCreateButton("Button1", 24, 88, 75, 25)
$button1p5 = GUICtrlCreateButton("Button1.5", 24, 120, 75, 25)
GUISwitch($Form1, $cTab_Sec)
$button2 = GUICtrlCreateButton("Button2", 54, 88, 75, 25)
GUISwitch($Form1, $cTab_Ter)
$button3 = GUICtrlCreateButton("Button3", 84, 88, 75, 25)
GUICtrlCreateTabItem('')
GUICreate($Form1)
$iEnd = GUICtrlCreateDummy()

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $iStart To $iEnd
            ConsoleWrite(GUICtrlRead($nMsg) & ' was pressed - code ' & $nMsg - $iStart& @CRLF)
    EndSwitch
WEnd
M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

lol you really know you're AutoIt :D. So basically if I understand, by creating all the tabs first, then "changing" to each tab during creation, the buttons all have continuous ID numbers? Hmm, so I can do that next time, but are there any issues with my previous example that should make me do it this new way?

Link to comment
Share on other sites

  • Moderators

Morthawt,

 

you really know you're AutoIt

I rather hope so. :whistle:

 

the buttons all have continuous ID numbers

ControlIDs are the indices to an internal Autoit array which holds details of all the native created controls in the script. These ControlIDs are allocated in numerical order, so creating controls in immediate succession should give you consecutive values. The allocation is actually to the first vacant element in the array so if you have previously deleted some controls this is not guaranteed - and as it is undocumented it might not be true in future releases. Of course to be absolutely correct you should put the ControlIDs into an array and loop through it, but if you take care you can do as I did above. ;)

 

are there any issues with my previous example

Yes, it is a misuse of the Assign function which could well bite you later. :o

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Morthawt,

Yes, it is a misuse of the Assign function which could  well will  bite you later. :o

Another way to do this...

#include <GUIConstantsEx.au3>
#include <array.au3>

#AutoIt3Wrapper_Add_Constants=n

local $aButtons[13]

GUICreate("GUI Buttons")

For $i = 0 To UBound($aButtons)-1
    $aButtons[$i]=GUICtrlCreateButton($i+1,$i*30+5,20,25,25)
Next
GUISetState()
While 1
    $msg = guigetmsg()
    switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $aButtons[0] to $aButtons[ubound($aButtons)-1]
            MsgBox(1,1,"ButtonText=[" & GUICtrlRead($msg) & "] was clicked")
    EndSwitch
WEnd

kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

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...