HOWTO: Make a List Box Item Unavailable for Selection
ID: Q74792
|
The information in this article applies to:
-
Microsoft Win32 Software Development Kit (SDK)
-
Microsoft Windows Software Development Kit (SDK) 3.1
-
Microsoft Windows 2000
SUMMARY
In the Microsoft Windows graphical environment, an application can use
a list box to enumerate options. However, there are circumstances in
which one or more options may not be appropriate. The application can
change the appearance of items in a list box and prevent the user from
selecting one of these items by using the techniques discussed below.
MORE INFORMATIONChanging the Appearance of a List Box Item
To dim (gray) a particular item in a list box, use an owner-draw list
box as follows:
- Create a list box that has the LBS_OWNERDRAW and LBS_HASSTRINGS
styles.
- Use the following code to process the WM_MEASUREITEM message:
case WM_MEASUREITEM:
((MEASUREITEMSTRUCT FAR *)(lParam))->itemHeight = wItemHeight;
break;
wItemHeight is the height of a character in the list box font.
- Use the following code to process the WM_DRAWITEM message:
#define PHDC (pDIS->hDC)
#define PRC (pDIS->rcItem)
DRAWITEMSTRUCT FAR *pDIS;
...
case WM_DRAWITEM:
pDIS = (DRAWITEMSTRUCT FAR *)lParam;
/* Draw the focus rectangle for an empty list box or an
empty combo box to indicate that the control has the
focus
*/
if ((int)(pDIS->itemID) < 0)
{
switch(pDIS->CtlType)
{
case ODT_LISTBOX:
if ((pDIS->itemAction) & (ODA_FOCUS))
DrawFocusRect (PHDC, &PRC);
break;
case ODT_COMBOBOX:
if ((pDIS->itemState) & (ODS_FOCUS))
DrawFocusRect (PHDC, &PRC);
break;
}
return TRUE;
}
/* Get the string */
switch(pDIS->CtlType)
{
case ODT_LISTBOX:
SendMessage ( pDIS->hwndItem,
LB_GETTEXT,
pDIS->itemID,
(LPARAM)(LPSTR)szBuf);
break;
case ODT_COMBOBOX:
SendMessage ( pDIS->hwndItem,
CB_GETLBTEXT,
pDIS->itemID,
(LPARAM)(LPSTR)szBuf);
break;
}
if (*szBuf == '!') // This string is disabled
{
hbrGray = CreateSolidBrush (GetSysColor
(COLOR_GRAYTEXT));
GrayString ( PHDC,
hbrGray,
NULL,
(LPARAM)(LPSTR)(szBuf + 1),
0,
PRC.left,
PRC.top,
0,
0);
DeleteObject (hbrGray);
/* SPECIAL CASE - Need to draw the focus rectangle if
there is no current selection in the list box, the
1st item in the list box is disabled, and the 1st
item has gained or lost the focus
*/
if (pDIS->CtlType == ODT_LISTBOX)
{
if (SendMessage ( pDIS->hwndItem,
LB_GETCURSEL,
0,
0L) == LB_ERR)
if ( (pDIS->itemID == 0) &&
((pDIS->itemAction) & (ODA_FOCUS)))
DrawFocusRect (PHDC, &PRC);
}
}
else // This string is enabled
{
if ((pDIS->itemState) & (ODS_SELECTED))
{
/* Set background and text colors for selected
item */
crBack = GetSysColor (COLOR_HIGHLIGHT);
crText = GetSysColor (COLOR_HIGHLIGHTTEXT);
}
else
{
/* Set background and text colors for unselected
item */
crBack = GetSysColor (COLOR_WINDOW);
crText = GetSysColor (COLOR_WINDOWTEXT);
}
// Fill item rectangle with background color
hbrBack = CreateSolidBrush (crBack);
FillRect (PHDC, &PRC, hbrBack);
DeleteObject (hbrBack);
// Set current background and text colors
SetBkColor (PHDC, crBack);
SetTextColor (PHDC, crText);
// TextOut uses current background and text colors
TextOut ( PHDC,
PRC.left,
PRC.top,
szBuf,
lstrlen(szBuf));
/* If enabled item has the input focus, call
DrawFocusRect to set or clear the focus
rectangle */
if ((pDIS->itemState) & (ODS_FOCUS))
DrawFocusRect (PHDC, &PRC);
}
return TRUE;
Strings that start with "!" are displayed dimmed. The exclamation mark
character is not displayed.
Preventing Selection
To prevent a dimmed string from being selected, create the list box
with the LBS_NOTIFY style. Then use the following code in the list
box's parent window procedure to process the LBN_SELCHANGE
notification:
case WM_COMMAND:
switch (wParam)
{
...
case IDD_LISTBOX:
if (LBN_SELCHANGE == HIWORD(lParam))
{
idx = (int)SendDlgItemMessage(hDlg, wParam,
LB_GETCURSEL, 0, 0L);
SendDlgItemMessage(hDlg, wParam, LB_GETTEXT, idx,
(LONG)(LPSTR)szBuf);
if ('!' == *szBuf)
{
// Calculate an alternate index here
// (not shown in this example).
// Then set the index.
SendDlgItemMessage(hDlg, wParam, LB_SETCURSEL, idx, 0L);
}
}
break;
...
}
break;
When the user attempts to select a dimmed item, the alternate index
calculation moves the selection to an available item.
Additional query words:
listbox WIN16SDK
Keywords : kbCtrl kbListBox kbNTOS kbWinOS2000 kbSDKWin32 kbGrpUser kbWinOS
Version : WINDOWS:3.1
Platform : WINDOWS
Issue type : kbhowto
|