v8listbox.jpg

The list box item allows the display and selection of multiple text strings. A list box has a vertical scroll bar that is used to scroll through the list of text strings when there are more strings than can be displayed within the list box item at one time.

List boxes can have multiple columns. Each column can have its own type of justification. Within a given row, there is one list box cell for every column. A list box with three columns would have three cells per row. An option exists when defining the list box to either allow selection of only whole rows or to allow individual cells to be selected. The handling of the selection of rows within a list box is defined by the attributes of the list box and the operational mode the list box is using. MicroStation uses four Motif Selection Modes: Single, Browse, Multiple and Extended which are described later in this section.

The list box item is designed to manipulate a string list. The list box item assumes that there is one string list member per list box cell. The string list members should be stored in row order. The first string list member corresponds to the list cell at row 0, column 0, the second string list member corresponds to the list cell at row 0, column 1, and so forth.

There must be at least one auxiliary information field associated with each string member in the string list. This is specified by setting the nInfoFields argument greater than or equal to one when calling mdlStringList_create. The list box item uses the first information field of each string list member to store selection and control information for each cell in the list box. This field must not be modified by the MDL programmer. If application data needs to be associated with each list box cell, that data can be placed in additional information fields.

Every list box should have an item hook function attached to it. When the item hook function receives the DITEM_MESSAGE_CREATE message it should indicate the list box's string list by calling mdlDialog_listBoxSetStrListP. The string list must be created prior to calling this function. The string list must have at least one auxiliary information field per member and be initialized with one string member for each cell in the list box. If no item hook function is attached to the list box or the hook function did not create and attach a string list to the list box, the list box item handler will allocate an empty string list with two auxiliary information fields and attach it to the list box.

When the item hook function receives the DITEM_MESSAGE_DESTROY it should generally destroy the string list that the list box is manipulating. The usual reason for not destroying the string list is when it will be used in further processing, for example, plotting all the files that the user just selected. If no item hook function is associated with the list box or the hook function did not create the string list, the list box item handler will destroy the string list associated with the list box.

Additional rows can be added to the contents of a list box by inserting members into the string list that the list box is set to manipulate. This is done with the mdlStringList_insertMember function. Rows can be deleted from the contents of a list box by deleting members from the list box's string list. This is done with the mdlStringList_deleteMember function. The string that is displayed within an individual list box cell can be changed by calling the mdlStringList_setMember function. Be certain, however, not to ever change a string list member's first auxiliary information field. To be on the safe side, the infoFieldsP argument to mdlStringList_setMember can always be set to NULL. Whenever the number of rows in a list box is changed, the mdlDialog_listBoxNRowsChanged function must be called or mdlDialog_listBoxSetStrListP can be called again.

The item hook function will receive a DITEM_MESSAGE_STATECHANGED message whenever the current selection changes.

In MicroStation V8, ListBoxes support horizontal scrollbars, resizable columns and column sorting, and a new data model called the ListModel. When using resizable columns with horizontal scrollbars, it is best to now explicitly set the width field in the item's extent when including the ListBox in a DialogItemListRsc. Also, the nRows field in the Ditem_ListBoxRsc can be usurped when the height field is explicitly set in the item's extent in either the DialogItemListRsc or when mdlDialog_itemSetExtent is called. This can be useful when a ListBox is in a resizable dialog box and the application needs to resize the ListBox based on the width and height of the dialog. Also, several new attributes have been added to the ListBox for MicroStation V8.

Item list specification

The DialogItemRsc field extent specifies the location of the list box. The x position specifies the location of the left side of the list box's beveled rectangle, not the start of the list box's text label. The y position specifies the top of the list box's beveled rectangle. The list box resource specification's column widths and nRows fields determine a list box's width and height. Therefore, set the item list's extent width and height to 0.

The type field should be ListBox.

The ID determines the DItem_ListBoxRsc instance to load.

The attributes field can be ON or OFF and optionally combined with HIDDEN. It will usually be ON.

The itemArg field is unused and should usually be set to 0.

The label field can override the label contained in the DItem_ListBoxRsc instance.

The auxInfo field is not used with list box items.

The following is an example of a list box item list specification:

{{XC, YC, 0, 0}, ListBox, LISTID_FileListFiles, ON, 0, "", ""}

Item Resource Specification

The list box item is defined in a resource file with the following structure:

typedef struct ditem_listcolumnrsc
{
int width;
int maxSize; // max # of chars in column
long attributes;
#if defined (resource)
char heading[];
#else
long headingLength;
char heading[1];
#endif
typedef struct ditem_listrsc
{
ULong helpInfo;
ULong helpSource;
long itemHookId;
long itemHookArg;
long attributes;
int nRows;
int sizeNumColumn;
#if defined (resource)
char label[];
DItem_ListColumnRsc listColumns[];
#else
long labelLength;
char label[1];
#endif

The DItem_ListBoxRsc structure has the following unique fields.

Field Description
attributes Specifies the list box's attributes. It is constructed by combining the constants from the attributes table (below) with the logical OR operator.
nRows Specifies the number of rows that will display.
sizeNumColumn Enables the list box handler to automatically number the rows. The maximum number of digits that can be used to number the rows must be specified. For example if a list can have up to 99 rows, specify 2 here. The rows will not be numbered if 0 is specified.
listColumns Represents an array of DItem_ListColumnRsc. This array will have one entry for each column in the list box. See the next table for a description of the DItem_ListColumnRsc structure.
attributes Value Meaning
LISTATTR_LABELONSIDE The list box's label will be placed to the left instead of at the default.
LISTATTR_NEVERSELECTION The user will be unable to select any part of the list. The list in this case is used only to view strings.
LISTATTR_DRAGSELECTION The user can select multiple rows by dragging the cursor or using the SHIFT and/or CTRL modifier keys when clicking on list box rows. Replaces the LISTATTR_RANGESELECTION attribute.
LISTATTR_DISJOINTSELECTION When combined with LISTATTR_DRAGSELECTION, this value indicates that multiple disjoint selections can be made.
LISTATTR_NOSELECTION The list does not require a selection to always be present.
LISTATTR_INDEPENDENTCOLS Individual cells, instead of entire rows, can be selected.
LISTATTR_NOKEYSEARCH Indicates that a pressed key does not cause a search thorugh the string list for a match on the first character in column 1 and position the list box pointer in that row.
LISTATTR_FIXEDFONT Indicates that a fixed width font should be used when displaying text in the list box.
LISTATTR_DYNAMICSCROLL Indicates that the list box contents should be scrolled as the user drags the scroll bar handle up and down in the list box scroll bar.
LISTATTR_COLOREDROWS Indicates that colored rows are to be used in this list box. If colored rows are to be used, the application must ensure that at least two auxiliary information fields are attached to the string list members for use by the list box item handler and tha t the color descriptor for the color to be used in the display of the row is stored in the second auxiliary information field. Specifying NULL in the second fields indicates that the default color should be used for display.
LISTATTR_DRAWOVERLAPPING Indicates that any items overlapping the list box are to be redrawn when the list box is drawn/updated.

The following attributes are new in MicroStation V8:

attributes Value Meaning
LISTATTR_DRAWPREFIXICON Indicates an icon will be drawn after a specified pixel offset and before the text in column 0.
When using StringLists, store the Icon ID in info field 2, the pixel offset in info field 3, the Icon Resource Type (RTYPE) in info field 4, and the Icon Owner in info field 5. For ListModel use, see ListModel documentation.
LISTATTR_TOOLFONTHEIGHT Row height will be equal to the current tool size (Workspace > Preferences > Tools > Tool Size)
LISTATTR_TRACKSCREENCOORD Indicates the application's motion function will be called with global coordinates as dragging of a row occurs.
LISTATTR_FONTBYCOLUMN Indicates a font index may be specified for each column within a row. When using StringLists, store the Font Index in info field 6.
LISTATTR_INDEPENDENTCOLS Indicates individual cells may be selected as opposed to the entire row.
LISTATTR_COLHEADINGBORDERS Border lines will be drawn around column headings.
LISTATTR_RESIZABLECOLUMNS Borders between columns become handles, allowing for resizing of column widths.
When using resizable columns, the ListBox width should be explicitly set in the DialogItemListRsc instead of specifying 0, which results in the ListBox width being determined by the widths of the columns.
LISTATTR_SEPARATORS Indicates a cell value of `-' will result in a separator line being drawn in the row, and the row will be unselectable.
LISTATTR_DLOGBGCOLOR Indicates the dialog background color will be used as the row background color instead of the normal item background color.
LISTATTR_HORIZSCROLLBAR A horizontal scrollbar will be activated when text for any row is beyond the width of the ListBox.
LISTATTR_SORTCOLUMNS The column headings become buttons which can be pressed, resulting in both ascending and descending sorting.
Sorting for certain columns may be turned off by calling mdlDialog_listBoxSetColInfoX with the sortStatus arg set to NOSORT.
LISTATTR_SAVECOLUMNINFO Column widths and sorting information are automatically saved to the prferences file.
LISTATTR_NOTRAVERSAL Indicates no traversal rectangle is to be drawn around the ListBox item.
LISTATTR_GRID Indicates a bounding box is to be drawn around each cell.
LISTATTR_NEWCOLHEADORIGIN Indicates the column heading origin is to be equal to the origin specified for the ListBox and not above the ListBox.
LISTATTR_EDITABLE Indicates each cell within the ListBox is editable.
LISTATTR_NOELLIPSES Columns will not show points of ellipsis (...) when truncated.
LISTATTR_RIGHTCLICKSTOHOOK Send right button clicks to hook function.

The following may be used in the ListColumnRsc attributes field with HIDDEN and ALIGN_*

attributes Value Meaning
LISTCOLATTR_NOSORT Used with LISTATTR_SORTCOLUMNS to indicate that a column is not sortable.
LISTCOLATTR_NOEDIT Used with LISTATTR_EDITABLE to indicated that a column is not editable.
LISTCOLATTR_EDITABLE This column is editable, regardless of LISTATTR_EDITABLE.
LISTCOLATTR_NOHIGHLIGHT This column is not highlightable.

The following attributes cause the MicroStation list box item handler to emulate various Motif style selection models for list boxes and should not be used in conjunction with any of the LISTATTR_xxxxSELECTION attributes documented above:

attributes Value Meaning
LISTATTR_SELSINGLE Emulate the Motif Single Selection model which allows the selection of a single row in the list box. Clicking on the row selects the row and deselects the previously selected row.
LISTATTR_SELBROWSE Emulate the Motif Browse Selection model which allows the selection of a single row in the list box. This model is the same as Single Selection, but additionally allows the user to browse the list box by dragging the cursor through the rows in the list box; highlighting each row as the cursor passes over it. Releasing the mouse button on a row selects the row and deselects the previously selected row.
LISTATTR_SELMULTI Emulate the Motif Multiple Selection model which allows the selection of multiple rows in the list box. Rows are added to or removed from the selection list by clicking on them with the mouse.
LISTATTR_SELEXTENDED Emulate the Motif Extended Selection model which allows the selection of multiple rows in the list box. This model is the same as Multiple Selection, but additionally allows the user to select a range of rows in the list box by dragging the cursor through the rows in the list box. Use if the SHIFT and/or CTRL modifier keys extends the selection capabilities of rows in the list box.

The DItem_ListColumnRsc structure has the following unique fields.

Field Description
width Specifies the column width in dialog coordinate units.
maxSize Specifies the maximum number of characters that display in the column.
attributes Specifies the column's attributes. The values listed in the attributes table below are valid.
heading Specifies a heading for the column. The heading will be justified above the column according to the justification bits in attributes.
attributes Value Meaning
ALIGN_LEFT Up to maxSize characters will be left-justified in a column that is width wide.
ALIGN_RIGHT Up to maxSize characters will be right-justified in a column that is width wide.
ALIGN_CENTER Up to maxSize characters will be centered in a column that is width wide.

The following is an example of a list box item resource. This item is used in the Open file dialog box, and is defined in MicroStation's resource file.

DItem_ListBoxRsc LISTID_FileListFiles=
{
{
{14*XC, 14, 0, ""},
}
};

Item hook function messages

The following messages are sent to item hook functions that are attached to list box items:

  DITEM_MESSAGE_CREATE 
  DITEM_MESSAGE_DESTROY 
  DITEM_MESSAGE_SYNCHRONIZE 
  DITEM_MESSAGE_BUTTON 
  DITEM_MESSAGE_KEYSTROKE 
  DITEM_MESSAGE_STATECHANGED 

List box item functions

Funtion Description
mdlDialog_listBoxDeleteAll deletes all columns from a list box.
mdlDialog_listBoxDeleteColumn deletes one column from a list box.
mdlDialog_listBoxDrawContents redraws all or part of the list's visible contents.
mdlDialog_listBoxEnableCells sets the state (enabled or disabled) of a range of cells.
mdlDialog_listBoxSetColInfo sets the attributes of a list box column
mdlDialog_listBoxGetColInfo gets the attributes of a list box column.
mdlDialog_listBoxGetDisplayRange returns the range of cells currently displayed in the list box.
mdlDialog_listBoxGetInfo gets the attributes of a list box.
mdlDialog_listBoxSetInfo sets the attributes of a list box.
mdlDialog_listBoxGetLocationCursor gets the location of the selection cursor in a list box.
mdlDialog_listBoxSetLocationCursor sets the location of the selection cursor in a list box.
mdlDialog_listBoxGetNColumns returns the number of columns in a list box.
mdlDialog_listBoxGetNextSelection obtains the next selected cell after the specified cell.
mdlDialog_listBoxGetSelectRange returns the range of selected cells. If non-contiguous selection is enabled, not every cell in the range will be selected.
mdlDialog_listBoxGetSelections returns the location of all currently selected cells.
mdlDialog_listBoxSetSelections extends the list of currently selected cells.
mdlDialog_listBoxGetStrListP returns a pointer to the stringList that is currently connected to the list box.
mdlDialog_listBoxSetStrListP sets the stringList that the list box will manipulate. This function must be called when the function receives the DITEM_MESSAGE_CREATE message. It can also be called any time a list box's underlying stringList is changed completely.
mdlDialog_listBoxInsertColumn inserts a column into an existing list box.
mdlDialog_listBoxIsCellSelected returns an indication of whether a given cell is selected.
mdlDialog_listBoxIsCellEnabled returns an indication of whether a given cell is enabled.
mdlDialog_listBoxLastCellClicked returns the cell that the last data button click occurred in.
mdlDialog_listBoxNRowsChanged should be called any time the number of rows in the stringList attached to the list box changes. Calling this function correctly resizes the list box's scroll bar.
mdlDialog_listBoxSelectCells selects (highlights) a range of cells.
mdlDialog_listBoxSetTopRow sets the top row that displays in the list box.
mdlDialog_listBoxSetTopRowRedraw sets which row is the first displayed in a list box and optionally redraws the list box.

The following functions are new MicroStation V8:

Funtion Description
mdlDialog_listBoxGetListModelP retrieves a pointer to the ListModel.
mdlDialog_listBoxSetListModelP sets the ListModel pointer in the ListBox.
mdlDialog_listBoxNRowsChangedRedraw similar to mdlDialog_listBoxNRowsChanged but also gives the option of redrawing or not.
mdlDialog_listBoxGetColInfoX gets information about the column, similar to mdlDialog_listBoxGetColInfo, but with additional arguments.
mdlDialog_listBoxSetColInfoX sets information about the column, similar to mdlDialog_listBoxSetColInfo, but with additional arguments.
mdlDialog_listBoxInsertColumnX inserts a column into an existing list box, similar to mdlDialog_listBoxInsertColumn, but with additional arguments.
mdlDialog_listBoxGetHeights retrieves several heights from a ListBox, including the row height, heading height, and label height.
mdlDialog_listBoxSetFilter changes the status of the filter for the specified list box.
mdlDialog_listBoxSetHighlightColumn sets the highlight column for the list box.
mdlDialog_listBoxGetEditCell gets the row and column of the cell being editred in the list box item.
mdlDialog_listBoxEditCell starts a cell editing session on the specified row and column in the list box item.


List boxes

If you have seen Bentley PowerDraft or MicroStation, you may have noticed the File Open/Create dialog boxes contain folder icons for each directory name, and the tool box selection dialog contains a list box containing check box icons. They are just two examples of an enhancement in the list box item handler that displays icons in a list box.

Modifying list boxes to include icons

// List box resource definition from LISTICON.R
DItem_ListBoxRsc LISTBOXID_Choices =
{
NOHELP, MHELP, HOOKITEMID_CheckListBox, NOARG,
5, 0, "",
{
{(WIDTH_FILEOPENDIRS_LISTBOX + 10)*XC, 30, 0, ""},
}
};
Listbox.jpg
Listbox_with_icons.jpg

The dialog font sizes vary from 8 to 24 points. Your application should have an icon to support each available font size. In the LISTBOX application, we have taken a few different approaches. The list box containing directory names uses small (16 x 12 pixels), medium (24 x 18 pixels) and large (32 x 24 pixels) icons, depending on the current dialog font size. The Choices list box uses a different icon for each dialog font size. For example, for 10 point dialog font, we created a 10 x 10 pixel icon (resource definition shown below).

// From USTATION.R
{
10, 10, FORMAT_MONOBITMAP, BLACK_INDEX, TXT_IconM67_ON,
{
0x00, 0x1f, 0xe6, 0x19, 0x4a, 0x4c, 0x93, 0x25, 0x29,
0x86, 0x7f, 0x80, 0x00,
}
};
// From listicon_checkListBoxHook() in LISTICON.MC
{
int fontHeight = mdlDialog_fontGetCurHeight(dimP->db);
int status;
DialogItem *diP = dimP->dialogItemP;
RawItemHdr *rihP = diP->rawItemP;
StringList *strListP;
//* ************************************************************* *
//* Create the string list with at least four info fields. These
//* info fields will be used as follows:
//* 0 - Reserved for the dialog manager
//* 1 - Reserved for colored row information
//* (see documentation of LISTATTR_COLOREDROWS)
//* (see MDL example NEWITEMS)
//* 2 - Resource ID of icon to display preceding that row of text.
// * 3 - Number of pixels to indent before drawing the icon.
//* **************************************************************
strListP = mdlStringList_create(0, 4);
//* ************************************************************* *
//* if string list create failed, tell the dialog manager
//* create failed
//* *************************************************************
if (NULL == strListP)
{
dimP->u.create.createFailed = TRUE;
return;
}
// ************************************************************* *
//* populate the string list with text and icon information based on
//* the current font height.
//* *************************************************************
if (SUCCESS !=
(status = listicon_checkListPopulate(strListP, fontHeight)))
{
listicon_errorPrint(MSGID_CheckBoxPopulateErr);
dimP->u.create.createFailed = TRUE;
return;
}
// associate the string list to the list box
mdlDialog_listBoxSetStrListP(rihP, strListP, 1);
break;
}
...

The function listicon_checkListPopulate is called from the list box hook function above when the list box is created. The string list for the choices list box is populated with ten choices with check box icons. The function listicon_toggleCheckBox assigns the check box icon information to the string list's information fields.

Private int listicon_checkListPopulate
(
StringList *strListP, // <= string list to populate
int fontHeight // => current dialog font height
)
{
int status = SUCCESS, i, newIndex;
if (NULL == strListP)
return ERROR;
for (i = 0; I<10; i++)
{
char buff[50];
sprintf(buff, "%d Choice", i);
status = mdlStringList_insertMember(&newIndex, strListP, -1, 1);
if (SUCCESS != status)
break;
mdlStringList_setMember(strListP, newIndex, buff, NULL);
// Add the check box icon information to the string list
listicon_toggleCheckBox(strListP, newIndex, fontHeight, NULL);
}
return status;
}

The string list associated with the list box must have additional information fields that store the icon information for the members of the string list.The function listicon_toggleCheckBox(shown below) initially populates the string list's information fields and toggles the check box when the user clicks on a row in the list box. The string list's information fields are populated according to the following table :

Field number Use of the information field
0 Reserved for the dialog manager to store selection and control information for each cell in the list box.
1 Reserved for colored row information.
2 Resource identifier of the icon to display preceding a row of text.
3 Number of pixels to indent before drawing the icon.

In this function, the current font height determines which icon size to use for the string list. Field 2 in the information field is set to the appropriate icon's resource identifier; field 3 is set to the number of pixels that the icon is indented. For this example, all check box icons are indented by one pixel.

Private void listicon_toggleCheckBox
(
StringList *strListP, // <> string list to store icon info
int listIndex, // => index into string list
int fontHeight, // => current dialog font height
int *infoFieldsP // => current information field values
)
{
int iconRscID, status;
int pixelOffset; // number of pixels that icon is indented
//* ************************************************************* *
//* if the icon resource id was previously set, then use it's value,
//* otherwise, set the id to zero
//* *************************************************************
iconRscID = (infoFieldsP) ? infoFieldsP[2] : 0;
// indent the icon by 1 pixel
pixelOffset = 1;
// ************************************************************* *
//* if the toggle is OFF then turn it ON. The toggle is initially
//* set to OFF.
//* *************************************************************
if (fontHeight < 9)
{
iconRscID = (iconRscID == ICONID_ToggleOff8Pt) ?
}
else if (fontHeight < 11)
{
iconRscID = (iconRscID == ICONID_ToggleOff10Pt) ?
ICONID_ToggleOn10Pt : ICONID_ToggleOff10Pt;
}
else if (fontHeight < 13)
{
iconRscID = (iconRscID == ICONID_ToggleOff12Pt) ?
}
else if (fontHeight < 17)
{
iconRscID = (iconRscID == ICONID_ToggleOff14Pt) ?
}
else if (fontHeight < 23)
{
iconRscID = (iconRscID == ICONID_ToggleOff18Pt) ?
}
else
{
iconRscID = (iconRscID == ICONID_ToggleOff24Pt) ?
}
//* *************************************************************
//* Set the third info field (index 2) to the resource ID of icon
//* to display preceding this row of text.
//* *************************************************************
mdlStringList_setInfoField(strListP, listIndex, 2, iconRscID);
// ************************************************************* *
//* Set the fourth info field (index 3) to the number of pixels to
//* indent before drawing the icon.
//* *************************************************************
mdlStringList_setInfoField(strListP, listIndex, 3, pixelOffset);
}

Handle the FONT CHANGED event to modify icon information in the string list and represent the new font height of the dialog. List box text sizes change automatically when the current dialog font changes-but because icon resources are a fixed size, the programmer must update the icon resource identifier in the StringList according to the new font height. The application must request font change event messages from the dialog manager by setting the fontChanges member of DialogHookInterests to TRUE during the dialog box creation.

// From listicon_mainBoxHook() in LISTICON.MC
...
{
// *************************************************************
Establish an interest in Dialog font changes so we can change our
icon sizes when the dialog manager gives us the
*************************************************************
dmP->u.create.interests.fontChanges = TRUE;
break;
};
...

When the user moves the dialog box to another screen that has a different font size, the dialog manager sends the DIALOG_MESSAGE_FONTCHANGED message to the dialog box hook function.When the hook function receives the message, the application can either recreate the string list for the list box or modify each icon resource identifier in each string list member's information field.

The MDL applications NEWITEMS and LISTBOX mentioned are delivered with the MicroStation MDL programming examples.

MicroStation V8 ListModels

For MicroStation V8, new features have been added to the Dialog Manager along with improvements to existing features. These features help provide better compatibility with updated Windows standards. One new feature is the ListModel data source. In addition to StringLists, ListBoxes and ComboBoxes now support the new ListModel as an alternative data source. Features of the ListModel include:

ListModel Overview

The ListModel is new with MicroStation V8. The ListModel contains a certain number of columns and rows. The number of columns is set when the ListModel is created via the mdlListModel_create function. For each column, the ListModel contains a ListColumn. The ListModel also contains a list of ListRows, each containing a ListCell for each column in the ListModel.

A ListColumn contains information used when processing ListCells in its column. This information includes:

A ListRow contains:

status flag

A ListCell contains:

A broad set of functions is provided to create and destroy the different objects and to access and set information within the objects.


Copyright © 2017 Bentley Systems, Incorporated. All rights reserved.