OWNCOMBO.C


/******************************************************************************\
* This is a part of the Microsoft Source Code Samples.
* Copyright 1993 - 1998 Microsoft Corp.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
\******************************************************************************/

/***************************************************************************
* *
* PROGRAM : OwnCombo.c *
* *
* PURPOSE : Illustrates the use of functions and messages for *
* combo boxes and owner-draw control styles. *
* *
* FUNCTIONS : WinMain - Creates the app. window and *
* enters the message loop. *
* *
* OwnComboInit - Registers the main window class *
* *
* About - Dialog function for the About *
* dialog. *
* *
* OwnComboWndProc - Window function for app. It *
* handles the menu selections *
* and processes the other window *
* messages. *
* *
* DrawEntireItem - Handles the drawing of a list *
* list box or combo box item. *
* *
* HandleSelectionState - Handles the selecting/deselect- *
* ing of a list box or combo box *
* item. *
* *
* HandleFocusState - Handles the getting/losing of *
* the input focus by a list box *
* *
* ListBoxExample - Dialog function for the *
* owner-draw list box example. *
* *
* ComboBoxExample - Dialog function for the text *
* combo dialog. *
* *
* OwnerComboBoxExample - Dialog fubction for the drop- *
* down-list combobox with *
* ownerdraw. *
* *
***************************************************************************/
#include "windows.h"
#include "owncombo.h"

HANDLE hInst;

/****************************************************************************
* *
* FUNCTION : WinMain(HANDLE, HANDLE, LPSTR, int) *
* *
* PURPOSE : Creates the app. window and enters the message loop. *
* *
****************************************************************************/

int APIENTRY WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{

HWND hWnd;
MSG msg;

UNREFERENCED_PARAMETER( lpCmdLine );

if (!hPrevInstance)
if (!OwnComboInit (hInstance))
return (0);

hInst = hInstance;

/* Create the app. window */
hWnd = CreateWindow ("owncombo",
"Owner-draw & Combo Box Example",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
(HWND) NULL,
NULL,
hInstance,
(LPSTR) NULL);

if (!hWnd)
return (0);

ShowWindow (hWnd, nCmdShow);

while (GetMessage (&msg, NULL, 0, 0)){
TranslateMessage (&msg);
DispatchMessage (&msg);
}

return(msg.wParam);
}


/****************************************************************************
* *
* FUNCTION : OwnComboInit (hInstance) *
* *
* PURPOSE : Registers the main window class. *
* *
* RETURNS : TRUE - if RegisterClass () succeeds. *
* FALSE - if RegisterClass () fails. *
* *
****************************************************************************/
BOOL NEAR PASCAL OwnComboInit (HANDLE hInstance)
{
HANDLE hMemory;
PWNDCLASS pWndClass;
BOOL bSuccess;

/* Allocate for and fill class structure. */
hMemory = LocalAlloc (LPTR, sizeof (WNDCLASS));
if(!hMemory){
MessageBox(NULL, "<OwnComboInit> Not enough memory.", NULL, MB_OK | MB_ICONHAND);
return(FALSE);
}

pWndClass = (PWNDCLASS) LocalLock (hMemory);

pWndClass->style = 0;
pWndClass->lpfnWndProc = (WNDPROC) OwnComboWndProc;
pWndClass->hInstance = hInstance;
pWndClass->hIcon = LoadIcon (hInstance, "owncombo");
pWndClass->hCursor = LoadCursor (NULL, IDC_ARROW);
pWndClass->hbrBackground = GetStockObject (WHITE_BRUSH);
pWndClass->lpszMenuName = (LPSTR) "OwnComboMenu",
pWndClass->lpszClassName = (LPSTR) "owncombo";

bSuccess = RegisterClass (pWndClass);
LocalUnlock (hMemory);
LocalFree (hMemory);

return (bSuccess);
}

/****************************************************************************
* *
* FUNCTION : About (hDlg,message, wParam, lParam) *
* *
* PURPOSE : Dialog function for the About... dialog. *
* *
****************************************************************************/
BOOL APIENTRY About (
HWND hDlg,
UINT message,
UINT wParam,
LONG lParam)
{

UNREFERENCED_PARAMETER(lParam);
switch (message){
case WM_INITDIALOG:
return(TRUE);

case WM_COMMAND:
if (LOWORD(wParam) == IDOK){
EndDialog (hDlg,0);
return(FALSE);
}
break;

default:
break;
}
return(FALSE);
}


/****************************************************************************
* *
* FUNCTION : OwnComboWndProc(hWnd, message, wParam, lParam) *
* *
* PURPOSE : Window function for the app. It handles menu selections *
* and processes window WM_ messages. *
* *
****************************************************************************/
LONG APIENTRY OwnComboWndProc (
HWND hWnd,
UINT message,
UINT wParam,
LONG lParam)
{
switch (message){
case WM_COMMAND:
switch (LOWORD(wParam)){
case IDM_EXIT:
DestroyWindow (hWnd);
break;

case IDM_ABOUT:
/* Bring up the about box */
DialogBox (hInst,
"AboutBox",
hWnd,
About);

break;

case IDM_LISTBOX:
/* Bring up the list box example */
DialogBox (hInst,
"ListBoxDialog",
hWnd,
About);
break;

case IDM_MULTILISTBOX:
/* Bring up the multiple selection list box example */
DialogBox (hInst,
"MultiListBoxDialog",
hWnd,
About);
break;

case IDM_COMBOBOX:
/* Bring up the combo box example */
DialogBox (hInst,
"ComboBoxDialog",
hWnd,
About);
break;

case IDM_OWNERCOMBOBOX:
/* Bring up the owner-draw dropdown list box example */
DialogBox (hInst,
"OwnerComboBoxDialog",
hWnd,
About);
break;
}
break;

case WM_DESTROY:
PostQuitMessage (0);
break;

default:
return(DefWindowProc(hWnd, message, wParam, lParam));
}
return(0);
}

/****************************************************************************
* *
* FUNCTION : HandleSelectionState(LPDRAWITEMSTRUCT, int) *
* *
* PURPOSE : Handles a change in an item selection state. If an item is *
* selected, a black rectangular frame is drawn around that *
* item; if an item is de-selected, the frame is removed. *
* *
* COMMENT : The black selection frame is slightly larger than the gray *
* focus frame so they won't paint over each other. *
* *
****************************************************************************/
VOID APIENTRY HandleSelectionState(
LPDRAWITEMSTRUCT lpdis,
INT inflate)
{
RECT rc;
HBRUSH hbr;

/* Resize rectangle to place selection frame outside of the focus
* frame and the item.
*/
CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
InflateRect ((LPRECT)&rc, inflate, inflate);

if (lpdis->itemState & ODS_SELECTED)
{
/* selecting item -- paint a black frame */
hbr = GetStockObject(BLACK_BRUSH);
}
else
{
/* de-selecting item -- remove frame */
hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
}
FrameRect(lpdis->hDC, (LPRECT)&rc, hbr);
DeleteObject (hbr);
}

/****************************************************************************
* *
* FUNCTION : HandleFocusState(LPDRAWITEMSTRUCT, int) *
* *
* PURPOSE : Handle a change in item focus state. If an item gains the *
* input focus, a gray rectangular frame is drawn around that *
* item; if an item loses the input focus, the gray frame is *
* removed. *
* *
* COMMENT : The gray focus frame is slightly smaller than the black *
* selection frame so they won't paint over each other. *
* *
****************************************************************************/
VOID APIENTRY HandleFocusState(
LPDRAWITEMSTRUCT lpdis,
INT inflate)
{
RECT rc;
HBRUSH hbr;

/* Resize rectangle to place focus frame between the selection
* frame and the item.
*/
CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
InflateRect ((LPRECT)&rc, inflate, inflate);

if (lpdis->itemState & ODS_FOCUS)
{
/* gaining input focus -- paint a gray frame */
hbr = GetStockObject(GRAY_BRUSH);
}
else
{
/* losing input focus -- remove (paint over) frame */
hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
}
FrameRect(lpdis->hDC, (LPRECT)&rc, hbr);
DeleteObject (hbr);
}

/****************************************************************************
* *
* FUNCTION : DrawEntireItem(LPDRAWITEMSTRUCT, int) *
* *
* PURPOSE : Draws an item and frames it with a selection frame and/or *
* a focus frame when appropriate. *
* *
****************************************************************************/
VOID APIENTRY DrawEntireItem(
LPDRAWITEMSTRUCT lpdis,
INT inflate)
{
RECT rc;
HBRUSH hbr;

/* Resize rectangle to leave space for frames */
CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
InflateRect ((LPRECT)&rc, inflate, inflate);

/* Create a brush using the value in the item data field (this value
* was initialized when we added the item to the list/combo box using
* LB_ADDSTRING/CB_ADDSTRING) and draw the color in the list/combo box.
*/
hbr = CreateSolidBrush (lpdis->itemData);
FillRect (lpdis->hDC, (LPRECT)&rc, hbr);
DeleteObject (hbr);

/* Draw or erase appropriate frames */
HandleSelectionState(lpdis, inflate + 4);
HandleFocusState(lpdis, inflate + 2);
}

/****************************************************************************
* *
* FUNCTION : ListBoxExample (hDlg, message, wParam, lParam) *
* *
* PURPOSE : Dialog function for the owner-draw list box example. *
* It sets up the example dialog with the owner-draw list box,*
* adds the colors to the list box, and handles setting the *
* selection and focus for the items. *
* *
****************************************************************************/
BOOL APIENTRY ListBoxExample (
HWND hDlg,
UINT message,
UINT wParam,
LONG lParam)
{
LPDRAWITEMSTRUCT lpdis;
LPMEASUREITEMSTRUCT lpmis;

/* Vars for WM_DRAWITEM */

switch (message){
case WM_COMMAND:
switch (LOWORD(wParam)){
case IDOK:
EndDialog (hDlg, 0);
return (TRUE);
break;

/* Clicking any of these buttons adds the corresponding color
* to the list box. The application-supplied data is the RGB
* value for the color to be drawn in the listbox.
*/
case ID_BLACK:
SendMessage (GetDlgItem (hDlg, ID_LISTBOX),
LB_ADDSTRING,
0,
RGB (0,0,0));
return(TRUE);
break;
case ID_RED:
SendMessage (GetDlgItem (hDlg, ID_LISTBOX),
LB_ADDSTRING,
0,
RGB (255,0,0));
return(TRUE);
break;

case ID_BLUE:
SendMessage (GetDlgItem (hDlg, ID_LISTBOX),
LB_ADDSTRING,
0,
RGB (0,0,255));
return(TRUE);
break;

case ID_GREEN:
SendMessage (GetDlgItem (hDlg, ID_LISTBOX),
LB_ADDSTRING,
0,
RGB (0,255,0));
return(TRUE);
break;

default:
return(FALSE);
break;
}

case WM_DRAWITEM:
/* Get pointer to the DRAWITEMSTRUCT */
lpdis = (LPDRAWITEMSTRUCT)lParam;

if (lpdis->itemID == -1)
{
/* We have a request to draw an item in the list box, yet there
* are no list box items. This is sent when the user TABS into
* an empty list box or an empty list box gets the focus. We
* have to indicate (somehow) that this owner-draw list box has
* the focus. We do it in response to this message. Note that
* lpdis->itemData field would be invalid in this instance so
* we can't allow it to fall into our standard routines.
*/
HandleFocusState(lpdis, -5);
}
else
{
switch (lpdis->itemAction)
{
case ODA_DRAWENTIRE:
DrawEntireItem(lpdis, -7);
break;

case ODA_SELECT:
HandleSelectionState(lpdis, -3);
break;

case ODA_FOCUS:
HandleFocusState(lpdis, -5);
break;
}
}

/* Return TRUE meaning that we processed this message. */
return(TRUE);
break;

case WM_MEASUREITEM:
lpmis = (LPMEASUREITEMSTRUCT)lParam;

/* All the items are the same height since the list box style is
* LBS_OWNERDRAWFIXED
*/
lpmis->itemHeight = 30;
break;

case WM_CLOSE:
EndDialog(hDlg, 0);
return(TRUE);
break;

default:
return(FALSE);
}

return(TRUE);
}

/****************************************************************************
* *
* FUNCTION : ComboBoxExample(hWnd, message, wParam, lParam) *
* *
* PURPOSE : Dialog function for the text combo dialog. The push buttons*
* send various messages to the combo box and the edit control*
* when selected. They allow the user to vary data sent with *
* each message. *
* *
****************************************************************************/
BOOL APIENTRY ComboBoxExample(
HWND hDlg,
UINT message,
UINT wParam,
LONG lParam)
{

HWND hWndCombo; /* Handle to the combo box control */
/* in the dialog box window */
HWND hWndCheckBox; /* Handle to the Auto Check Box */
CHAR strSingleEditLine[255]; /* Single line edit control input */
INT wIndex, wCount;

/* Get handles to the Combo box and the Check box */
hWndCombo = GetDlgItem(hDlg, ID_COMBOBOX);
hWndCheckBox = GetDlgItem(hDlg, ID_STEPSBOX);

switch (message){
case WM_COMMAND:
switch (LOWORD(wParam)){
case IDOK:
EndDialog (hDlg,0);
return(TRUE);

case ID_UNSLBUTTON:
/* Selecting this button unselects any selection in the
* combo box.
*/
SetDlgItemText (hDlg, ID_TEXT1, "");
SetDlgItemText (hDlg, ID_TEXT2, "");
wIndex = (WORD) SendMessage( hWndCombo, CB_GETCURSEL, 0, 0L);
if (wIndex == CB_ERR)
MessageBox (hDlg, (LPSTR)"No Selection", NULL, MB_OK);
else
SendMessage (hWndCombo, CB_SETCURSEL, (WPARAM)-1, 0L);
SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
break;

case ID_NUMSELBUTTON:
/* An integer value is taken from the edit control and an
* attempt is made to select a combo box entry having this
* index.
*/
SetDlgItemText (hDlg, ID_TEXT1, "");
SetDlgItemText (hDlg, ID_TEXT2, "");
wCount = (WORD) SendMessage (hWndCombo, CB_GETCOUNT, 0, 0L);
wIndex = (INT) GetDlgItemInt (hDlg, ID_SINGLEEDIT, NULL, TRUE);
if (wIndex >= wCount)
MessageBox (hDlg, (LPSTR)"Bad Selection", NULL, MB_OK);
else
SendMessage(hWndCombo, CB_SETCURSEL, wIndex, 0L);
SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
break;

case ID_TXTSELBUTTON:
/* A text string is taken from the edit control and an
* attempt is made to select a combo box entry having the
* string as a prefix.
*/
SetDlgItemText (hDlg, ID_TEXT1, "");
SetDlgItemText (hDlg, ID_TEXT2, "");
GetDlgItemText (hDlg, ID_SINGLEEDIT,
(LPSTR)strSingleEditLine, 255);
wIndex = (WORD) SendMessage (hWndCombo,
CB_SELECTSTRING,
(WPARAM)-1,
(LONG)(LPSTR)strSingleEditLine);
if (wIndex == CB_ERR)
MessageBox (hDlg, (LPSTR)"Bad Selection", NULL, MB_OK);
SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
break;

case ID_FNDSELBUTTON:
/* Searches for the text specified in the list of combo
* entries and returns the index (in combo box) of the
* first match. The index is displayed in the "Text1"
* field of the dialog.
*/
SetDlgItemText (hDlg, ID_TEXT1, "");
SetDlgItemText (hDlg, ID_TEXT2, "");
GetDlgItemText (hDlg,
ID_SINGLEEDIT,
(LPSTR)strSingleEditLine,
255);
wIndex = (WORD)SendMessage (hWndCombo,
CB_FINDSTRING,(WPARAM)-1,
(LONG)(LPSTR)strSingleEditLine);
if (wIndex == CB_ERR)
MessageBox (hDlg, (LPSTR)"Bad Selection", NULL, MB_OK);
else
SetDlgItemInt (hDlg, ID_TEXT1, wIndex, FALSE);
SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
break;

case ID_CLRBUTTON:
/* Clears the combo box of all it's entries */
SetDlgItemText (hDlg, ID_TEXT1, "");
SetDlgItemText (hDlg, ID_TEXT2, "");
wCount = (WORD) SendMessage (hWndCombo, CB_GETCOUNT, 0, 0L);
if (!wCount)
MessageBox (hDlg, (LPSTR)"Already clear", NULL, MB_OK);
else{
SetDlgItemInt (hDlg, ID_TEXT1, wCount, TRUE);
SetDlgItemText (hDlg, ID_TEXT2, "Items cleared");
SendMessage (hWndCombo,CB_RESETCONTENT, 0, 0L);
}
SetFocus (GetDlgItem (hDlg,ID_SINGLEEDIT));
break;

case ID_ADDBUTTON:
/* Takes the string specified in the edit control and
* adds it to the combo box.
*/
SetDlgItemText (hDlg, ID_TEXT1, "");
SetDlgItemText (hDlg, ID_TEXT2, "");
GetDlgItemText (hDlg, ID_SINGLEEDIT, strSingleEditLine, 255);
SendMessage (hWndCombo,
CB_ADDSTRING,
0,
(LONG)(LPSTR) strSingleEditLine);
SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
break;

case ID_DELETEBUTTON:
/* Delete the currently selected item from the combo box. */
SetDlgItemText (hDlg, ID_TEXT1, "");
SetDlgItemText (hDlg, ID_TEXT2, "");
wIndex = (WORD) SendMessage (hWndCombo, CB_GETCURSEL, 0, 0L);
if (SendMessage (hWndCombo, CB_DELETESTRING, wIndex, 0L) == CB_ERR)
MessageBox (hDlg, (LPSTR)"No Selection", NULL, MB_OK);
else{
SetDlgItemText (hDlg, ID_TEXT1, "deleted index #");
SetDlgItemInt (hDlg, ID_TEXT2, wIndex, TRUE);
}
SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
break;

case ID_CBDIRBUTTON:
/* Appends a directory listing of the current directory
* to the combo box entries.
*/
SetDlgItemText (hDlg, ID_TEXT1, "");
SetDlgItemText (hDlg, ID_TEXT2, "");
wIndex = (WORD)SendMessage (hWndCombo,
CB_DIR,
0x10|0x4000,
(LONG)(LPSTR)"*.*");
SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
break;


case ID_CPYBUTTON:
/* Copies the currently selected item in the combo box to
* the edit control.
*/
SetDlgItemText (hDlg, ID_TEXT1, "");
SetDlgItemText (hDlg, ID_TEXT2, "");
wIndex = (WORD) SendMessage (hWndCombo, CB_GETCURSEL, 0, 0L);
if (wIndex == CB_ERR)
MessageBox(hDlg, (LPSTR)"No Selection", NULL, MB_OK);
else{
wCount = SendMessage (hWndCombo, CB_GETLBTEXTLEN, wIndex, 0L);
SendMessage (hWndCombo,
CB_GETLBTEXT,
wIndex,
(LONG)(LPSTR)strSingleEditLine);
SetDlgItemText(hDlg, ID_SINGLEEDIT,
(LPSTR)strSingleEditLine);

SetDlgItemText(hDlg, ID_TEXT1, "copied index #"); 
SetDlgItemInt(hDlg, ID_TEXT2, wIndex, TRUE);
}
SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
break;

/* When the combo notification box is checked, a message box
* is flashed showing what notification codes the combo box is
* returning to the app. in response to the messages sent by
* the buttons.
*/
case ID_COMBOBOX:
if (SendMessage (hWndCheckBox, BM_GETCHECK, 0, 0L)){
switch (HIWORD(lParam)){
case (WORD)CBN_ERRSPACE:
MessageBox (hDlg, (LPSTR)"CB Out of Space",
"CB MSG", MB_OK);
break;

case CBN_SELCHANGE:
MessageBox (hDlg, (LPSTR)"CB Sel Change",
"CB MSG", MB_OK);
break;

case CBN_DBLCLK:
MessageBox(hDlg, (LPSTR)"CB Double Click",
"CB MSG", MB_OK);
break;

case CBN_SETFOCUS:
SetDlgItemText(hDlg, ID_TEXT1, "CB SetFocus");
break;

case CBN_KILLFOCUS:
SetDlgItemText(hDlg, ID_TEXT1, "CB KillFocus");
break;
}
}
break;

default:
return(FALSE);
}
break;

case WM_CLOSE:
EndDialog(hDlg, 0);
return(TRUE);
break;

default:
return(FALSE);
}
return(TRUE);
}


/****************************************************************************
* *
* FUNCTION : OwnerComboBoxExample(hWnd, message, wParam, lParam) *
* *
* PURPOSE : Dialog function for the dropdown list combo box with *
* owner-draw. *
* *
****************************************************************************/
BOOL APIENTRY OwnerComboBoxExample (
HWND hDlg,
UINT message,
UINT wParam,
LONG lParam)
{
LPDRAWITEMSTRUCT lpdis;
LPMEASUREITEMSTRUCT lpmis;

switch (message){
case WM_COMMAND:
switch (LOWORD(wParam)){
case IDOK:
EndDialog (hDlg, 0);
return(TRUE);
break;

/* Clicking any of these buttons adds the corresponding color
* to the combo box. The application-supplied data is the RGB
* value for the color to be drawn in the listbox.
*/
case ID_BLACK:
SendMessage (GetDlgItem(hDlg, ID_LISTBOX),
CB_ADDSTRING,
0,
RGB (0,0,0));
return(TRUE);
break;

case ID_RED:
SendMessage (GetDlgItem (hDlg, ID_LISTBOX),
CB_ADDSTRING,
0,
RGB (255,0,0));
return(TRUE);
break;

case ID_BLUE:
SendMessage (GetDlgItem(hDlg, ID_LISTBOX),
CB_ADDSTRING,
0,
RGB (0,0,255));
return(TRUE);
break;

case ID_GREEN:
SendMessage (GetDlgItem(hDlg, ID_LISTBOX),
CB_ADDSTRING,
0,
RGB (0,255,0));
return(TRUE);
break;

default:
return(TRUE);
break;
}

case WM_DRAWITEM:
/* Get pointer to the DRAWITEMSTRUCT */
lpdis = (LPDRAWITEMSTRUCT)lParam;

if (lpdis->itemID == -1){
/* We have a request to draw an item in the combo box, yet there
* are no combo box items. This is sent when the user TABS into
* an empty combo box or an empty combo box gets the focus. We
* have to indicate (somehow) that this owner-draw combo box has
* the focus. We do it in response to this message. Note that
* lpdis->itemData field would be invalid in this instance so
* we can't allow it to fall into our standard routines.
*/
HandleFocusState(lpdis, -2);
}
else
{
switch (lpdis->itemAction)
{
case ODA_DRAWENTIRE:
DrawEntireItem(lpdis, -4);
break;

case ODA_SELECT:
HandleSelectionState(lpdis, 0);
break;

case ODA_FOCUS:
HandleFocusState(lpdis, -2);
break;
}
}

/* Return TRUE meaning that we processed this message. */
return(TRUE);
break;

case WM_MEASUREITEM:
lpmis = (LPMEASUREITEMSTRUCT)lParam;

/* All the items are the same height since the combo box is
* CBS_OWNERDRAWFIXED
*/
if (lpmis->itemID == -1){
/* If -1 for item, then we are setting the height of the
* always visible static item part of the dropdown combo box.
*/
lpmis->itemHeight = 25;
return(TRUE);
}
lpmis->itemHeight = 30;
break;

case WM_CLOSE:
EndDialog(hDlg, 0);
return(TRUE);
break;

default:
return(FALSE);
}
return(TRUE);
}