#pragma	title("Time Entry Field Control  --  Version 1.0 -- (TimeFld.C)")
#pragma	subtitle("  Time Entry Field Control Control DLL - Interface Definitions")

#pragma	info(noext)

#define	INCL_DOS		   /* Include OS/2 DOS Kernal		*/
#define	INCL_GPI		   /* Include OS/2 PM GPI Interface	*/
#define	INCL_WIN		   /* Include OS/2 PM Windows Interface	*/

#include <os2.h>
#include <stdlib.h>
#include <string.h>

#include <pmcx.h>

#include "timefld.h"

/* This	module contains	an example installable control that can	be used	*/
/* within applications where additional	facilities are provided	that	*/
/* are not found within	the default controls of	OS/2 PM.		*/
/*									*/
/* For complete	details	regarding the PM Control Extensions (PMCX)	*/
/* consult the User's Guide.                                            */
/*									*/
/* The DLL is created using the	following command line invocation:	*/
/*									*/
/*     Icc -G3e- -O+ -Rn -W3 -C	TimeFld.C				*/

/* Filename:   TimeFld.C						*/

/*  Version:   1.0							*/
/*  Created:   1993-06-10						*/
/*  Revised:   1994-06-26						*/

/* Routines:   BOOL EXPENTRY TimeFldRegister(HAB hAB);			*/
/*	       BOOL EXPENTRY TimeFldQuery(PUSERINFO pControlInfo);	*/
/*	       MRESULT EXPENTRY	TimeFldWndProc(HWND hWnd, ULONG	msg,	*/
/*					      MPARAM mp1, MPARAM mp2);	*/
/*	       MRESULT EXPENTRY	TimeFldStyles(HWND hWnd, ULONG msg,	*/
/*					      MPARAM mp1, MPARAM mp2);	*/


/* Copyright ¸ 1989-1994  Prominare Inc.  All Rights Reserved.		*/

/* --------------------------------------------------------------------	*/

/************************************************************************/
/************************************************************************/
/*		       DISCLAIMER OF WARRANTIES.			*/
/************************************************************************/
/************************************************************************/
/*     The following [enclosed]	code is	library	code created by		*/
/*     Prominare Inc.  This library code is  provided to you solely	*/
/*     for the purpose of assisting you	in the development of your	*/
/*     applications.  The code is provided "AS IS", without		*/
/*     warranty	of any kind.  Prominare	Inc. shall not be liable	*/
/*     for any damages arising out of your use of the library code,	*/
/*     even if they have been advised of the possibility of such	*/
/*     damages.								*/
/************************************************************************/
/************************************************************************/

/* --- Window Information Structures ----------------------------------	*/

typedef	struct _TIMEFIELD	   /* tf */
   {
   HWND	  hwndHours;		   /* Hours Entry Fiild	Handle		*/
   HWND	  hwndMinutes;		   /* Minutes Entry Fiild Handle	*/
   HWND	  hwndSeconds;		   /* Seconds Entry Fiild Handle	*/
   HWND	  hwndOwner;		   /* Owner Window Handle		*/
   SWP	  aswp[3];		   /* Raised Field Flag			*/
   LONG	  cxSep;		   /* Separator	Width			*/
   LONG	  cxField;		   /* Field Width			*/
   LONG	  aClr[7];		   /* Presentation Colours Array	*/
   ULONG  flStyle;		   /* Style Flag			*/
   CHAR	  szText[16];		   /* Time String Holder		*/
   } TIMEFIELD ;

typedef	TIMEFIELD *PTIMEFIELD;

#define	SWP_HOURS    0
#define	SWP_MINUTES  1
#define	SWP_SECONDS  2

/* --- Module Prototype	Definitions -----------------------------------	*/

BOOL	EXPENTRY TimeFldRegister(HAB hAB);
BOOL	EXPENTRY TimeFldQueryInfo(PUSERINFO pUserInfo);
MRESULT	EXPENTRY TimeFldWndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
MRESULT	EXPENTRY TimeFldStyles(HWND hWnd, ULONG	msg, MPARAM mp1, MPARAM	mp2);

static VOID CalcSize(PRECTL prcl, PTIMEFIELD ptf);
static VOID SetDefaultColours(HWND hWnd, PTIMEFIELD ptf);
static LONG lGetPresParam(HWND hWnd, ULONG ulID1, ULONG	ulID2, LONG lDefault);

#pragma	subtitle("   Time Entry Field Control DLL - Control Initialization Function")
#pragma	page ( )

/* --- TimeFldRegister ------------------------------------------------	*/
/*									*/
/*     This function is	used to	register the installable control class	*/
/*     with OS/2 Presentation Manager.	The registration must use the	*/
/*     USER_CWINDOWWORDS to reserve memory for the control to allow for	*/
/*     proper usage by Resource	Editor and for use by the control	*/
/*     dialog and window procedures.  The information for the control	*/
/*     containing the style, presentation parameters and control data	*/
/*     is pointed to by	a pointer that can be referenced by the		*/
/*     control's dialog and window procedure as required.  The memory   */
/*     for the structure is allocated and controlled through Resource	*/
/*     Editor.	 The control can reserve more memory for its use	*/
/*     by adding the memory required to	that of	the USER_CWINDOWWORDS	*/
/*     constant.							*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HAB hAB;	= Application Anchor Block Handle			*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     TimeFldRegister =  TRUE : Class Registration Successful		*/
/*		       = FALSE : Class Registration Failed		*/
/*									*/
/* --------------------------------------------------------------------	*/

BOOL EXPENTRY TimeFldRegister(HAB hAB)

{
		       /* Register the control class with OS/2		*/
		       /* Presentation Manager and return registration	*/
		       /* result					*/

return(WinRegisterClass(hAB, "TimeField", TimeFldWndProc,
			CS_SYNCPAINT | CS_SIZEREDRAW, USER_CWINDOWWORDS));

}
#pragma	subtitle("   Time Entry Field Control DLL - Query Control Information Function")
#pragma	page ( )

/* --- TimeFldQuery ---------------------------------------------------	*/
/*									*/
/*     This function is	used to	return to the caller information	*/
/*     regarding the installable control and its capabilities.	The	*/
/*     function	should return a	true value otherwise Resource		*/
/*     Editor will not register	the control as being usable.		*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     PUSERINFO pUserInfo; = User Information Pointer			*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     TimeFldQuery =  TRUE : User Information Being Returned		*/
/*		    = FALSE : No User Information Available		*/
/*									*/
/* --------------------------------------------------------------------	*/

BOOL EXPENTRY TimeFldQuery(PUSERINFO pUserInfo)

{
		       /* Complete the User Information	structure	*/
		       /* passed to the	function by Resource Editor	*/

		       /* Complete the version and number of control	*/
		       /* types.  In Version 1.00 of CCRS, only	one	*/
		       /* control type is used.				*/
pUserInfo->ulMajor = 3UL;
pUserInfo->ulMinor = 0UL;
		       /* Complete the author and control classname	*/

memcpy(pUserInfo->szAuthor,    "Prominare Inc.", 15);
memcpy(pUserInfo->szClassname, "TimeField", 10);
memcpy(pUserInfo->szName,      "TimeFld", 8);

		       /* Complete the default size and	style of the	*/
		       /* first	user control type			*/

pUserInfo->utDefined[0].cx	     = 63L;
pUserInfo->utDefined[0].cy	     = 12L;
pUserInfo->utDefined[0].flStyle	     = WS_VISIBLE | DTS_CURRENTTIME;

		       /* Set the maximum amount of text control can	*/
		       /* accept including NULL	termination byte	*/

pUserInfo->utDefined[0].cMaxText     = 16UL;

		       /* Save the style's dialogue ID, type, control   */
		       /* data size and	count of style masks		*/

pUserInfo->utDefined[0].idDlg	     = DLG_CTRLUSER;
pUserInfo->utDefined[0].flOptions    = PMCXOPT_REFRESH;
pUserInfo->utDefined[0].ulType	     = UTYPE_PRIVATE;
pUserInfo->utDefined[0].cCtlData     = 0;
pUserInfo->utDefined[0].cMasks	     = 1;
pUserInfo->utDefined[0].flStyleType  = STYLETYPE_BITFLAGS;
pUserInfo->utDefined[0].stMasks[0].flStyleMask = DTS_CURRENTTIME;
pUserInfo->utDefined[0].stMasks[0].idStyle     = IDS_DTS_CURRENTTIME;

		       /* Save the description of the control		*/

memcpy(pUserInfo->utDefined[0].szDescription, "Time Entry Field", 17);

		       /* Return the success flag back to Resource	*/
		       /* Editor					*/
return(TRUE);
}
#pragma	subtitle("   Time Entry Field Control DLL - Control Window Procedure")
#pragma	page( )

/* --- lGetPresParam ----------------------------------	[ Private } ---	*/
/*									*/
/*     This function is	used to	retrieve a presentation	parameter	*/
/*     that may	be present.  If	the presentation parameter is not,	*/
/*     the default colour passed to the	function will be used.		*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HWND  hWnd;     = Window	Handle					*/
/*     ULONG ulID1;    = Presentation Parameter	1 ID			*/
/*     ULONG ulID2;    = Presentation Parameter	2 ID			*/
/*     LONG  lDefault; = Default Colour					*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     lGetPresParam = Colour to Use					*/
/*									*/
/* --------------------------------------------------------------------	*/

LONG lGetPresParam(HWND	hWnd, ULONG ulID1, ULONG ulID2,	LONG lDefault)

{
HPS   hPS;			   /* Presentation Space Handle		*/
LONG  lClr;			   /* Presentation Parameter Colour	*/
ULONG ulID;			   /* Presentation Parameter ID		*/

if ( WinQueryPresParam(hWnd, ulID1, ulID2, &ulID, 4UL, (PVOID)&lClr,
		       QPF_NOINHERIT | QPF_ID2COLORINDEX | QPF_PURERGBCOLOR) )
   return(lClr);
else
   if (	(lDefault >= SYSCLR_SHADOWHILITEBGND) &&
	(lDefault <= SYSCLR_HELPHILITE)	)
       return(WinQuerySysColor(HWND_DESKTOP, lDefault, 0L));
   else
       if ( (lClr = GpiQueryRGBColor(hPS = WinGetPS(hWnd),
				     LCOLOPT_REALIZED, lDefault)) == GPI_ALTERROR )
	   {
	   WinReleasePS(hPS);
	   return(lDefault);
	   }
       else
	   {
	   WinReleasePS(hPS);
	   return(lClr);
	   }
}
#pragma	subtitle("   Time Entry Field Control DLL - Control Window Sizing Procedure")
#pragma	page ( )

/* --- CalcSize	---------------------------------------	[ Private ] ---	*/
/*									*/
/*     This function is	used to	calculate the sizes and	positions	*/
/*     of the various elements that are	used to	make up	a shadowed	*/
/*     text field.							*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HWND	  hWnd;	= Window Handle					*/
/*     PRECTL	  prcl;	= Control Rectangle Pointer			*/
/*     PTIMEFIELD ptf;	= Group	Box Information	Pointer			*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     Nothing								*/
/*									*/
/* --------------------------------------------------------------------	*/

static VOID CalcSize(PRECTL prcl, PTIMEFIELD ptf)

{

ptf->aswp[SWP_HOURS].x	= prcl->xLeft +	3L;
ptf->aswp[SWP_HOURS].y	= prcl->yBottom	+ 3L;
ptf->aswp[SWP_HOURS].cy	= prcl->yTop - prcl->yBottom - 6L;

ptf->aswp[SWP_MINUTES].x  = ptf->aswp[SWP_HOURS].x + ptf->aswp[SWP_HOURS].cx + ptf->cxSep + 3L;
ptf->aswp[SWP_MINUTES].y  = prcl->yBottom + 3L;
ptf->aswp[SWP_MINUTES].cy = prcl->yTop - prcl->yBottom - 6L;

ptf->aswp[SWP_SECONDS].x  = ptf->aswp[SWP_MINUTES].x + ptf->aswp[SWP_MINUTES].cx + ptf->cxSep +	3L;
ptf->aswp[SWP_SECONDS].y  = prcl->yBottom + 3L;
ptf->aswp[SWP_SECONDS].cy = prcl->yTop - prcl->yBottom - 6L;

WinSetMultWindowPos((HAB)NULL, ptf->aswp, 3UL);
}
#pragma	subtitle("   Time Entry Field Control DLL - Default Colours Procedure")
#pragma	page( )

/* --- SetDefaultColours ------------------------------	[ Private ] ---	*/
/*									*/
/*     This function is	used to	set the	default	colours	that the	*/
/*     image button should use within the internal paint routines.	*/
/*     The colour can either be	a presentation parameter that has	*/
/*     been set	or it can be the default colour	as defined within	*/
/*     control.								*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HWND    hWnd;	= Window Handle					*/
/*     PIMGBTN pimgbtn;	= Image	Button Structure Pointer		*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     Nothing								*/
/*									*/
/* --------------------------------------------------------------------	*/

static VOID SetDefaultColours(HWND hWnd, PTIMEFIELD ptf)

{
		       /* Set up the colours that will be used within	*/
		       /* the painting of the control.	The colour	*/
		       /* indices are:					*/
		       /*						*/
		       /* 0 : Foreground (PP_FOREGROUND*)		*/
		       /* 1 : Background (PP_BACKGROUND*)		*/
		       /* 2 : Hilight Foreground (PP_HILITEFOREGROUND*)	*/
		       /* 3 : Hilight Background (PP_HILITEBACKGROUND*)	*/
		       /* 4 : Disabled Foreground (PP_DISABLEDFORE*)	*/
		       /* 5 : Disabled Foreground (PP_DISABLEDFORE*)	*/
		       /* 6 : Border (PP_BORDER*)			*/

ptf->aClr[0] = lGetPresParam(hWnd, PP_FOREGROUNDCOLOR,
			     PP_FOREGROUNDCOLORINDEX,
			     SYSCLR_OUTPUTTEXT);
ptf->aClr[SWP_MINUTES] = lGetPresParam(hWnd, PP_BACKGROUNDCOLOR,
			     PP_BACKGROUNDCOLORINDEX,
			     SYSCLR_FIELDBACKGROUND);
ptf->aClr[SWP_SECONDS] = lGetPresParam(hWnd, PP_HILITEFOREGROUNDCOLOR,
			     PP_HILITEFOREGROUNDCOLORINDEX,
			     SYSCLR_OUTPUTTEXT);
ptf->aClr[3] = lGetPresParam(hWnd, PP_HILITEBACKGROUNDCOLOR,
			     PP_HILITEBACKGROUNDCOLORINDEX,
			     SYSCLR_BACKGROUND);
ptf->aClr[4] = lGetPresParam(hWnd, PP_DISABLEDFOREGROUNDCOLOR,
			     PP_DISABLEDFOREGROUNDCOLORINDEX,
			     SYSCLR_OUTPUTTEXT);
ptf->aClr[5] = lGetPresParam(hWnd, PP_DISABLEDBACKGROUNDCOLOR,
			     PP_DISABLEDBACKGROUNDCOLORINDEX,
			     SYSCLR_BACKGROUND);
ptf->aClr[6] = lGetPresParam(hWnd, PP_BORDERCOLOR,
			     PP_BORDERCOLORINDEX,
			     SYSCLR_BUTTONDARK);
}
#pragma	subtitle("   System Functions - Parse Date Function")
#pragma	page( )

/* --- fParseTime -----------------------------------------------------	*/
/*									*/
/*     This function is	used to	parse a	submitted date from a		*/
/*     INT a year, month, day integer format.				*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     CHAR *pszTimeStr; = Time	String to Decode			*/
/*     PLONG plHours;	 = Pointer to Hours Holder			*/
/*     PLONG plMinutes;	 = Pointer to Minutes Holder			*/
/*     PLONG plSeconds;	 = Pointer to Seconds Holder			*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     fParseTime =  TRUE : Time String	Successfully Parsed		*/
/*		  = FALSE : Time String	Invalid				*/
/*									*/
/* --------------------------------------------------------------------	*/

BOOL fParseTime(CHAR *pszTimeStr, PLONG	plHours, PLONG plMinutes, PLONG	plSeconds)

{
PCH  pch;			   /* Character	String Pointer		*/
PCH  pchTime;			   /* Date Character String Pointer	*/

if ( (pch = strchr(pszTimeStr, ':')) &&	(strlen(pszTimeStr) >= 5) )
   {
		       /* Extract month	from date string submitted	*/

   *pch	= 0;
   *plHours = (LONG)atol(pszTimeStr);
   if (	(*plHours < 0L)	|| (*plHours > 23L) )

		       /* Illegal month	value, return with not		*/
		       /* successful flag				*/

       return(FALSE);

		       /* Determine day/year separator			*/

   if (	!(pch =	strchr(pchTime = ++pch,	':')) )
       return(FALSE);

		       /* Extract day from date	string submitted	*/

   *pch	= 0;
   *plMinutes =	(LONG)atol(pchTime);
   if (	(*plMinutes < 0L) || (*plMinutes > 59L)	)

		       /* Illegal month	value, return with not		*/
		       /* successful flag				*/

       return(FALSE);

		       /* Extract year from date string	submitted	*/

   *plSeconds =	(LONG)atol(++pch);
   if (	(*plSeconds < 0L) || (*plSeconds > 59L)	)

		       /* Illegal day value, return with not		*/
		       /* successful flag				*/

       return(FALSE);
   return(TRUE);
   }
return(FALSE);
}
#pragma	subtitle("   Time Entry Field Control DLL - Control Window Procedure")
#pragma	page ( )

/* --- TimeFldWndProc ---------------------------------	[ Private ] ---	*/
/*									*/
/*     This function is	used to	handle the messages sent to the		*/
/*     installed control.  The window procedure	is designed to		*/
/*     allow for multiple instances and	to be totally re-entrant.	*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HWND   hWnd; = Window Handle					*/
/*     ULONG  msg;  = PM Message					*/
/*     MPARAM mp1;  = Message Parameter	1				*/
/*     MPARAM mp2;  = Message Parameter	2				*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     TimeFldWndProc =	Message	Handling Result				*/
/*									*/
/* --------------------------------------------------------------------	*/

MRESULT	EXPENTRY TimeFldWndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)

{
CHAR	      szBuffer[16];	   /* String Buffer			*/
DATETIME      dt;		   /* Date/Time	Holder			*/
HPS	      hPS;		   /* Presentation Space Handle		*/
LONG	      lClr;		   /* Presentation Parameter Colour	*/
LONG	      lHours;		   /* Hours Holder			*/
LONG	      lMinutes;		   /* Minutes Holder			*/
LONG	      lSeconds;		   /* Second Holder			*/
PCREATESTRUCT pcrst;		   /* Create Structure Pointer		*/
PTIMEFIELD    ptf;		   /* Text Field Structure Pointer	*/
RECTL	      rcl;		   /* Rectangle	Holder			*/
ULONG	      ulID;		   /* Presentation Parameter ID		*/
PWNDPARAMS    pwprm;		   /* Window Parameters	Pointer		*/
register INT i,	n;		   /* Loop/Index Counters		*/

switch ( msg )
   {
		       /* Perform control initialization when the	*/
		       /* control is created				*/
   case	WM_CREATE :
		       /* Create a heap	for the	control	using a		*/
		       /* segment					*/

       DosAllocMem((PPVOID)(PVOID)&ptf,	4096UL,	PAG_READ | PAG_WRITE | PAG_COMMIT);

		       /* Save the address of the text string pointer	*/
		       /* in the control's reserved memory to allow it  */
		       /* to be	referenced as required by the control	*/

       WinSetWindowPtr(hWnd, QWW_CDATA,	(PVOID)ptf);

		       /* Get the control's creation structure address  */
		       /* to copy the default text of the control to	*/
		       /* the memory in	the heap			*/

       pcrst = (PCREATESTRUCT)PVOIDFROMMP(mp2);

       ptf->hwndOwner =	pcrst->hwndOwner;
       ptf->hwndHours  = WinCreateWindow(hWnd, WC_ENTRYFIELD, NULL,
				       ES_CENTER | ES_MARGIN | ES_AUTOSCROLL | ES_AUTOTAB | WS_GROUP | WS_TABSTOP,
				       0L, 0L, 0L, 0L, hWnd,
				       HWND_TOP, EF_HOURS,
				       pcrst->pCtlData,	pcrst->pPresParams);
       WinSendMsg(ptf->hwndHours, EM_SETTEXTLIMIT, MPFROMSHORT(2), 0L);

       ptf->hwndMinutes	 = WinCreateWindow(hWnd, WC_ENTRYFIELD,	NULL,
					 ES_CENTER | ES_MARGIN | ES_AUTOSCROLL | ES_AUTOTAB | WS_TABSTOP,
					 0L, 0L, 0L, 0L, hWnd,
					 HWND_TOP, EF_MINUTES,
					 pcrst->pCtlData, pcrst->pPresParams);
       WinSendMsg(ptf->hwndMinutes, EM_SETTEXTLIMIT, MPFROMSHORT(2), 0L);

       ptf->hwndSeconds	 = WinCreateWindow(hWnd, WC_ENTRYFIELD,	NULL,
					ES_CENTER | ES_MARGIN |	ES_AUTOSCROLL |	ES_AUTOTAB | WS_TABSTOP,
					0L, 0L,	0L, 0L,	hWnd,
					HWND_TOP, EF_SECONDS,
					pcrst->pCtlData, pcrst->pPresParams);
       WinSendMsg(ptf->hwndSeconds, EM_SETTEXTLIMIT, MPFROMSHORT(2), 0L);

       rcl.xLeft = rcl.yBottom = 0L;
       rcl.xRight = rcl.yTop = 200L;

       WinDrawText(hPS = WinGetPS(hWnd), -1L, " : ", &rcl, 0L, 0L,
		   DT_LEFT | DT_TOP | DT_QUERYEXTENT);

       ptf->cxSep = rcl.xRight - rcl.xLeft;

       rcl.xLeft = rcl.yBottom = 0L;
       rcl.xRight = rcl.yTop = 200L;

       WinDrawText(hPS,	-1L, "444", &rcl, 0L, 0L,
		   DT_LEFT | DT_TOP | DT_QUERYEXTENT);

       ptf->cxField = rcl.xRight - rcl.xLeft;

		       /* Set up the colours that will be used within	*/
		       /* the painting of the control.	The colour	*/
		       /* indices are:					*/
		       /*						*/
		       /* 0 : Foreground (PP_FOREGROUND*)		*/
		       /* 1 : Background (PP_BACKGROUND*)		*/
		       /* 2 : Hilight Foreground (PP_HILITEFOREGROUND*)	*/
		       /* 3 : Hilight Background (PP_HILITEBACKGROUND*)	*/
		       /* 4 : Disabled Foreground (PP_DISABLEDFORE*)	*/
		       /* 5 : Disabled Foreground (PP_DISABLEDFORE*)	*/
		       /* 6 : Border (PP_BORDER*)			*/

       SetDefaultColours(hWnd, ptf);

       ptf->aswp[SWP_HOURS].hwnd   = ptf->hwndHours;
       ptf->aswp[SWP_MINUTES].hwnd = ptf->hwndMinutes;
       ptf->aswp[SWP_SECONDS].hwnd = ptf->hwndSeconds;

       ptf->aswp[SWP_HOURS].fl	 = SWP_MOVE | SWP_SIZE | SWP_SHOW;
       ptf->aswp[SWP_MINUTES].fl = SWP_MOVE | SWP_SIZE | SWP_SHOW;
       ptf->aswp[SWP_SECONDS].fl = SWP_MOVE | SWP_SIZE | SWP_SHOW;

       ptf->aswp[SWP_HOURS].cx	 = ptf->cxField;
       ptf->aswp[SWP_MINUTES].cx = ptf->cxField;
       ptf->aswp[SWP_SECONDS].cx = ptf->cxField;

       ptf->aswp[SWP_HOURS].hwndInsertBehind = HWND_TOP;
       ptf->aswp[SWP_MINUTES].hwndInsertBehind = HWND_TOP;
       ptf->aswp[SWP_SECONDS].hwndInsertBehind = HWND_TOP;


       if ( pcrst->flStyle & DTS_CURRENTTIME )
	   {
	   DosGetDateTime(&dt);
	   WinSetWindowText(ptf->hwndHours,   _ltoa(dt.hours,	szBuffer, 10));
	   if (	dt.minutes < 10	)
	       {
	       strcpy(szBuffer,	"0");
	       i = 1;
	       }
	   else
	       i = 0;
	   _ltoa(dt.minutes, &szBuffer[i], 10);
	   WinSetWindowText(ptf->hwndMinutes, szBuffer);
	   if (	dt.seconds < 10	)
	       {
	       strcpy(szBuffer,	"0");
	       i = 1;
	       }
	   else
	       i = 0;
	   _ltoa(dt.seconds, &szBuffer[i], 10);
	   WinSetWindowText(ptf->hwndSeconds, szBuffer);
	   }
       else
	   if (	pcrst->pszText && pcrst->pszText[0] )
	       if ( fParseTime(strcpy(ptf->szText, pcrst->pszText), &lHours, &lMinutes,	&lSeconds) )
		   {
		   WinSetWindowText(ptf->hwndHours,   _ltoa(lHours,   szBuffer,	10));
		   if (	lMinutes < 10 )
		       {
		       strcpy(szBuffer,	"0");
		       i = 1;
		       }
		   else
		       i = 0;
		   _ltoa(lMinutes,  &szBuffer[i], 10);
		   WinSetWindowText(ptf->hwndMinutes, szBuffer);
		   if (	lSeconds < 10 )
		       {
		       strcpy(szBuffer,	"0");
		       i = 1;
		       }
		   else
		       i = 0;
		   _ltoa(lSeconds,  &szBuffer[i], 10);
		   WinSetWindowText(ptf->hwndSeconds, szBuffer);
		   }

       ptf->flStyle = pcrst->flStyle;

       rcl.xLeft   =\
       rcl.yBottom = 0L;
       rcl.xRight  = pcrst->cx;
       rcl.yTop	   = pcrst->cy;
       CalcSize(&rcl, ptf);
       break;
		       /* Control size changing, update	the rectangle	*/
		       /* points for the Time Entry Field Control	*/
   case	WM_SIZE	:
       WinQueryWindowRect(hWnd,	&rcl);
       CalcSize(&rcl,
		ptf = (PTIMEFIELD)WinQueryWindowPtr(hWnd, QWW_CDATA));
       break;
		       /* Process control notification messages	sent by	*/
		       /* the "roving" entry field.  In	most cases the	*/
		       /* the notification message will	be "repackaged"	*/
		       /* and sent to the owner	of the table for	*/
		       /* processing.					*/
   case	WM_CONTROL :
		       /* Determine the	control	sending	the		*/
		       /* notification message				*/

       switch (	SHORT1FROMMP(mp1) )
	   {
	   case	EF_HOURS :
	       switch (	SHORT2FROMMP(mp1) )
		   {
		       /* Entry	field data changed message received	*/

		   case	EN_CHANGE :
		
		       /* Get the address of the control info from the	*/
		       /* control's reserved memory                     */

		       ptf = (PTIMEFIELD)WinQueryWindowPtr(hWnd, QWW_CDATA);

		       /* Get the text of the entry field and save	*/
		       /* while	it is being entered to ensure that it	*/
		       /* is always current				*/

		       if ( (n = WinQueryWindowText(ptf->hwndHours, 3L,	szBuffer)) != 0	)
			   {
			   for ( i = 0;	i < n; i++ )
			       if ( (szBuffer[i] < '0')	|| (szBuffer[i]	> '9') )
				   {
				   WinSendMsg(ptf->hwndHours, EM_SETSEL,
					      MPFROM2SHORT(i, i	+ 1), 0L);
				   WinAlarm(HWND_DESKTOP, WA_NOTE);
				   WinSetFocus(HWND_DESKTOP, ptf->hwndHours);
				   return(0L);
				   }

			   n = atoi(szBuffer);
			   if (	(n < 0)	|| (n >	23) )
			       {
			       WinAlarm(HWND_DESKTOP, WA_ERROR);
			       WinSendMsg(ptf->hwndHours, EM_SETSEL,
					  MPFROM2SHORT(0, 2), 0L);
			       WinSetFocus(HWND_DESKTOP, ptf->hwndHours);
			       }
			   }
		       break;

		       /* Allow	all other messages to pass through	*/
		       /* unprocessed by the table control owner	*/

		   default :
		       break;
		   }
	       break;

	   case	EF_MINUTES :
	       switch (	SHORT2FROMMP(mp1) )
		   {
		       /* Entry	field data changed message received	*/

		   case	EN_CHANGE :
		
		       /* Get the address of the control info from the	*/
		       /* control's reserved memory                     */

		       ptf = (PTIMEFIELD)WinQueryWindowPtr(hWnd, QWW_CDATA);

		       /* Get the text of the entry field and save	*/
		       /* while	it is being entered to ensure that it	*/
		       /* is always current				*/

		       if ( (n = WinQueryWindowText(ptf->hwndMinutes, 3L, szBuffer)) !=	0 )
			   {
			   for ( i = 0;	i < n; i++ )
			       if ( (szBuffer[i] < '0')	|| (szBuffer[i]	> '9') )
				   {
				   WinAlarm(HWND_DESKTOP, WA_NOTE);
				   WinSendMsg(ptf->hwndMinutes,	EM_SETSEL,
					      MPFROM2SHORT(i, i	+ 1), 0L);
				   WinSetFocus(HWND_DESKTOP, ptf->hwndMinutes);
				   return(0L);
				   }

			   n = atoi(szBuffer);
			   if (	(n < 0)	|| (n >	59) )
			       {
			       WinAlarm(HWND_DESKTOP, WA_ERROR);
			       WinSendMsg(ptf->hwndMinutes, EM_SETSEL,
					  MPFROM2SHORT(0, 2), 0L);
			       WinSetFocus(HWND_DESKTOP, ptf->hwndMinutes);
			       }
			   }
		       break;

		       /* Allow	all other messages to pass through	*/
		       /* unprocessed by the table control owner	*/

		   default :
		       break;
		   }
	       break;


	   case	EF_SECONDS :
	       switch (	SHORT2FROMMP(mp1) )
		   {
		       /* Entry	field data changed message received	*/

		   case	EN_CHANGE :
		
		       /* Get the address of the control info from the	*/
		       /* control's reserved memory                     */

		       ptf = (PTIMEFIELD)WinQueryWindowPtr(hWnd, QWW_CDATA);

		       /* Get the text of the entry field and save	*/
		       /* while	it is being entered to ensure that it	*/
		       /* is always current				*/

		       if ( (n = WinQueryWindowText(ptf->hwndSeconds, 3L, szBuffer)) !=	0 )
			   for ( i = 0;	i < n; i++ )
			       if ( (szBuffer[i] < '0')	|| (szBuffer[i]	> '9') )
				   {
				   WinAlarm(HWND_DESKTOP, WA_NOTE);
				   WinSendMsg(ptf->hwndSeconds,	EM_SETSEL,
					      MPFROM2SHORT(i, i	+ 1), 0L);
				   WinSetFocus(HWND_DESKTOP, ptf->hwndSeconds);
				   return(0L);
				   }
			   n = atoi(szBuffer);
			   if (	(n < 0)	|| (n >	59) )
			       {
			       WinAlarm(HWND_DESKTOP, WA_ERROR);
			       WinSendMsg(ptf->hwndSeconds, EM_SETSEL,
					  MPFROM2SHORT(0, 2), 0L);
			       WinSetFocus(HWND_DESKTOP, ptf->hwndSeconds);
			       }
		       break;

		       /* Allow	all other messages to pass through	*/
		       /* unprocessed by the table control owner	*/

		   default :
		       break;
		   }
	       break;

	   default :
	       break;
	   }
       break;
		       /* Process window parameters setting		*/

   case	WM_SETWINDOWPARAMS :

		       /* Get the address for the windows parameters	*/
		       /* structure					*/

       pwprm = (PWNDPARAMS)PVOIDFROMMP(mp1);

		       /* Check	to see if the text for the control is	*/
		       /* being	set					*/

       if ( pwprm->fsStatus & WPM_TEXT )
	   {
		       /* Text being set, get the address of the text	*/
		       /* string stored	in the heap			*/

	   ptf = (PTIMEFIELD)WinQueryWindowPtr(hWnd, QWW_CDATA);

		       /* Check	to see if any text is being set		*/

	   if (	pwprm->cchText )
	       {
		       /* Check	to make	sure that the text that	is to	*/
		       /* be set is not	greater	than the memory		*/
		       /* allocated					*/

	       if ( pwprm->cchText > 15	)
		   {
		   strncpy(ptf->szText,	pwprm->pszText,	15);
		   ptf->szText[16] = 0;
		   }
	       else
		   strcpy(ptf->szText, pwprm->pszText);

	       if ( fParseTime(ptf->szText, &lHours, &lMinutes,	&lSeconds) )
		   {
		   WinSetWindowText(ptf->hwndHours,   _ltoa(lHours,   szBuffer,	10));
		   if (	lMinutes < 10 )
		       {
		       strcpy(szBuffer,	"0");
		       i = 1;
		       }
		   else
		       i = 0;
		   _ltoa(lMinutes, &szBuffer[i], 10);
		   WinSetWindowText(ptf->hwndMinutes, szBuffer);
		   if (	lSeconds < 10 )
		       {
		       strcpy(szBuffer,	"0");
		       i = 1;
		       }
		   else
		       i = 0;
		   _ltoa(lSeconds, &szBuffer[i], 10);
		   WinSetWindowText(ptf->hwndSeconds, szBuffer);
		   }
	       }
	   else
	       {
		       /* No text is being set,	clear any existing text	*/

	       ptf->szText[0] =	0;
	       WinSetWindowText(ptf->hwndHours	, "");
	       WinSetWindowText(ptf->hwndMinutes, "");
	       WinSetWindowText(ptf->hwndSeconds , "");
	       }
	   }
       break;
		       /* Process window parameters query		*/

   case	WM_QUERYWINDOWPARAMS :

		       /* Get the address for the windows parameters	*/
		       /* structure					*/

       pwprm = (PWNDPARAMS)PVOIDFROMMP(mp1);

		       /* Determine the	type of	query			*/

       switch (	pwprm->fsStatus	)
	   {
		       /* Query	type:  get text				*/

	   case	WPM_TEXT :

		       /* Text being asked for,	get the	address	of the	*/
		       /* text string stored in	the heap		*/

	       ptf = (PTIMEFIELD)WinQueryWindowPtr(hWnd, QWW_CDATA);

	       WinQueryWindowText(ptf->hwndHours,   3L,	szBuffer);
	       strcat(szBuffer,	" : ");
	       WinQueryWindowText(ptf->hwndMinutes, 3L,	&szBuffer[strlen(szBuffer)]);
	       strcat(szBuffer,	" : ");
	       WinQueryWindowText(ptf->hwndSeconds, 3L,	&szBuffer[strlen(szBuffer)]);

		       /* Copy the text	from the string	to the		*/
		       /* structure					*/

	       strcpy(pwprm->pszText, szBuffer);
	       break;
		       /* Query	type:  get text	length			*/

	   case	WPM_CCHTEXT :

		       /* Place	the length the string within the	*/
		       /* structure					*/

	       WinQueryWindowText(ptf->hwndHours,   3L,	szBuffer);
	       strcat(szBuffer,	" : ");
	       WinQueryWindowText(ptf->hwndMinutes, 3L,	&szBuffer[strlen(szBuffer)]);
	       strcat(szBuffer,	" : ");
	       WinQueryWindowText(ptf->hwndSeconds, 3L,	&szBuffer[strlen(szBuffer)]);
	       pwprm->cchText =	strlen(szBuffer);
	       break;
		       /* Query	type:  get control data	length		*/

	   case	WPM_CBCTLDATA :

		       /* Set the control data length to zero		*/

	       pwprm->cbCtlData	= 0;
	       break;

	   default :
	       return(WinDefWindowProc(hWnd, msg, mp1, mp2));
	   }
       break;
		       /* Presentation parameters changed, record the	*/
		       /* change internally				*/

   case	WM_PRESPARAMCHANGED :
       if ( LONGFROMMP(mp1) < PP_FONTNAMESIZE )
	   {
	   ptf = (PTIMEFIELD)WinQueryWindowPtr(hWnd, QWW_CDATA);
	   if (	WinQueryPresParam(hWnd,	(ULONG)LONGFROMMP(mp1),
				  (ULONG)((LONGFROMMP(mp1) % 2)	? LONGFROMMP(mp1) + 1L : 0L),
				  &ulID, 4UL, (PVOID)&lClr,
				  QPF_NOINHERIT	| QPF_ID1COLORINDEX | QPF_ID2COLORINDEX) )
	       ptf->aClr[(LONGFROMMP(mp1) - 1L)	/ 2L] =	lClr;

	   WinInvalidateRect(hWnd, (PRECTL)NULL, TRUE);
	   }
		       /* Check	to see if an individual	presentation	*/
		       /* parameter has	changed	if so, get the new	*/
		       /* colour value for use by the painting routines	*/

       if ( LONGFROMMP(mp1) && (LONGFROMMP(mp1)	< PP_FONTNAMESIZE) )
	   {
		       /* Get the address of the control info from the	*/
		       /* control's reserved memory                     */

	   ptf = (PTIMEFIELD)WinQueryWindowPtr(hWnd, QWW_CDATA);

		       /* Get the new presentation parameter colour for	*/
		       /* the presentation parameter that has changed.	*/
		       /* Get the colour as a RGB value	so as to be	*/
		       /* able to get an exact value and not an		*/
		       /* approximation	which could happen if the	*/
		       /* presentation parameter was set as a RGB but	*/
		       /* queried as an	index.	When WinQueryPresParam	*/
		       /* returns a 0, it indicates that no		*/
		       /* presentation parameter set and the default	*/
		       /* colours should be used.			*/

	   switch ( LONGFROMMP(mp1) )
	       {
	       case PP_FOREGROUNDCOLOR :
	       case PP_FOREGROUNDCOLORINDEX :
		   ptf->aClr[0]	= lGetPresParam(hWnd, PP_FOREGROUNDCOLOR,
						PP_FOREGROUNDCOLORINDEX,
						SYSCLR_OUTPUTTEXT);
		   WinSetPresParam(ptf->hwndHours,
				   PP_FOREGROUNDCOLOR,
				   4L, (PVOID)&ptf->aClr[0]);
		   WinSetPresParam(ptf->hwndMinutes,
				   PP_FOREGROUNDCOLOR,
				   4L, (PVOID)&ptf->aClr[0]);
		   WinSetPresParam(ptf->hwndSeconds,
				   PP_FOREGROUNDCOLOR,
				   4L, (PVOID)&ptf->aClr[0]);
		   break;

	       case PP_BACKGROUNDCOLOR :
	       case PP_BACKGROUNDCOLORINDEX :
		   ptf->aClr[SWP_MINUTES] = lGetPresParam(hWnd,	PP_BACKGROUNDCOLOR,
						PP_BACKGROUNDCOLORINDEX,
						SYSCLR_BACKGROUND);
		   WinSetPresParam(ptf->hwndHours,
				   PP_BACKGROUNDCOLOR,
				   4L, (PVOID)&ptf->aClr[SWP_MINUTES]);
		   WinSetPresParam(ptf->hwndMinutes,
				   PP_BACKGROUNDCOLOR,
				   4L, (PVOID)&ptf->aClr[SWP_MINUTES]);
		   WinSetPresParam(ptf->hwndSeconds,
				   PP_BACKGROUNDCOLOR,
				   4L, (PVOID)&ptf->aClr[SWP_MINUTES]);
		   break;

	       case PP_HILITEFOREGROUNDCOLOR :
	       case PP_HILITEFOREGROUNDCOLORINDEX :
		   ptf->aClr[SWP_SECONDS] = lGetPresParam(hWnd,	PP_HILITEFOREGROUNDCOLOR,
						PP_HILITEFOREGROUNDCOLORINDEX,
						SYSCLR_OUTPUTTEXT);
		   break;

	       case PP_HILITEBACKGROUNDCOLOR :
	       case PP_HILITEBACKGROUNDCOLORINDEX :
		   ptf->aClr[3]	= lGetPresParam(hWnd, PP_HILITEBACKGROUNDCOLOR,
						PP_HILITEBACKGROUNDCOLORINDEX,
						SYSCLR_BACKGROUND);
		   break;

	       case PP_DISABLEDFOREGROUNDCOLOR :
	       case PP_DISABLEDFOREGROUNDCOLORINDEX :
		   ptf->aClr[4]	= lGetPresParam(hWnd, PP_DISABLEDFOREGROUNDCOLOR,
						PP_DISABLEDFOREGROUNDCOLORINDEX,
						SYSCLR_OUTPUTTEXT);
		   break;

	       case PP_DISABLEDBACKGROUNDCOLOR :
	       case PP_DISABLEDBACKGROUNDCOLORINDEX :
		   ptf->aClr[5]	= lGetPresParam(hWnd, PP_BACKGROUNDCOLOR,
						PP_BACKGROUNDCOLORINDEX,
						SYSCLR_BACKGROUND);
		   break;

	       case PP_BORDERCOLOR :
	       case PP_BORDERCOLORINDEX	:
		   ptf->aClr[6]	= lGetPresParam(hWnd, PP_BORDERCOLOR,
						PP_BORDERCOLORINDEX,
						SYSCLR_BUTTONDARK);
		   break;
	       }
		       /* Invalidate the button	to force to use	the	*/
		       /* new colours just set or removed		*/

	   WinInvalidateRect(hWnd, (PRECTL)NULL, TRUE);
	   }
       else
		       /* Determine if the Scheme Palette has forced a	*/
		       /* global scheme	update in which	case, check all	*/
		       /* of the presentation parameters to see	if they	*/
		       /* have been added or removed			*/

	   if (	LONGFROMMP(mp1)	== 0L )

		       /* Set up the colours that will be used within	*/
		       /* the painting of the control.			*/

	       SetDefaultColours(hWnd,
				 ptf = (PTIMEFIELD)WinQueryWindowPtr(hWnd, QWW_CDATA));
       break;
		       /* Erase	control	background			*/

   case	WM_ERASEBACKGROUND :
       return(MRFROMLONG(TRUE));

		       /* Paint	the Control				*/
   case	WM_PAINT :
		       /* Get the address of the text from the		*/
		       /* control's reserved memory                     */

       ptf = (PTIMEFIELD)WinQueryWindowPtr(hWnd, QWW_CDATA);

		       /* Get the presentation space for the control	*/
		       /* and set the colour table to RGB mode		*/

       GpiCreateLogColorTable(hPS = WinBeginPaint(hWnd,	(HPS)NULL, (PRECTL)NULL),
			      0L, LCOLF_RGB, 0L, 0L, (PLONG)NULL);

       rcl.xRight = (rcl.xLeft = ptf->aswp[SWP_HOURS].x	+ ptf->aswp[SWP_HOURS].cx) + ptf->cxSep;
       rcl.yTop	= (rcl.yBottom = ptf->aswp[SWP_HOURS].y) + ptf->aswp[SWP_HOURS].cy;

       WinDrawText(hPS,	-1L, " : ", &rcl, 0L, 0L,
		   DT_CENTER | DT_VCENTER | DT_TEXTATTRS);

       rcl.xRight = (rcl.xLeft = ptf->aswp[SWP_MINUTES].x + ptf->aswp[SWP_MINUTES].cx) + ptf->cxSep;
       rcl.yTop	= (rcl.yBottom = ptf->aswp[SWP_MINUTES].y) + ptf->aswp[SWP_MINUTES].cy;

       WinDrawText(hPS,	-1L, " : ", &rcl, 0L, 0L,
		   DT_CENTER | DT_VCENTER | DT_TEXTATTRS);

       WinEndPaint(hPS);
       break;
		       /* Control being	destroyed			*/
   case	WM_DESTROY :
		       /* Get the address of the text from the		*/
		       /* control's reserved memory                     */

       ptf = (PTIMEFIELD)WinQueryWindowPtr(hWnd, QWW_CDATA);
       WinDestroyWindow(ptf->hwndHours);
       WinDestroyWindow(ptf->hwndMinutes);
       WinDestroyWindow(ptf->hwndSeconds);

		       /* Release the heap allocated for use by	the	*/
		       /* control					*/

       DosFreeMem((PVOID)ptf);
       break;
		       /* Default message processing			*/
   default :
       return(WinDefWindowProc(hWnd, msg, mp1, mp2));
   }

return(0L);
}
#pragma	subtitle("   Time Entry Field Control DLL - Control Styles Dialogue Procedure")
#pragma	page ( )

/* --- TimeFldStyles --------------------------------------------------	*/
/*									*/
/*     This function is	used for the custom control's styles dialogue   */
/*     box procedure.							*/
/*									*/
/*     When the	dialogue is invoked from Resource Editor, the	     */
/*     address of the user style information is	contained in message	*/
/*     parameter 2.  The dialogue is responsible for saving the		*/
/*     address.	 The best method to do this is to save the pointer	*/
/*     in the dialogue's reserved memory where it can be retrieved as   */
/*     needed.								*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HWND   hWnd; = Dialog Window Handle				*/
/*     ULONG  msg;  = PM Message					*/
/*     MPARAM mp1;  = Message Parameter	1				*/
/*     MPARAM mp2;  = Message Parameter	2				*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     TimeFldStyles = Message Handling	Result				*/
/*									*/
/* --------------------------------------------------------------------	*/

MRESULT	EXPENTRY TimeFldStyles(HWND hWnd, ULONG	msg, MPARAM mp1, MPARAM	mp2)

{
PUSERSTYLE   pust;		   /* User Style Pointer		*/
SWP	     swp;		   /* Screen Window Position Holder	*/

switch ( msg )
   {
		       /* Perform dialogue initialization		*/
   case	WM_INITDLG :
		       /* Save the pointer to user style information	*/
		       /* within the dialog's reserved memory           */

       WinSetWindowPtr(hWnd, QWL_USER, (PVOID)mp2);

		       /* Get the pointer to the user style information	*/

       if ( (pust = (PUSERSTYLE)mp2) !=	NULL )
	   {
		       /* Set the text,	ID symbol and value for	the	*/
		       /* control					*/

	   WinSetDlgItemText(hWnd, EF_TEXT, pust->pszText);
	   pust->pfnSetSymbolID(hWnd, IDBX_SYMBOLVALUE,	pust);

	   if (	pust->flStyle &	DTS_CURRENTTIME	)
	       WinSendDlgItemMsg(hWnd, CB_CURRENTTIME, BM_SETCHECK,
				 MPFROMSHORT(TRUE), 0L);

	   if (	pust->flStyle &	WS_VISIBLE )
	       WinSendDlgItemMsg(hWnd, CB_VISIBLE, BM_SETCHECK,
				 MPFROMSHORT(TRUE), 0L);

	   if (	pust->flStyle &	WS_GROUP )
	       WinSendDlgItemMsg(hWnd, CB_GROUP, BM_SETCHECK,
				 MPFROMSHORT(TRUE), 0L);

	   if (	pust->flStyle &	WS_DISABLED )
	       WinSendDlgItemMsg(hWnd, CB_DISABLED, BM_SETCHECK,
				 MPFROMSHORT(TRUE), 0L);

	   if (	pust->flStyle &	WS_TABSTOP )
	       WinSendDlgItemMsg(hWnd, CB_TABSTOP, BM_SETCHECK,
				 MPFROMSHORT(TRUE), 0L);
	   }
		       /* Centre dialog	on the screen			*/

       WinQueryWindowPos(hWnd, (PSWP)&swp);
       WinSetWindowPos(hWnd, HWND_TOP,
		       (WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN) - swp.cx) /	2L,
		       (WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - swp.cy) /	2L,
		       0L, 0L, SWP_MOVE);
       break;
		       /* Process push button selections		*/
   case	WM_COMMAND :
       switch (	SHORT1FROMMP(mp1) )
	   {
		       /* Presentation push button selected		*/

	   case	DID_FONTCLR :

		       /* Get the pointer to the user style information	*/

	       if ( (pust = PDATAFROMDLG(hWnd))	!= NULL	)

		       /* Get the address of the look up function from	*/
		       /* user style information structure and display	*/
		       /* the dialog.  The value selected within the	*/
		       /* dialog will be automatically placed within	*/
		       /* the required entry fields			*/

		   pust->pfnGetFontClr(hWnd);
	       break;
		       /* Enter	pushbutton selected get	the definitions	*/
		       /* for the control				*/
	   case	DID_OK :

		       /* Get the pointer to the user style information	*/

	       if ( (pust = PDATAFROMDLG(hWnd))	!= NULL	)
		   {
		       /* Get the address of the CUA compliance		*/
		       /* function from	the user style information	*/
		       /* structure.  The function will	check the text	*/
		       /* for CUA compliance according to index	value	*/
		       /* selected.  A return value of TRUE from the	*/
		       /* compliance function indicates	that the text	*/
		       /* entered is acceptable.  Conversely, a	FALSE	*/
		       /* return value indicates that text is non-	*/
		       /* compliant.  In this case, the	dialog should	*/
		       /* not be exited	from and the values within the	*/
		       /* the entry fields should not be saved.		*/

		   if (	!pust->pfnCUACheck(hWnd, EF_TEXT, CUACHK_CAPS) )
		       break;

		       /* Get the address of the symbol	validation	*/
		       /* function from	the user style information	*/
		       /* structure.  The function will	validate the	*/
		       /* symbol and will check	for duplications of	*/
		       /* values.  A return value of TRUE from the	*/
		       /* validation function indicates	that the symbol	*/
		       /* and value are	acceptable.  Conversely, a	*/
		       /* FALSE	return value indicates that symbol or	*/
		       /* value	was not	acceptable.  In	this case,	*/
		       /* the dialog should not	be exited from and the	*/
		       /* values within	the entry fields should	not be	*/
		       /* saved.					*/

		   if (	!pust->pfnGetSymbolID(hWnd, IDBX_SYMBOLVALUE, pust) )
		       break;
		   else
		       {
		       /* Symbol and value validated, get the text of	*/
		       /* the control and save within the user style	*/
		       /* information structure	for use	by Resource	*/
		       /* Editor					*/

		       pust->cText = WinQueryDlgItemText(hWnd, EF_TEXT,
							 16UL, pust->pszText);

		       /* Mask out current edit	field styles clearing	*/
		       /* selectable styles and	save new style		*/

		       pust->flStyle &=	0xffff8000UL;

		       if ( WinSendDlgItemMsg(hWnd, CB_CURRENTTIME,
					      BM_QUERYCHECK, 0L, 0L) )
			   pust->flStyle |= DTS_CURRENTTIME;

		       /* Save completed edit field style in internal	*/
		       /* window information				*/

		       pust->flStyle &=	~(WS_VISIBLE | WS_GROUP	| WS_DISABLED |	WS_TABSTOP);
		       if ( WinSendDlgItemMsg(hWnd, CB_VISIBLE,
					      BM_QUERYCHECK, 0L, 0L) )
			   pust->flStyle |= WS_VISIBLE;

		       if ( WinSendDlgItemMsg(hWnd, CB_GROUP,
					      BM_QUERYCHECK, 0L, 0L) )
			   pust->flStyle |= WS_GROUP;

		       if ( WinSendDlgItemMsg(hWnd, CB_DISABLED,
					      BM_QUERYCHECK, 0L, 0L) )
			   pust->flStyle |= WS_DISABLED;

		       if ( WinSendDlgItemMsg(hWnd, CB_TABSTOP,
					      BM_QUERYCHECK, 0L, 0L) )
			   pust->flStyle |= WS_TABSTOP;
		       }
		   }
		       /* Exit the dialogue indicating changes made	*/

	       WinDismissDlg(hWnd, TRUE);
	       break;
		       /* Cancel selected, exit	the dialogue without	*/
		       /* changing anything				*/

	   case	DID_CANCEL :
	       WinDismissDlg(hWnd, FALSE);
	       break;
	   }
       break;
		       /* Close	received, exit dialog			*/
   case	WM_CLOSE :
       WinDismissDlg(hWnd, FALSE);
       break;
		       /* Pass through unhandled messages		*/
   default :
       return(WinDefDlgProc(hWnd, msg, mp1, mp2));
   }
return(0L);

}
