LIST

A box containing numerous lines of text. Each line is an "item" that the user can select (ie, highlight). There is a scroll bar immediately to the right which, if there are more items than can be simultaneously displayed in the box, can be used to scroll those other items into view. (The scroll bar is inoperable if all of the items in the list can be simultaneously displayed in the box). The user can select an item by clicking upon it with the mouse. By holding the mouse button down, and moving the mouse up and down, he can also scroll the list. Alternately, the up and down cursor keys can be used to cursor through the list, and the SPACE bar will select an item.

For multiple select list boxes, more than one item can be selected simultaneously. When an item is selected, its state toggles. (ie, If the item was not selected, selecting it highlights it. If the item was highlighted, selecting it unhighlights, or deselects it).


Uses

A List box is used to present items that a user can choose from, much like checkmark or radio buttons, except that a list box uses up less area if you have lots of items from which the user can choose. Multiple select lists function like CHECK marks, and single select lists function like RADIO or PUSH 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 list box to those preset strings whenever the list box is first displated. Select (none) if you do not wish the list 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 LIST box must be created with one of the following four styles:

Single Only one item at a time can be selected.
Multi Allows more than one item to be selected simultaneously (ie, multiple select).
Extended (XSEL) Allows multiple items to be selected by using the SHIFT key and the mouse or special key combinations.
No Select (NOSEL) Read-only list. The user can't select any item.

A LIST box may have any, all, or none of the following styles (in addition to one of the above):

Sort Items in the list are displayed and added in alphabetical order.
Horz. Scroll (HSCROLL) Adds a horizontal scroll bar to the LIST box. The control manages its own scroll events.
Vert. Scroll (VSCROLL) Adds a vertical scroll bar to the LIST box. The control manages its own scroll events.
Keep scrollbar (NOSCROLL)The vertical scroll bar is disabled 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.
Column A multicolumn list box that is scrolled horizontally. Send a SETCOLUMNWIDTH message to set the width (in pixels) of a column, passing the desired width for the third arg
(REALHEIGHT) The height of the list box is exactly the size you specified. Normally, Windows resizes a list box so that its box won't cut off the text of the last displayed item.
No Redraw (NOREDRAW) The list of items is not redrawn when a new item is added, or an item is deleted. This style can be changed at any time by sending a SETREDRAW message. It is useful to enable NOREDRAW before adding/removing a large number of items to a list box, and then disabling NOREDRAW when finished. This can speed things up since the list box does not need to redraw itself after each item is added/removed.
Notify Layout script's SELECT subroutine for this list box is called whenever the user clicks or double-clicks a string.
No data (NODATA) Specifies a no-data list box. Use this style when the count of items in the list box will exceed one thousand. A no-data list box must also have the Owner draw FIXED style, but must not have the SORT nor STRINGS styles.

A no-data list box resembles an owner-drawn list box except that it contains no string or bitmap data for an item. Commands to add, insert, or delete an item always ignore any specified item data; requests to find a string within the list box always fail. The system sends a DRAWITEM event to your window when an item must be drawn. The itemID member of the DRAWITEMSTRUCT structure passed to your WM_DRAWITEM subroutine specifies the line number of the item to be drawn. A no-data list box does not accept a DELETEITEM message.

Keys Layout script's WM_VKEYTOITEM or WM_CHARTOITEM subroutines are called whenever the user presses a key while the list box has input focus. This allows your script to perform special processing on the keyboard input.
Use tabs (TABS) Allows a list box to recognize and expand tab characters when drawing its strings. The default tab positions are 32 dialog units. (A dialog unit is a horizontal or vertical distance. One horizontal dialog unit is equal to one-fourth of the current dialog base width unit. The dialog base units are computed based on the height and width of the current system font. The GetDialogBaseUnits OS function returns the current dialog base units in pixels).
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.
Border Has a border.

If you wish to utilize an owner-draw list 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 SINGLE, MULTI, XSEL, or NOSEL style, plus any additional styles above):

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 list 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 LIST box can have the any, all, or none of 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

A LIST box generates the following 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. This event will not be reported if the NOTIFY style is not specified.

For a multiple-selection list box, the SELECT event occurs whenever the user presses an arrow key, even if the selection does not actually change.

DBLCLK The user has double-clicked a string in the list. This event will not be reported if the NOTIFY style is not specified.
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 list box is deactivated.
ERROR The list box can't allocate enough memory to meet a specific request.


REXX Variable

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

If the LIST box has the Multi style, then the REXX Variable is assumed to be a stem name. The total number of items selected is stored in the variable name that consists of the stem, and a .0 tail. For example, if you have associated the variable name MyStem with a list box, then the number of items you want selected in the list box will be in the variable MyStem.0, and the text (or indexes) of those selected items will be in the variables MyStem.1 (first selected item), MyStem.2 (second selected item), MyStem.3 (third selected item), etc.


Dynamically add/remove a LIST

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

LIST 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 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 LIST, 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 LIST at an X Y position of 10, 10, with a width and height of 100 and 80, with the styles TABS and BORDER, extra styles of CLIENTEDGE and QUIET, and a REXX Variable name of MyList. Its items are gotten from the STRING definition named MyList Strings. We select the item named "Item 1". ("Item 1" must appear within that STRING definition, or you will get a SYNTAX error).

MyList = "Item 1"
error = GuiAddCtl("LIST 10,10,100,80, TABS|BORDER, CLIENTEDGE|QUIET, MyList,, MyList Strings")
Note: If you wish the LIST to have no selected item, then either DROP its associated variable, or set the variable to an empty string. For a MULTI list, you can either DROP its variable, or set its count of selected items to 0.

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 LIST by calling GuiRemoveCtl. Here we remove the above control:

error = GuiRemoveCtl("MyList")

Change/Add items to a list

You can dynamically change the items in a LIST by calling GuiAddCtlText. You pass the quoted name of the REXX variable associated with the LIST. 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 MyList 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 MyList's contents to the above 3 items. */
GuiAddCtlText("MyList", "MyListItems")
Note: All items previously in the list box 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 MyList's contents to the items in the STRING block named "Strs1". */
GuiAddCtlText("MyList", "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 MyList's existing items. */
GuiAddCtlText("MyList", "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 list, you can call GuiSendMsg to send an ADDSTRING message to the list box. You'll directly pass the string to GuiSendMsg.

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

/* Add "Another string" to the end of MyList's existing items. */
MyVariable = "Another string"
GuiSendMsg("MyList", "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("MyList", "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 LIST. 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 MyList:

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


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("MyList")
If the list has the MULTI style, then you can select several items in the list simultaneously. You must set the count of how many items are selected, and then list each selected item. Here we select two items -- "This is item 1." and "This is item 3.":
MyList.0 = 2
MyList.1 = "This is item 1."
MyList.2 = "This is item 3."
GuiSetCtlValue("MyList")
To unselect all items from a list, DROP the variable:
DROP MyList
GuiSetCtlValue("MyList")
Alternately, for a MULTI list, you can set the count to 0:
MyList.0 = 0
GuiSetCtlValue("MyList")
Alternately, for a single select list, you can set the variable to an empty string:
MyList = ""
GuiSetCtlValue("MyList")


Querying the selected item

To determine which item(s) have 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("MyList")
IF error == "" THEN SAY "Selected item:" MyList
Note: If the list has the MULTI style, then a series of compound variables are set. For example, assume the above list was created with the MULTI style:
error = GuiGetCtlValue("MyList")
IF error == "" THEN DO

   SAY "There are" MyList.0 "selections:"

   DO i = 1 TO MyList.0

      SAY "Selection" i || ":" MyList.i

   END

END
Note: If there's no selection, then the rexx variable is DROP'ed:
error = GuiGetCtlValue("MyList")
IF error == "" THEN DO
   IF EXISTS("MyList") THEN SAY "Selected item:" MyList
   ELSE SAY "No selection"
END

Fill the list with filenames

You can fill a LIST box 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")