home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
CPROG
/
WINDATE.ZIP
/
DATE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-27
|
35KB
|
828 lines
/* DATE.C - Mark Jones' date/calendar routines for Windows 3.0
Copyright (c) 1990, 1991, Mark Jones
713 Lisa Ln.
Cedar Hill, TX 75104
(214) 291-0509
Compuserve 70511,706
*/
#define _WINDOWS
#define _WINDLL
#include <windows.h>
#include "Date.h"
#include <float.h>
#include <math.h>
/*****************************************************************************
MODIFICATION LOG
Date Version Who Change
---- ------- --- --------------------------------------------------
3 OCT 90 1.00 Mark J. Added DATE.ICO as a resource
Finished DateObj() and tested
22 OCT 1.01 Mark J. Add _WINDOWS and _WINDLL and recompiled with
warning level 3 (W3), fixing certain conversion
warnings
2/10/91 Changed "<win.h>" reference to <windows.h>
*****************************************************************************/
/*****************************************************************************/
/* MISC. DEFINITIONS */
#define SET_ERR(ErrCode) ( ((((LONG) DATE_ERROR)<<16)&0xFFFF0000L) + ErrCode)
/*****************************************************************************/
/* GLOBAL FIELDS */
int MoDaTbl[12] = { /* days-in-month table */
31, 29, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31 };
/*****************************************************************************/
/*****************************************************************************/
/* OBJECT-ORIENTED DATE.DLL FUNCTIONS */
/*****************************************************************************/
/*****************************************************************************/
/* DateObj() : INTERFACE WITH DATE.DLL AS A SINGLE OBJECT */
/* This function allows external access to the functionality of DATE.DLL via
a generic "object" interface. "DateObj" is the name of the object, and this
function presents "DateObj" in a way that resembles the interface to a
true object. Such an interface may be desirable in table-driven
applications, or in systems that recognize only primitive data types,
and have no ability to inspect a data structure. DateObj() is also
applicable to third-party software tools that cannot efficiently access
data-structure elements, such as Toolbook and Plus, or simply in situations
where a simpler, object-oriented interface is desired.
----------
PROTOTYPE:
----------
LONG FAR PASCAL DateObj(HANDLE hDateObj, WORD uMsg, WORD uID, LONG lParam)
------
INPUT:
------
The following input parameters are used in the interface with "DateObj" :
Parameter Possible values Meaning/Usage
--------- --------------- ----------------------------------------------
HANDLE hDateObj This is the handle to an instance of the
"DateObj" object. Each object-instance will
be created by the CREATE message.
WORD uMsg CREATE Creates a new "DateObj" object - used only
when the ID value is DATE
DELETE Deletes an existing "DateObj" object - used
only when the ID value is DATE
SET Used to set a property or value in DateObj,
or to initialize the entire DateObj to NULLs
GET Retrieves a propery or value from DateObj
CALCULATE Forces DateObj to recalculate itself, based
on either a julian or a normal date; the
calculation method is determined by setting
lParam to either JULIAN or NORMAL. When
CALCULATE is used, the value of uID doesn't
matter.
WORD uID DATE A "DateObj" object - used only with CREATE,
DELETE, and SET messages
MONTH Month number, from 1 to 12
DAY Day of month, from 1 to 31
YEAR Year, from 1901 to 2100
JULIANDATE Julian date value, from 1 to 72743
LEAPYEAR Does this date fall within a leap year?
DAYOFWEEK What is the day of the week (0 to 6)?
DAYOFYEAR What is the day of the year (1 to 366)?
DAYSINMONTH How many days are in the month (1 to 31)?
LONG lParam * The lParam parameter is used only when the
uMsg has a value of SET. lParam should
contain the numeric value associated with
the uID during a SET operation. The following
values are valid lParam values:
uID valid lParam value(s)
--- ----------------------
DATE 0
MONTH 1 to 12
DAY 1 to 31
YEAR 1 to 2100
JULIANDATE 1 to 72743
LEAPYEAR N/A (does not use SET)
DAYOFWEEK N/A (does not use SET)
DAYOFYEAR N/A (does not use SET)
-------
OUTPUT:
-------
The "DateObj" function returns a LONG value which varies depending on the
input-message and the ID. If an error occurred, the HIWORD of the
LONG return value will contain the value DATE_ERROR, and the LOWORD
will contain a mnemonic code explaining the cause of the error. The
following table summarizes the meanings of the possible error values
in LOWORD:
LOWORD error value Meaning
------------------ ----------------------------------------------
GENERAL_FAILURE The operation cannot be performed because of
an underlying system failure, such as a lack
of memory, etc.
BAD_INPUT A bad lParam value was passed to DateObj().
NULL_HANDLE The hDateObj value had a NULL (0) value.
BAD_HANDLE The hDateObj value was non-NULL, but it was not
usable by DateObj().
BAD_ID The uID value was not valid. See the "INPUT"
section above for a list of valid uID values.
WRONG_ID The uID value was valid, but was not usable
in the context of the call. For example, since
a CREATE message applies only to a DATE object,
the following would produce an error:
lResult =
DateObj(hDateObj, CREATE, MONTH, lParam);
but the following would be valid:
lResult =
DateObj(hDateObj, CREATE, DATE, lParam);
BAD_MESSAGE An invalid value was passed on the uMsg parameter.
Consult the "INPUT" section above for a list of
valid uMsg values.
FATAL_ERROR An unexplainable error occurred during a CALCULATE
operation, and DateObj couldn't complete its
processing. This error points to a bug in DATE.DLL!
More specific information is provided below explaining the possible error-
return values.
If the HIWORD of the LONG return value is not equal to DATE_ERROR, the
LOWORD value represents the result of a normal procedure.
The way to test for success after returning from a DateObj() call is with
statements similar to:
lResult = DateObj(hDateObj, uMsg, uId, lParam);
if (HIWORD(lResult) != DATE_ERROR)
nResultNormal = LOWORD(lResult);
else
myErrorHandler(LOWORD(lResult));
The following table details the possible DateObj() return values.
-----------------------------
DateObj() return-values table
-----------------------------
uMsg DateObj LONG return value
---- ----------------------------------------------------------------
CREATE HIWORD = DATE_ERROR: A Date object could not be created
LOWORD = GENERAL_FAILURE:
Memory could not be alloc'd
WRONG_ID: A uID != DATE was passed
-*-
HIWORD = 0: The instance of DateObj was created
LOWORD = A valid handle to the DateObj object
DELETE HIWORD = DATE_ERROR: The Date object could not be
deleted
LOWORD = WRONG_ID: A uID != DATE was passed, or
the hDateObj parameter was NULL
NULL_HANDLE:A value of NULL (0) was passed in hDateObj
GENERAL_FAILURE:
DateObj memory cannot be freed! The
hDateObj value might be garbage.
-*-
HIWORD = 0: The instance of DateObj was destroyed.
LOWORD = hDateObj (this handle is now meaningless)
SET HIWORD = DATE_ERROR: The element could not be set
LOWORD = BAD_INPUT: A bad value was passed, which fell outside
the allowed range.
NULL_HANDLE:The hDateObj handle was NULL (0).
BAD_HANDLE: The hDateObj handle parameter was garbage.
-*-
HIWORD = 0: The item was initialized. If uID == DATE, then
the DateObj was set to all NULLs (0s).
LOWORD = hDateObj
GET HIWORD = DATE_ERROR: The element could not be retrieved
LOWORD = NULL_HANDLE:The hDateObj handle was NULL (0).
GENERAL_FAILURE:
The DateObj could not be found. The
hDateObj handle might be garbage!
BAD_ID: The uID value was not recognized. See
the "INPUT" section above for a list
of the valid values for uID.
-*-
HIWORD = 0: The element's value was successfully retrieved.
LOWORD = Element value (except with YEAR, in which it is likely
that a portion of the HIWORD could be used; in any case,
the HIWORD will never == DATE_ERROR on a normal return)
CALCULATE
HIWORD = DATE_ERROR: DateObj could not calculate itself
LOWORD = NULL_HANDLE:The hDateObj handle was NULL (0).
GENERAL_FAILURE:
The DateObj could not be found. The
hDateObj handle might be garbage!
BAD_INPUT: The values in DateObj from which the
calculations are made are bad -- you
screwed up by passing a wrong value
during a SET message.
FATAL_ERROR:A bug exists in DATE.DLL! Scream
vigorously at Mark Jones.
<other> HIWORD = DATE_ERROR: An invalid uMsg value was used
LOWORD = BAD_MESSAGE: "
*/
/*****************************************************************************/
LONG FAR PASCAL DateObj(HANDLE hDateObj, WORD uMsg, WORD uID, LONG lParam)
{
LONG lReturn; // return() value
Date FAR *fpDate; // &DateObj
// INITIALIZE RETURN VALUE TO NO-ERROR
lReturn = 0;
// MAIN OBJECT-MESSAGE (uMsg) DISPATCH switch:
switch(uMsg)
{
//******************************************************************
case CREATE: // CREATE A NEW DateObj
if (uID != DATE)
{
lReturn = SET_ERR(WRONG_ID);
break;
}
lReturn = (LONG) GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
sizeof(Date));
if (!lReturn)
{
lReturn = SET_ERR(GENERAL_FAILURE);
break;
}
break; // end of uMsg case CREATE
//******************************************************************
case DELETE: // DELETE AN EXISTING DateObj
if (uID != DATE) // If ID doesn't belong here,
{
lReturn = SET_ERR(WRONG_ID); // return a WRONG_ID
break;
}
if (!hDateObj) // If NULL hDateObj
{
lReturn = SET_ERR(NULL_HANDLE); // return a BAD_INPUT
break;
}
lReturn = hDateObj; // Set lReturn to != DATE_ERROR
if (GlobalFree(hDateObj)) // If block cannot be freed,
lReturn = SET_ERR(GENERAL_FAILURE); // return a GENERAL_FAILURE
break; // end of uMsg case DELETE
//******************************************************************
case SET: // SET A PROPERTY OR VALUE
if (!hDateObj) // If bad hDateObj handle,
{
lReturn = SET_ERR(NULL_HANDLE); // return a DATE_ERROR
break;
}
// Get a far pointer to DateObj
lReturn = (LONG) GlobalLock(hDateObj);
if (!lReturn) // If unsuccessful,
{
lReturn = SET_ERR(BAD_HANDLE); // return a BAD_HANDLE
break;
}
fpDate = (Date FAR *) lReturn; // store &DateObj in fpDate
lReturn = hDateObj; // successful so far
switch(uID) // Route message
{
//----------------------------------------------------------
case DATE: // SETting a DATE
fpDate->nYear = // set DateObj to all 0's
fpDate->nMonth =
fpDate->nDay =
fpDate->nLeapYear =
fpDate->nError =
fpDate->nYearDays =
fpDate->nDayOfWeek = 0;
fpDate->lJulianDate = 0L;
break;
//----------------------------------------------------------
case MONTH: // SETting a MONTH
if (lParam < 1 || lParam > 12) // If outside valid range,
lReturn = SET_ERR(BAD_INPUT); // return BAD_INPUT
else // else,
// set nMonth to lParam
fpDate->nMonth = LOWORD(lParam);
break;
//----------------------------------------------------------
case DAY: // SETting a DAY
if (lParam < 1 || lParam > 31) // If outside valid range,
lReturn = SET_ERR(BAD_INPUT); // return BAD_INPUT
else // else,
fpDate->nDay = LOWORD(lParam);// set nDay to lParam
break;
//----------------------------------------------------------
case YEAR: // SETting a YEAR
// If outside valid range,
if (lParam < BASE_YEAR || lParam > CEIL_YEAR)
lReturn = SET_ERR(BAD_INPUT); // return BAD_INPUT
else // else,
// set nYear to lParam
fpDate->nYear = LOWORD(lParam);
break;
//----------------------------------------------------------
case JULIANDATE: // SETting a JULIANDATE
// If outside valid range,
if (lParam < 1 || lParam > MAX_JULIAN)
lReturn = SET_ERR(BAD_INPUT); // return BAD_INPUT
else // else,
fpDate->lJulianDate = lParam; // set lJulianDate to lParam
break;
//----------------------------------------------------------
default: // bad uID!
lReturn = SET_ERR(BAD_ID);
} // end of switch(uID)
GlobalUnlock(hDateObj); // Release fpDate
break; // end of uMsg case SET
//******************************************************************
case GET: // GET A PROPERTY OR VALUE
if (!hDateObj) // If bad hDateObj handle,
{
lReturn = SET_ERR(NULL_HANDLE); // return an DATE_ERROR
break;
}
// Get a far pointer to DateObj
lReturn = (LONG) GlobalLock(hDateObj);
if (!lReturn) // If unsuccessful,
{
lReturn = SET_ERR(GENERAL_FAILURE); // return a GENERAL_FAILURE
break;
}
fpDate = (Date FAR *) lReturn; // store &DateObj in fpDate
lReturn = hDateObj; // successful so far
switch(uID) // Route message
{
//----------------------------------------------------------
case MONTH: // GETting a MONTH
lReturn = fpDate->nMonth;
break;
//----------------------------------------------------------
case DAY: // GETting a DAY
lReturn = fpDate->nDay;
break;
//----------------------------------------------------------
case YEAR: // GETting a YEAR
lReturn = fpDate->nYear;
break;
//----------------------------------------------------------
case JULIANDATE: // GETting a JULIANDATE
lReturn = fpDate->lJulianDate;
break;
//----------------------------------------------------------
case LEAPYEAR: // GETting a LEAPYEAR
lReturn = fpDate->nLeapYear;
break;
//----------------------------------------------------------
case DAYOFWEEK: // GETting a DAYOFWEEK
lReturn = fpDate->nDayOfWeek;
break;
//----------------------------------------------------------
case DAYOFYEAR: // GETting a DAYOFYEAR
lReturn = fpDate->nYearDays;
break;
//----------------------------------------------------------
case DAYSINMONTH: // GETting a DAYSINMONTH
lReturn = MoDaTbl[fpDate->nMonth-1];
if (fpDate->nMonth==2 && !fpDate->nLeapYear)
lReturn--;
break;
//----------------------------------------------------------
default: // bad uID!
lReturn = SET_ERR(BAD_ID); // return a BAD_ID
} // end of switch(uID)
GlobalUnlock(hDateObj); // Release fpDate
break; // end of uMsg case GET
//******************************************************************
case CALCULATE: // FORCE DateObj to recalc
if (!hDateObj) // If bad hDateObj handle,
{
lReturn = SET_ERR(NULL_HANDLE); // return an DATE_ERROR
break;
}
// Get a far pointer to DateObj
lReturn = (LONG) GlobalLock(hDateObj);
if (!lReturn) // If unsuccessful,
{
lReturn = SET_ERR(GENERAL_FAILURE); // return a GENERAL_FAILURE
break;
}
fpDate = (Date FAR *) lReturn; // store &DateObj in fpDate
lReturn = hDateObj; // successful so far
switch(lParam) // Route message
{
//----------------------------------------------------------
case JULIAN: // Calc based on julian date
if (fpDate->lJulianDate < 1 || fpDate->lJulianDate > MAX_JULIAN)
{ // If original julian date was bad,
// return a BAD_INPUT
lReturn = SET_ERR(BAD_INPUT);
break;
}
CalcNormalDate(fpDate); // Calculate a normal date
if (fpDate->nError) // If an error occurred,
{ // report a bug in DATE.DLL and exit!
lReturn = SET_ERR(FATAL_ERROR);
break;
}
break;
//----------------------------------------------------------
case NORMAL: // Calc based on normal date
CheckValidDate(fpDate); // Check for a valid MMDDYYYY date
if (fpDate->nError) // If an error occurred,
{ // return a BAD_INPUT
lReturn = SET_ERR(BAD_INPUT);
break;
}
CalcDayOfWeek(fpDate); // Calculate all items
if (fpDate->nError) // If an error occurred,
{ // report a bug in DATE.DLL and exit!
lReturn = SET_ERR(FATAL_ERROR);
break;
}
break;
//----------------------------------------------------------
default: // bad uID!
lReturn = SET_ERR(BAD_ID); // return a BAD_ID
} // end of switch(uID)
GlobalUnlock(hDateObj); // Release fpDate
break; // end of uMsg case CALCULATE
//******************************************************************
default: // BAD uMsg value!
lReturn = SET_ERR(BAD_MESSAGE);
} // end of switch(uMsg)
return(lReturn); // return LONG value
}
/*****************************************************************************/
/*****************************************************************************/
/* PROCEDURE-ORIENTED DATE.DLL FUNCTIONS */
/*****************************************************************************/
/*****************************************************************************/
/* CALCULATE THE DATE FROM A JULIAN VALUE */
/* This procedure will determine the date from any valid Julian number.
A valid Julian number will range from 1 to 72743.
If the Julian value is valid, this procedure will fill in the fields
DateStruct->nYear, DateStruct->nMonth, DateStruct->nDay,
DateStruct->nLeapYear, DateStruct->nYearDays, and
DateStruct->nDayOfWeek.
If the Julian value is bad, this procedure will make DateStruct->nError =
ON, and will return with no further action.
*/
VOID FAR PASCAL CalcNormalDate(Date far *DateStruct)
{
int ctr; /* loop counter */
int accum; /* accumulator */
long JulianSave = DateStruct->lJulianDate; /* julian-date save */
DateStruct->nError = OFF; /* no error yet */
/* if bad Julian value, */
if (DateStruct->lJulianDate<1 || DateStruct->lJulianDate>MAX_JULIAN)
{
DateStruct->nError = ON; /* flag as date error */
return; /* return from function */
}
/* CALCULATE DateStruct->nYear */
/* determine year number */
DateStruct->nYear = (int) ((float) DateStruct->lJulianDate / 365.25) +
BASE_YEAR;
if (!DateStruct->lJulianDate % 1461L) DateStruct->nYear--;
/* CALCULATE DateStruct->nYearDays */
/* determine day # in year */
DateStruct->nYearDays = (int)
( DateStruct->lJulianDate -
(long) ( ((float) (DateStruct->nYear - BASE_YEAR)) * 365.25 )
);
/* CALCULATE DateStruct->nLeapYear */
if (DateStruct->nYear % 4) /* determine leap year ? */
DateStruct->nLeapYear = OFF; /* if remainder, OFFT leap yr */
else /* else, */
DateStruct->nLeapYear = ON; /* is a leap year */
/* CALCULATE DateStruct->nMonth */
accum = 0; /* zero out day accumulator */
for (ctr = 0; ctr < 12; ctr++) /* month-day accumulate loop */
{
accum += MoDaTbl[ctr]; /* add # days in month */
if (accum >= DateStruct->nYearDays) /* if finished accumulating */
{
DateStruct->nMonth = ctr + 1; /* month is identified */
break; /* exit loop */
}
if (ctr==1 && !DateStruct->nLeapYear) /* if Feb of non-leap year */
accum--; /* decrement accum by 1 */
}
/* CALCULATE DateStruct->nDay */
/* determine day in month */
DateStruct->nDay = MoDaTbl[ctr] - (accum - DateStruct->nYearDays);
/* CALCULATE DateStruct->nDayOfWeek
The new DateStruct->nYear, DateStruct->nMonth, and DateStruct->nDay
is used to recalculate the julian date, using the CalcDayOfWeek()
function.
If the calculation fails, this function immediately returns. Otherwise,
the new DateStruct->lJulianDate value is compared to the previous one.
If the new value is not equal to the old one, the DateStruct->nError flag
is set, and this function returns.
*/
CalcDayOfWeek(DateStruct); /* determine day-of-week */
if (DateStruct->nError) return; /* exit if error */
if (DateStruct->lJulianDate != JulianSave) /* if DateStruct->
JulianDate changed, */
DateStruct->nError = ON; /* there is a bug */
}
/*****************************************************************************/
/* CALCULATE THE DAY OF THE WEEK */
/* This procedure calculates the value for the DateStruct->nDayOfWeek,
ranging from 0 (Sunday) to 6 (Saturday). The fields DateStruct->nYear,
DateStruct->nMonth, and DateStruct->nDay should be initialized with valid
date values before this function is called.
This procedure will exit with no action if any of these three date
fields (DateStruct->nYear, DateStruct->nMonth, and DateStruct->nDay) has a
bad value, and the DateStruct->nError field will be set to ON (bad date
data).
*/
VOID FAR PASCAL CalcDayOfWeek(Date far *DateStruct)
{
DateStruct->nDayOfWeek = 0; /* initial value of 0 */
CalcJulianDate(DateStruct); /* calculate julian value */
if (!DateStruct->nError) { /* if a valid date, */
/* determine day of week */
DateStruct->nDayOfWeek = (int) (DateStruct->lJulianDate % 7) + 1;
if (DateStruct->nDayOfWeek > 6)
DateStruct->nDayOfWeek = 0;
}
}
/*****************************************************************************/
/* CALCULATE THE JULIAN VALUE OF A DATE */
/* This procedure calculates the value for the field DateStruct->lJulianDate,
which is the consecutive day number, starting at 1, from January 1,
1901 (Julian date value of 1), and is accurate to February 28, 2100
(Julian date value of 72743).
This procedure will exit with no action if any of the three date
fields (DateStruct->nYear, DateStruct->nMonth, and DateStruct->nDay) has a
bad value, and the DateStruct->nError field will be set to ON (bad date
data).
*/
VOID FAR PASCAL CalcJulianDate(Date far *DateStruct)
{
DateStruct->lJulianDate = 0; /* no julian date yet */
CalcYearDays(DateStruct); /* calc # days into year */
if (!DateStruct->nError) /* if a valid date, */
{ /* calculate julian date */
DateStruct->lJulianDate = (
((long) (DateStruct->nYear - BASE_YEAR)) * 365
) +
(
(DateStruct->nYear - BASE_YEAR) / 4
) +
DateStruct->nYearDays;
}
}
/*****************************************************************************/
/* CALCULATE THE NUMBER OF DAYS INTO THE YEAR */
/* This procedure calculates the value for the field DateStruct->nYearDays,
which is the "day number" in the year for the date designated by
the three date fields (DateStruct->nYear, DateStruct->nMonth, and
DateStruct->nDay). The value of the DateStruct->nYearDays field may range
from 1 to 366.
This procedure will exit with no action if any of the three date
fields (DateStruct->nYear, DateStruct->nMonth, and DateStruct->nDay) has a
bad value, and the DateStruct->nError field will be set to ON (bad date
data).
*/
VOID FAR PASCAL CalcYearDays(Date far *DateStruct)
{
int ctr; /* loop counter */
DateStruct->nYearDays = 0; /* no year days yet */
IsLeapYear(DateStruct); /* determine if leap year */
if (!DateStruct->nError) { /* if a valid date, */
if (DateStruct->nMonth > 1) { /* if past January, */
/* accumulate month-days */
for (ctr=0; ctr < DateStruct->nMonth-1; ctr++)
{
DateStruct->nYearDays += MoDaTbl[ctr];
}
}
DateStruct->nYearDays += DateStruct->nDay; /* add day-in-month */
/* if past Feb, non-leap yr, */
if (DateStruct->nMonth > 2 && !DateStruct->nLeapYear)
DateStruct->nYearDays -= 1; /* take one day away */
}
}
/*****************************************************************************/
/* IS THIS A LEAP YEAR ? */
/* This procedure determines whether the date designated by the
three date fields (DateStruct->nYear, DateStruct->nMonth, and
DateStruct->nDay) falls within a leap year. If it does, then the field
DateStruct->nLeapYear will be set to ON; otherwise, it will be set to 0.
This procedure will exit with no action if any of the three date
fields (DateStruct->nYear, DateStruct->nMonth, and DateStruct->nDay) has a
bad value, and the DateStruct->nError field will be set to ON (bad date
data).
*/
VOID FAR PASCAL IsLeapYear(Date far *DateStruct)
{
CheckValidDate(DateStruct); /* is this a valid date ? */
if (!DateStruct->nError) { /* if a valid date, */
if (DateStruct->nYear % 4) /* determine if leap year */
DateStruct->nLeapYear = OFF; /* if remainder, OFFT leap yr */
else /* else, */
DateStruct->nLeapYear = ON; /* is a leap year */
}
}
/*****************************************************************************/
/* VERIFY THAT DATE FIELDS CONTAIN VALID VALUES */
/* This procedure checks to see whether the date designated by the
three date fields (DateStruct->nYear, DateStruct->nMonth, and
DateStruct->nDay) is a valid date, but does not check for leap years.
If the date field data is valid, the field DateStruct->nError will contain
an OFF upon exit. Otherwise, this field will contain an ON.
*/
VOID FAR PASCAL CheckValidDate(Date far *DateStruct)
{
DateStruct->nError = OFF; /* no date error yet */
if /* test date values */
(
DateStruct->nYear < BASE_YEAR ||
DateStruct->nYear > CEIL_YEAR ||
DateStruct->nMonth < 1 ||
DateStruct->nMonth > 12 ||
DateStruct->nDay < 1 ||
DateStruct->nDay > 31 ||
(DateStruct->nYear==CEIL_YEAR && DateStruct->nMonth>=2 &&
DateStruct->nDay>28)
)
DateStruct->nError = ON; /* signify date error */
if (!DateStruct->nError)
if (DateStruct->nDay > MoDaTbl[DateStruct->nMonth-1])
DateStruct->nError = ON;
}
/*****************************************************************************/
/* ONE-TIME GLOBAL DLL-INIT FUNCTION */
int FAR PASCAL LibMain (HANDLE hInstance,
WORD wDataSeg,
WORD cbHeapSize,
LPSTR lpszCmdLine)
{
/* Perform DLL initialization
.
.
.
*/
if (cbHeapSize != 0) /* If DLL data seg is MOVEABLE */
UnlockData(0); /* unlock the data seg */
return(1); /* Initialization successful,
otherwise, return(0); */
}
/*****************************************************************************/
/* ONE-TIME GLOBAL DLL-SHUTDOWN FUNCTION */
WORD FAR PASCAL WEP(int nParameter)
{
if (nParameter == WEP_SYSTEM_EXIT)
{
/* System shutdown in progress. Respond accordingly. */
return(1);
}
else
{
if (nParameter == WEP_FREE_DLL)
{
/* DLL-use count is zero. Every application that had loaded the
DLL has freed it. */
return(1);
}
else
{
/* Undefined value. Ignore. */
return(1);
}
}
}