COMBO

A combination of an ENTRY and LIST. The list is not visible until you click the mouse upon a small arrow immediately to the right of the entry. Then, the list drops down, and the user can manipulate it like a list. Otherwise, if he clicks inside of the entry box, he can then manipulate that part of it just like an entry. Whenever an item in the list is selected, it is automatically copied to the entry. He can also use the up and down arrow keys to select an item from the list.


Uses

Like a list box, this displays many choices to the user, but the entry also gives him the opportunity to type in some text that isn't currently in the list. So, it might be used for a situation where you want to present some default choices to the user, but then allow him to reject those and specify his own choice. It can also conserve screen space while achieving the same purpose as a LIST or group of RADIO buttons.


Styles

Contents The Contents field shows all of the STRINGS resources in your Window Layout script. (If you haven't yet inserted any Strings resources, then this list will be empty). You can pick out a STRINGS resource to have REXX GUI automatically initialize the combo box to those preset strings whenever the combo box is first displated. Select (none) if you do not wish the combo box to be automatically initialized to a particular set of strings whenever it is created.

Shortcut The Shortcut box lets you enter a keyboard shortcut that will automatically select this control whenever the user presses that shortcut.

A COMBO box must be created with one of the following three styles:

Simple (SIMPLE) The list of items is displayed at all times. The current selection in the list is displayed in the entry control, but the user can alternately enter a new item (that doesn't appear in the list) by typing into the entry.
Drop down (DROP) The list box is not displayed unless the user clicks on the small arrow next to the entry control. The current selection in the list is displayed in the entry control, but the user can alternately enter a new item (that doesn't appear in the list) by typing into the entry.
Preset (PRESET) The list box is not displayed unless the user clicks on the small arrow next to the entry control. The entry control is read-only, so it merely displays the currently selected item, and the user can't enter a new item (that doesn't appear in the list).

A SIMPLE or DROP style COMBO box may have any, all, or none of the following styles (in addition to SIMPLE or DROP):

Vert. Scroll (VSCROLL) The list has a scroll bar attached to its right side which the user can operate to scroll through the list of items.
Auto scroll (H_AUTO) Automatically scrolls text (in the entry box) to the right by 10 characters when the user types a character at the end of the entry. When the user presses the ENTER key, the control scrolls back to the first character.
Lowercase (LOWER) Converts all characters to lowercase as they are typed into the entry control.
Uppercase (UPPER) Converts all characters to uppercase as they are typed into the entry control.
Oem Text entered in the entry control is converted from the ANSI character set to the OEM character set and then back to ANSI. This ensures proper character conversion when the application calls the AnsiToOem Windows function to convert an ANSI string in the control to OEM characters. This style is most useful for controls that contain filenames.
Sort Items in the list are displayed and added in alphabetical order.
Keep scrollbar (NOSCROLL) Shows a disabled vertical scroll bar for the list box when the box does not contain enough items to scroll. If you do not specify this style, the scroll bar is hidden when the list box does not contain enough items.
Keep Height (REALHEIGHT) The size of the list box is exactly the size you specified when created. Normally, the operating system resizes a combo box's list area so that it does not display partial items.
No Sibling (NOSIBLING) Prevents this control from drawing into any overlapping controls.
Group Marks this control as the first of a group of controls in which the user can move from one control to the next with the arrow keys. All subsequent controls (after this first control) belong to the same group up to the next control that has its GROUP flag set. (ie, One group ends where the next begins). For example, to make a group of radio buttons function properly, the first radio button should have the GROUP style, and the subsequent buttons must not.
Tabstop The user can move to this control using the TAB key.
Disabled Control is initially disabled. You can later enable it with a call to GuiSetCtlPlacement.
Hide Control is hidden. You can later make it visible with a call to GuiSetCtlPlacement.

A PRESET style COMBO box may have any, all, or none of the following styles (in addition to PRESET style):

Vert. Scroll As above.
Auto scroll As above.
SORT As above.
Keep scrollbar As above.
Keep Height As above.
No Sibling As above.
Group As above.
Tabstop As above
Disabled As above
Hide As above
Border Has a border.

If you wish to utilize an owner-draw combo box (ie, where your Window Layout script handles events to draw the contents of the list instead of having the operating system do that automatically) then you can specify one of the following styles (in addition to SIMPLE, DROP, or PRESET style, plus any additional styles for those):

Fixed The items in the list box are the same height.
Variable The items in the list box are variable height.

If you specify FIXED or VARIABLE, then you can also have the following style:

Strings The list contains items consisting of strings, and the combo box itself maintains the memory and addresses of the strings (so your script doesn't have to do that on its own). Your script can then send a GETTEXT message to retrieve the text for a particular item.


Extra styles

A COMBO box can have the following extra styles:

Item index (INDEX) Instead of returning the actual text of an item when it is selected, its index number (ie, where it appears in the list) is returned. The first item in the list has an index of 0.
Quiet Do not report any events for this control.
Modal Frame (MODALFRAME) Has a double border.
Static Edge (STATICEDGE) Has a three-dimensional border intended to be used for windows that do not accept user input.
Client Edge (CLIENTEDGE) Has a 3D look comprised of a border with a sunken edge.
Accept files (FILES) Accepts drag-and-drop files (ie, the DROPFILES event).
Align text right (RIGHT) Gives the control generic right-aligned properties (as opposed to the default of left-aligned properties).
Read right-to-left (RTLREADING) Displays the window text using right-to-left reading order properties (instead of the default of left-to-right).
Left Scrollbar (LEFTBAR) The scroll bar is placed upon the left side of the list (instead of the right side).
Transparent The control is to be transparent. Any controls that are beneath this one are not obscured.


Events

All COMBO boxes generate the following basic set of events:

Event name When it occurs
SELECT The user has changed the selected item in the list either by clicking on an item in the list, or by using the arrow keys.
FOCUS The user has made the control activated, and therefore may be prepared to operate it.
UNFOCUS The user has selected another control or some other window, and therefore the combo box is deactivated.
ERROR The combo box can't allocate enough memory to meet a specific request.

A SIMPLE style combo also generates the following events (in addition to the basic set of events above):

Event name When it occurs
DBLCLK The user has double-clicked a string in the list.
UPDATE The user is about to alter the text in the entry box. This event occurs before the ENTRY's text is redrawn with the new alteration.
INPUT The user may have altered the text in the entry box. Unlike the UPDATE event, this event occurs after the entry's text is updated and redrawn with any alterations.
OK The user has selected an item in the list. This event indicates that the user's selection is to be processed. In a combo box with the SIMPLE style, the OK event occurs immediately before every SELECT event.

A DROP style combo also generates the following events (in addition to the basic set of events above):

Event name When it occurs
UPDATE The user is about to alter the text in the entry box. This event occurs before the ENTRY's text is redrawn with the new alteration. This event does not occur for a combo box with a PRESET style.
INPUT The user may have altered the text in the entry box. Unlike the UPDATE event, this event occurs after the entry's text is updated and redrawn with any alterations. This event does not occur for a combo box with a PRESET style.
DROP The list is about to be made visible because the user has clicked on the small icon next to the ENTRY.
CLOSE The list has been folded up so that its items are no longer visible. Note: You can't predict the order in which events happen. In particular, a SELECT event may occur either before or after a CLOSE event.
OK The user has selected an item in the list, and perhaps has also closed the list. This event indicates that the user's selection is to be processed.
CANCEL The user has selected an item in the list, but then has selected another control or wants to close the window that contains the combo box. This event indicates the user's initial selection is to be ignored.

A PRESET style combo also generates the following events (in addition to the basic set of events above):

Event name When it occurs
DROP The list is about to be made visible because the user has clicked on the small icon next to the ENTRY.
CLOSE The list has been folded up so that its items are no longer visible. Note: You can't predict the order in which events happen. In particular, a SELECT event may occur either before or after a CLOSE event.
OK The user has selected an item in the list, and perhaps has also closed the list. This event indicates that the user's selection is to be processed.
CANCEL The user has selected an item in the list, but then has selected another control or wants to close the window that contains the combo box. This event indicates the user's initial selection is to be ignored.


REXX Variable

A COMBO box must have a REXX variable associated with it. Before opening the window which contains the control, you must set this variable's value to the text of the item you wish selected (or if the "Item index" style is specified, then the item number to select where the first item is 0, the second item is 1, etc).


Dynamically add/remove a COMBO

You can dynamically add a COMBO box to an already open window by calling GuiAddCtl. You must pass a line that describes the control. The format for this line is:

COMBO X, Y, Width, Height, Styles, ExtraStyles, VariableName, Accelerator, Contents
X and Y is the position of the top left corner of the control, relative to the window's top left corner.

Width and Height are the size of the control, in pixels.

Styles and ExtraStyles are those listed above, with each style separated by a | character.

VariableName is the variable name to be associated with the control.

Accelerator is the keyboard shortcut that causes the control to be selected for user input.

Contents describes the items that are initially presented in the dropdown list. This must be the name of some STRING definition. That STRING definition's contents will be placed into the list box. If you prefer, you can omit this field, and set the contents of the list manually by calling GuiAddCtlText (described below).

If you specify Contents, then before adding a COMBO, you should set its associated REXX variable to either the text of the item you wish selected, or the index number of that item (if using the INDEX extra style).

For example, here we add a COMBO at an X Y position of 10, 10, with a width and height of 100 and 80, with the style BORDER, extra styles of CLIENTEDGE and QUIET, and a REXX Variable name of MyCombo. Its items are gotten from the STRING definition named MyCombo Strings. We select the item named "Item 1". ("Item 1" must appear within that STRING definition, or you will get a SYNTAX error).

MyCombo = "Item 1"
error = GuiAddCtl("COMBO 10,10,100,80, BORDER, CLIENTEDGE|QUIET, MyCombo,, MyCombo Strings")
Note: If you wish the COMBO to have no selected item, then either DROP its associated variable, or set the variable to an empty string.

If you do not specify that the items are to be gotten from some STRING definition, then after you call GuiAddCtl, you must call GuiAddCtlText to add the items to the list, and then call GuiSetCtlValue to select the desired item. See below for details.

You can dynamically remove a COMBO by calling GuiRemoveCtl. Here we remove the above control:

error = GuiRemoveCtl("MyCombo")

Change/Add items to a list

You can dynamically change the items in a COMBO by calling GuiAddCtlText. You pass the quoted name of the REXX variable associated with the COMBO. You also pass the quoted name of a stem variable that has been initialized to all of the items in the list. A tail name of 0 holds the count of items. Then, a tail of 1 is the first item, a tail of 2 is the second item, a tail of 3 is the third item, etc. For example, here we setup a variable named MyListItems to contain a list of 3 items named "This is item 1", "This is item 2", and "This is item 3". Then we call GuiAddCtlText to set these items into our above MyCombo control:

/* Initialize 3 items in MyListItems. */
MyListItems.0 = 3
MyListItems.1 = "This is item 1."
MyListItems.2 = "This is item 2."
MyListItems.3 = "This is item 3."

/* Set MyCombo's contents to the above 3 items. */
GuiAddCtlText("MyCombo", "MyListItems")
Note: All items previously in the list are cleared out.

Alternately, you can pass a third, Option arg of "STRING" if you want the items to be fetched from one of the STRING definitions you created with the Window Editor. In this case, you pass the name you gave to that STRING definition. You can pass this as either a quoted string, or the value of some variable.

/* Set MyCombo's contents to the items in the STRING block named "Strs1". */
GuiAddCtlText("MyCombo", "Strs1", "STRING")
If you want to retain the existing items in the list, while adding some new items to the start or end of the existing items, then also specify the "PREPEND" or "APPEND" option, respectively.
/* Prepend the items in the STRING block named "Strs1" to MyCombo's existing items. */
GuiAddCtlText("MyCombo", "Strs1", "STRING | PREPEND")
Note: If using the SORT style, then the items will be reordered alphabetically when added to the list box. It is not advisable to use the INDEX and SORT styles together as you lose any correlation between the original indexes and the final sorted order of the items.

To add a single item to the end of a COMBO's list, you can call GuiSendMsg to send an ADDSTRING message to the combo box. You'll directly pass the string to GuiSendMsg.

/* Add "My string" to the end of MyCombo's existing items. */
GuiSendMsg("MyCombo", "ADDSTRING", , "My string")

/* Add "Another string" to the end of MyCombo's existing items. */
MyVariable = "Another string"
GuiSendMsg("MyCombo", "ADDSTRING", , MyVariable)

To insert a single item somewhere in a list of existing items, you can call GuiSendMsg to send an INSERTSTRING message to the list box. You'll directly pass the string to GuiSendMsg, and also pass the index number (where 0 would be to insert the string at the beginning of the list, 1 would be to insert the string after the first, existing item, etc. A -1 would insert the string at the end of the list).

/* Insert "My string" as the third item. */
GuiSendMsg("MyCombo", "INSERTSTRING", 2, "My string")


Delete items from a list

You can delete an item by calling GuiRemoveCtlText. You pass the quoted name of the REXX variable associated with the COMBO. You also pass the either the text of the item you wish to delete, or if using the INDEX extra style, you instead pass the index of the item (where 1 is the first item, 2 is the second item, etc). Here we delete "This is item 2." from MyCombo:

error = GuiRemoveCtlText("MyCombo", "This is item 2.")
Assuming we were using the INDEX extra style, here we delete item #3:
error = GuiRemoveCtlText("MyCombo", 3)
To delete the currently selected item from the list, then call GuiRemoveCtlText, and pass an empty string for the item to delete:
error = GuiRemoveCtlText("MyCombo", "")
To delete all items from the list (ie, clear out the list), then call GuiRemoveCtlText, and pass only the name of the variable associated with the control:
error = GuiRemoveCtlText("MyCombo")


Selecting an item

To select an item, first set the associated REXX variable to the text of the desired item, or the desired index number if using INDEX extra style. Then call GuiSetCtlValue, passing that quoted variable name. Here we select "This is item 1.":

MyList = "This is item 1."
GuiSetCtlValue("MyCombo")
To unselect all items from a list, DROP the variable:
DROP MyList
GuiSetCtlValue("MyCombo")
Alternately, you can set the variable to an empty string:
MyList = ""
GuiSetCtlValue("MyCombo")


Querying the selected item

To determine which item has been selected, call GuiGetCtlValue. This will set its associated REXX variable to the control's current selection. For example, here we query the above control's selection:
error = GuiGetCtlValue("MyCombo")
IF error == "" THEN SAY "Selected item:" MyCombo
Note: If there's no selection, then the rexx variable is DROP'ed:
error = GuiGetCtlValue("MyCombo")
IF error == "" THEN DO
   IF EXISTS("MyCombo") THEN SAY "Selected item:" MyCombo
   ELSE SAY "No selection"
END

Limit entered text

If you do not use the PRESET style, you can limit how many characters the user is allowed to type into a COMBO's box. You do this by sending a LIMITTEXT message. For the third arg, pass the desired number to characters to limit. For example, here we limit the user to entering 16 characters at most:

error = GuiSendMsg("MyCombo", "LIMITTEXT", 16)

Extended UI

For a drop down combo box, the F4 key normally opens or closes the list and the DOWN ARROW changes the current selection. But you can change the COMBO to use extended user interface. In extended user interface, the F4 key is disabled and the DOWN ARROW key opens the drop-down list.

To enable or disable extended user interface, send a SETEXTENDEDUI message. For the third arg, pass a 1 to enable, or 0 to disable.


Fill the list with filenames

You can fill a COMBO's list with filenames by sending a DIR message. For the third arg, pass a numeric sum of which types of files you desired. Add any of the following values:

Value Type of file
1 List files marked as Read-only.
2 List hidden files.
4 List system files.
16 Also search files in any sub-directories.
32 List archived files.
16384 List drives.
32768 List only files that are of the specified types above. Note: Normal files are always listed regardless of any types picked out above.

For the fourth arg, pass a file specification. For example, here we list all files in the directory "C:\MyDir" that end with a .TXT extension. We include archived files, and search sub-directories as well:

error = GuiSendMsg("MyCombo", "DIR", 16 + 32, "C:\MyDir\*.txt")