BlackFlag

Creating combo boxes on the fly

12 posts in this topic

#1 ·  Posted (edited)

I need to create labels and combo boxes on the fly.  The actual number of labels/combos I need depends on the first line of a csv file.  However, the problem is shown by this much reduced and only slightly different code.

#include <Constants.au3>
#include <GUIConstants.au3>
$position=25
$Working_Window = GUICreate("Example", 271, 510, 192, 114)
GUISetState(@SW_SHOW)
for $x=1 to 8
   $UseCombo="$Combo"&$x
   MsgBox(1,"Value of $useCombo",$useCombo)
   $Usenumber=GUICtrlCreateLabel($UseCombo, 8, $position, 100, 17)
   $UseCombo=GUICtrlCreateCombo("", 136,$position,113, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))
   ;Fill the combo
   GUICtrlSetData($UseCombo,"DB Field|Latitude|Longitude|Name|Symbol|Color|Depth|Temperature|Catch|Comment", "DB Field")
   $position=$position+24
Next
MsgBox(1,"1","1") ;used just to pause the display
$A=GUICtrlRead($Combo1)
MsgBox(1,"Well",$A)

The GUI is created correctly as far as I can tell.  However, when I try to read one of the Combo boxes --$A=GUICtrlRead($Combo1)-- I get an error that reads "Variable used without being declared."

Is what I am trying to do possible?  If so, how do I avoid the error?

Edited by BlackFlag

Share this post


Link to post
Share on other sites



BlackFlag,

You continually overwrite the $UseCombo variable with the ControlID of the combos as you create them - you do not create a new variable each time. If you need to read all of the combos the you need to save each ControlID - and an array is the easiest way to do this: :)

#include <GUIConstantsEx.au3>
#include <ComboConstants.au3>

$position = 25
$iCount = 8 ; How many combos?

$Working_Window = GUICreate("Example", 271, 510, 192, 114)

GUISetState(@SW_SHOW)

Global $aCombo[$iCount + 1] ; Create an array to hold the ControlIDs
For $x = 1 To 8
    $UseCombo = "$Combo" & $x
    $Usenumber = GUICtrlCreateLabel($UseCombo, 8, $position, 100, 17)
    $aCombo[$x] = GUICtrlCreateCombo("", 136, $position, 113, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)) ; Save the ControlID into the array
    ;Fill the combo
    GUICtrlSetData($aCombo[$x], "DB Field|Latitude|Longitude|Name|Symbol|Color|Depth|Temperature|Catch|Comment", "DB Field")
    $position = $position + 24
Next

MsgBox(1, "1", "1") ;used just to pause the display

; Now read the first combo using the [1] element of the array
$A = GUICtrlRead($aCombo[1])

MsgBox(1, "Well", $A)
If you are unused to working with arrays, I recommend the Arrays tutorial in the Wiki. ;)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

This was meant to be a quick and dirty way to convert a ton of information so I am likely to use your code. 

However, I don't understand why I am continually overwriting the $UseCombo variable with the ControlID of the combos.  $UseCombo is changing by one with each trip through the For...Next loop as can be told by the label, so I would assume the ControlID would also change.  If I were to create the control by

$Combo1=GUICtrlCreateCombo("", 136,Real-position,113, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))

...

$Combo8=GUICtrlCreateCombo("", 136,Real-position,113, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))

the combo boxes would work.  "$UseCombo="$Combo"&$x"  should create $Combo1 through $Combo8 as the ContolID

I am assuming that I am missing something basic here.

Share this post


Link to post
Share on other sites

BlackFlag,

 

I am assuming that I am missing something basic here

Indeed you are. :)

 

$UseCombo is changing by one with each trip through the For...Next loop as can be told by the label

Correct - you assign a new value to the variable with this line:

$UseCombo="$Combo"&$x
Where you misunderstand is saying:

I would assume the ControlID would also change. If I were to create the control by $Combo1=GUICtrlCreateCombo(...)

as that is not what happens.

What you actually do with that line is assign the value returned by the GUICtrlCreateCombo function - the ControlID of that combo - to the $UseCombo variable, overwriting the count value you had before. Trying to assign variables by name is fraught with problems - requiring the use of Assign & Eval - and using an array as I suggested is much better practice. ;)

Clearer now? :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Basically simply put Melba23 is saying that with your loop this is what's going on:

When you start your variable $UseCombo is empty or = ""

Loop starts

$x = 1

$UseCombo = "$Combo1"       <---- variable $UseCombo now holds a string value of "$Combo1"

Loop continues
 
$x = 2
 
$UseCombo = "$Combo2"      <---- variable $UseCombo now holds a string value of "$Combo2"
 
Loop continues
 
$x = n                                       <--- and so on
 
$UseCombo = "$Combon"          
 
Loop Ends

 

 
 
Now the value of the variable $UseCombo is "$Combon", where n = max value of $x
Edited by mpower

Share this post


Link to post
Share on other sites

mpower,

Not quite. What I am saying is this:

Loop starts

$x = 1
$UseCombo = "$Combo1"                 ; variable holds a string "$Combo1"
$UseCombo=GUICtrlCreateCombo(...)     ; variable now holds the ControlID of the first combo

Loop continues

$x = 2
$UseCombo = "$Combo2"                 ; variable holds a string "$Combo2"
$UseCombo=GUICtrlCreateCombo(...)     ; variable now holds the ControlID of the second combo

etc...
The point is that the ControlID of the combo is always overwritten and is not set to the value of the $UseCombo variable as the OP appeared to think. AutoIt ControlIDs are in fact the index numbers of an internal array that holds data on all the native-created controls so that they can bee easily accessed - they cannot be "preset" by the user in the manner than the original script presupposed. :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

Oops thats what I meant :P thanks Melba23 :)

mpower,

Not quite. What I am saying is this:

Loop starts

$x = 1
$UseCombo = "$Combo1"                 ; variable holds a string "$Combo1"
$UseCombo=GUICtrlCreateCombo(...)     ; variable now holds the ControlID of the first combo

Loop continues

$x = 2
$UseCombo = "$Combo2"                 ; variable holds a string "$Combo2"
$UseCombo=GUICtrlCreateCombo(...)     ; variable now holds the ControlID of the second combo

etc...
The point is that the ControlID of the combo is always overwritten and is not set to the value of the $UseCombo variable as the OP appeared to think. AutoIt ControlIDs are in fact the index numbers of an internal array that holds data on all the native-created controls so that they can bee easily accessed - they cannot be "preset" by the user in the manner than the original script presupposed. :)

M23

 

Share this post


Link to post
Share on other sites

Not really, I fail to see how this would be different from creating the combo boxes using a list.  If I were use $Combo1(etc), $Combo2(etc), these are correctly added to proper array by the GUICtrlCreateCombo function. 

If I create all of the need combo boxes when the interface is made.

1) I type Combo1 it is named $Combo1(  $Combo1=GUICtrlCreateCombo(...) )

2) $Combo1 is created as a combo box. (with a unique ID)

3) I type Combo2 it is name $Combo2

4) $Combo2 is created as a combo box. (with a unique ID)

In the next...for loop.

1) The Combo box name is created

2) It is written as a label (for demostration), the variable name has changed and is unique.

3) New control seems to be made (although apparently not with a unique ID).

4) The loop restarts the variable is x is advanced by one.

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Hi BlackFlag, I dont think you're thinking about it logically here is what's happening in your script:

 

 

Your loop, verbose, let's assume we're only running this loop once with the value of $x = 1:

For every value of $x from 1 to 1
 
   Set variable $UseCombo  to hold string "$Combo" & $x (e.g. if $x = 1, $UseCombo now holds a string value of "Combo1")
 
   Show a message box MsgBox(1,"Value of $useCombo",$useCombo) which shows the value of variable $UseCombo, (e.g. if $x = 1 then MsgBox should show "Combo1")
 
   Set variable $Usenumber  to hold the control ID of a label: GUICtrlCreateLabel($UseCombo, 8, $position, 100, 17), with the label containing the text string from variable $UseCombo (set in the 1st line of the loop).
   So now variable $Usenumber holds, for example, 0x83934050 - the Control ID of the Label you just created in the line above.
 
   Set variable $UseCombo to hold the control ID of a Combo box: GUICtrlCreateCombo("", 136,$position,113, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))
   Now variable $UseCombo holds, for example, 0x16235476 - the Control ID of the Combo Box you created in the line above. 
   
   Now you add the data to the Combo you just created via GUICtrlSetData($UseCombo,"DB Field|Latitude|Longitude|Name|Symbol|Color|Depth|Temperature|Catch|Comment", "DB Field")
   Set $position variable to previous value of variable $position + 24
 
End Loop
 
So at end of the First loop you have ended up with:
$Usenumber = 0x83934050 (the control ID of the 1st Label)
$UseCombo = 0x16235476  (the control ID of the 1st Combo Box)
 
Now Let's do a second loop with $x = 2 (in your case you're looping the same functions 8 times, this is just to demonstrate what is happening):
 
For every value of $x from 2 to 2
 
   Set variable $UseCombo  to hold string "$Combo" & $x (e.g. if $x = 2, $UseCombo now holds a string value of "Combo2")
 
   Show a message box MsgBox(1,"Value of $useCombo",$useCombo) which shows the value of variable $UseCombo, (e.g. if $x = 2 then MsgBox should show "Combo2")
 
   Set variable $Usenumber  to hold the control ID of a label: GUICtrlCreateLabel($UseCombo, 8, $position, 100, 17), with the label containing the text string from variable $UseCombo (set in the 1st line of the loop).
   So now variable $Usenumber holds, for example, 0x13494456 - the Control ID of the Label you just created in the line above.
 
   Set variable $UseCombo to hold the control ID of a Combo box: GUICtrlCreateCombo("", 136,$position,113, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))
   Now variable $UseCombo holds, for example, 0x99374654 - the Control ID of the Combo Box you created in the line above. 
   
   Now you add the data to the Combo you just created via GUICtrlSetData($UseCombo,"DB Field|Latitude|Longitude|Name|Symbol|Color|Depth|Temperature|Catch|Comment", "DB Field")
   Set $position variable to previous value of variable $position + 24
 
End Loop
 
So at end of the Second loop you have ended up with:
$Usenumber = 0x13494456 (the control ID of the 2nd Label)
$UseCombo = 0x99374654 (the control ID of the 2nd Combo Box)
 
 
Notice that with every increment of $x you are re-running the loop over again. So you are actually overwriting the value of the variables $Usenumber and $UseCombo multiple times. At the End I guarantee that you will only be able to deal with the last label you created and the last combo box you created. Because that's when the loop ended - when the value of $x is equal to 8. So the varuables  $Usenumber and $UseCombo would contain the control ID's of the 8th Label and Combo Box respectively.
Edited by mpower

Share this post


Link to post
Share on other sites

BlackFlag,

The misapprehension is here:

$Combo1 is created as a combo box. (with a unique ID)

You seem to expect a variable $Combo1 to be created and to hold the unique ControlID of the combo created at that point. However, you are using this line:

$UseCombo=GUICtrlCreateCombo(...)
which merely replaces the content of the $UseCombo variable (a literal string "$Combo1") with the ControlID of the created combo. You are NOT creating a variable named $Combo1 to hold that ControlID. To do that you would need to use the Assign function, which I would not recommend. Best practice would be to use an array as I suggested. :)

Does that help clear the fog? It is quite an important point and you really do need to grasp it. ;)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

Yeah, you finally it through my head :) .I was focusing on that fact that I was using $UseCombo as a variable while the documentation clearly shows $UseCombo was being used as the name of the control. 

Thanks for your time Melba23.  One of those "This should work--- oh damnit, it won't ever" sort of things....

Share this post


Link to post
Share on other sites

BlackFlag,

Excellent! :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

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