windows-nt/Source/XPSP1/NT/shell/osshell/accesory/calendar/cal2.c
2020-09-26 16:20:57 +08:00

499 lines
12 KiB
C

/*
* Windows Calendar
* Copyright (c) 1985 by Microsoft Corporation, all rights reserved.
* Written by Mark L. Chamberlin, consultant to Microsoft.
*
****** cal2.c
*
*/
#include "cal.h"
#include <time.h>
HDC vhDCTemp; /* Save code by not having to pass the HDC on each
call to DrawArrow and DrawArrowBorder. */
/**** CalPaint ****/
VOID APIENTRY CalPaint (
HWND hwnd,
HDC hDC)
{
register D3 *pd3;
if (hwnd == vhwnd1)
PatBlt (hDC, 0, vycoNotesBox, vcxWnd2A , vcyBorder, PATCOPY);
if (hwnd == vhwnd2A)
{
DispTime (hDC);
/* Assume we are in month mode so we will display the
current date.
*/
pd3 = &vd3Cur;
/* Set up global for DrawArrow and DrawArrowBorder. */
vhDCTemp = hDC;
#ifdef BUG_8560
/* We want the arrows to have the border color. */
SetTextColor (hDC, GetSysColor (COLOR_WINDOWFRAME));
/* Draw left arrow. */
DrawArrow (vhbmLeftArrow, vxcoLeftArrowFirst);
/* Draw border at left end of left arrow. */
DrawArrowBorder (vxcoLeftArrowFirst);
/* Draw border between left and right arrows. */
DrawArrowBorder (vxcoLeftArrowMax);
/* Draw right arrow. */
DrawArrow (vhbmRightArrow, vxcoRightArrowFirst);
/* Draw border to right of right arrow. */
DrawArrowBorder (vxcoRightArrowMax - vcxBorder);
#endif
/* Set colors back to defaults. */
SetDefaultColors (hDC);
/* Want to display the page date, not the current date. */
pd3 = &vd3Sel;
DispDate (hDC, pd3);
return;
}
if (hwnd == vhwnd2B)
{
PatBlt (hDC, 0, 0, vcxWnd2B+ vcxVScrollBar, vcyBorder, PATCOPY);
if (vfDayMode)
DayPaint (hDC);
else
{
PaintMonthGrid (hDC);
PaintMonth (hDC);
}
}
}
#ifdef BUG_8560
******************* The following are no longer required ********************
/**** DrawArrow ****/
VOID APIENTRY DrawArrow (
HBITMAP hbm,
INT xco)
{
SelectObject (vhDCMemory, hbm);
BitBlt (vhDCTemp, xco, vcyBorder, vcxHScrollBar, vcyHScrollBar,
vhDCMemory, 0, 0, SRCCOPY);
}
/**** DrawArrowBorder ****/
VOID APIENTRY DrawArrowBorder (INT xco)
{
PatBlt (vhDCTemp, xco, 0, vcxBorder, vcyWnd2A, PATCOPY);
}
************************ No longer required ********************************
#endif
/**** DispTime - Display the current time. ****/
VOID APIENTRY FAR DispTime (HDC hDC)
{
CHAR sz [CCHTIMESZ + 2]; /* added 2 for spaces. 19 Sep 89 Clark Cyr */
/* Convert the time into an ASCII string. */
GetTimeSz (vftCur.tm, sz);
lstrcat((LPSTR)sz, (LPSTR)" ");
/* Output the time. */
TextOut (hDC, vcxFont, vcyExtLead, (LPSTR)sz, lstrlen((LPSTR)sz));
}
/**** GetTimeSz - convert the time into a zero terminated ASCII string. ****/
INT APIENTRY GetTimeSz (
TM tm, /* The time to convert. */
CHAR *sz) /* pointer to the buffer to receive the string -
the caller should allocate CCHTIMESZ chars. */
{
#ifndef NOCOMMON
DOSTIME dt;
dt.minutes = tm % 60;
dt.hour = tm / 60;
return(GetTimeString(&dt, sz, GTS_LEADINGZEROS | GTS_LEADINGSPACE));
#else
WORD wHour;
/* Put in the boiler plate. */
lstrcpy (sz + 2, ": ");
wHour = tm / 60;
if (!vfHour24)
{
lstrcpy (sz + 5, "am");
if (wHour > 11)
{
/* Change to pm, and adjust down the hour. */
*(sz + 5) = 'p';
wHour -= 12;
}
/* Convert the 0 hour (midnight) to 12 (am is already selected). */
if (wHour == 0)
wHour = 12;
}
/* Convert the hours to ASCII. */
ByteTo2Digs ((BYTE)wHour, sz);
/* Change leading 0 to space if in 12 hour mode. */
if (!vfHour24 && *sz == '0')
*sz = ' ';
/* Convert the minutes to ASCII. */
ByteTo2Digs ((BYTE)(tm % 60), sz + 3);
#endif
}
/**** ByteTo2Digs - convert byte to 2 decimal ASCII digits. ****/
VOID APIENTRY ByteTo2Digs (
BYTE b, /* The byte to convert from binary to ASCII. */
CHAR *pch) /* Pointer to output buffer (must be at least 2
chars long.
*/
{
*pch++ = b / 10 + '0';
*pch = b % 10 + '0';
}
/**** DispDate - Display date in Wnd2A. */
VOID APIENTRY FAR DispDate (
HDC hDC,
D3 *pd3)
{
RECT rc;
HBRUSH hbr;
CHAR sz [CCHDATEDISP];
/* Convert the current date into an ASCII string. */
GetDateDisp (pd3, sz);
/* Erase the background */
GetClientRect(vhwnd2A, (LPRECT)&rc);
rc.left = vxcoDate;
if (hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW)))
{
FillRect(hDC, (LPRECT)&rc, hbr);
DeleteObject(hbr);
}
else
FillRect(hDC, (LPRECT)&rc, GetStockObject(WHITE_BRUSH));
SetBkMode(hDC,TRANSPARENT);
/* Output the date. Use transparent mode so we don't erase the background
* color.
*/
TextOut (hDC, vxcoDate+2, vcyExtLead, (LPSTR)sz, lstrlen ((LPSTR)sz));
SetBkMode(hDC,OPAQUE);
}
/**** GetDateDisp - convert the date to an ASCII string of the form:
weekday, month, day, year. For example, "Sunday, March 30, 1985".
****/
VOID APIENTRY GetDateDisp (
D3 *pd3,
CHAR *sz)
{
DOSDATE dd;
dd.dayofweek = 0xff; /* so it'll calculate day of week */
dd.year = pd3->wYear + 1980;
dd.month = pd3->wMonth + 1;
dd.day = pd3->wDay + 1;
GetLongDateString(&dd, sz, GDS_LONG | GDS_DAYOFWEEK);
}
/**** FillBuf - fill buffer with specified count of specified byte.
Return a pointer to the buffer position following the filled bytes.
****/
BYTE * APIENTRY FillBuf (
BYTE *pb,
INT cb,
BYTE b)
{
while (cb--)
*pb++ = b;
return (pb);
}
#ifndef NOCOMMON
/**** WordToASCII - convert word to ASCII digits - return a pointer
to the first character following the generated digits.
****/
CHAR * APIENTRY WordToASCII (
WORD w, /* Word to convert. */
CHAR *pch, /* Pointer to output buffer. */
BOOL fLeadZero) /* TRUE for leading zeroes,
FALSE to suppress leading zeroes.
*/
{
WORD wPlace;
WORD wDig;
for (wPlace = 10000; wPlace > 0; wPlace /= 10)
{
wDig = w / wPlace;
w %= wPlace;
if (wDig != 0 || fLeadZero || wPlace == 1)
{
*pch++ = wDig + '0';
/* After the first digit gets put down, we're no longer
going to see leading zeros. Prevent additional zeroes
from being suppressed by setting fLeadZero to TRUE.
*/
fLeadZero = TRUE;
}
}
return (pch);
}
#endif
/**** GetDashDateSel - convert the selected date to an ASCII string
of the form: mm-dd-yyyy. For example, "4-21-1985".
****/
VOID APIENTRY GetDashDateSel (CHAR *sz)
{
#ifndef NOCOMMON
DOSDATE dd;
dd.month = vd3Sel.wMonth + 1;
dd.day = vd3Sel.wDay + 1;
dd.year = vd3Sel.wYear + 1980;
GetDateString(&dd, sz, GDS_SHORT);
#else
sz = WordToASCII ((WORD)(vd3Sel.wMonth + 1), sz, FALSE);
*sz++ = '-';
sz = WordToASCII ((WORD)(vd3Sel.wDay + 1), sz, FALSE);
*sz++ = '-';
*(WordToASCII ((WORD)(vd3Sel.wYear + 1980), sz, FALSE)) = '\0';
#endif
}
/**** FGetTmFromTimeSz
The format for inputting the time is: [h]h[:mm][a|am|p|pm]
In other words:
- at least one digit must be used to specify the hour (even if it's 0)
- the minutes are optional but if specified must be two digits preceded
by a colon
- the am/pm designation is optional and can be abbreviated by just a or p
- The am/pm designation can use any combination of upper and lower case
- If hours > 12 then OK if pm specified, but error if am specified.
- if hours == 0 then OK if am specified, but error if pm specified.
- If 1 <= hour <= 12 then default to am if no am/pm specification.
****/
INT APIENTRY FGetTmFromTimeSz (
CHAR *sz, /* INPUT - ASCII time string. */
TM *ptm) /* OUTPUT - converted time - unchanged if we
return FALSE.
*/
{
DOSTIME dt;
INT iErr;
if ((iErr = ParseTimeString(&dt, sz)) == 0)
{
*ptm = dt.hour * 60 + dt.minutes;
return(TRUE);
}
return(iErr);
}
/**** SkipSpace - skip spaces in a sz. ****/
VOID APIENTRY SkipSpace (CHAR **psz)
{
while (**psz == ' ')
(*psz)++;
}
#ifdef NOCOMMON
/**** FGetWord - convert ASCII digits into a word
in the range 0 to 65535 inclusive.
****/
BOOL APIENTRY FGetWord (
CHAR **ppch,
WORD *pw)
{
LONG l;
CHAR ch;
l = 0;
/* Must see at least one digit. */
if (!isdigit (**ppch))
return (FALSE);
while (isdigit (ch = **ppch))
{
l = l * 10 + (ch - '0');
(*ppch)++;
if (l > 65535)
return (FALSE);
}
*pw = (WORD)l;
return (TRUE);
}
#endif
/**** ChUpperCase - convert from lower to upper case. ****/
#ifdef DISABLE
CHAR APIENTRY ChUpperCase (CHAR ch)
{
return (ch >= 'a' && ch <= 'z' ? ch - 'a' + 'A' : ch);
}
#endif
/**** FD3FromDateSz
Format supported: mm-dd-yyyy
(Slashes (/) may be used instead of dashes.)
If the year is in the range 0 through 99, it is assumed that the
low order digits of 19yy have been specified.
****/
BOOL APIENTRY FD3FromDateSz (
CHAR *sz, /* INPUT - ASCII date string. */
D3 *pd3) /* OUTPUT - converted date. Unchanged if
we return FALSE.
*/
{
DOSDATE dd;
INT iErr;
if ((iErr = ParseDateString(&dd, sz)) == 0)
{
pd3->wMonth = dd.month - 1;
pd3->wDay = dd.day - 1;
pd3->wYear = dd.year - 1980;
}
return(iErr);
}
/**** GetD3FromDt ****/
VOID APIENTRY GetD3FromDt (
DT dt,
D3 *pd3)
{
register INT cDaysYear;
register INT i;
INT cDaysMonth;
/* See how many 4 year periods are in it (366 for leap year, 3 * 365
for the next 3 years.
*/
pd3 -> wYear = 4 * (dt / 1461);
dt = dt % 1461;
/* Account for the individual years. Again, the first year is
a leap year, the next two are normal (only two since we already
divided by groups of 4 years).
*/
cDaysYear = 366;
while ((INT)dt >= cDaysYear)
{
dt -= (DT)cDaysYear;
pd3 -> wYear++;
cDaysYear = 365;
}
/* Subtract out days of each month. Note that we add one
to the count of days in the month for February in a leap year.
*/
for (i = MONTHJAN; (INT)dt >= (cDaysMonth = vrgcDaysMonth [i] +
(cDaysYear == 366 && i == MONTHFEB ? 1 : 0)); i++)
dt -= (DT)cDaysMonth;
pd3 -> wMonth = (WORD)i;
/* Whatever's left is the offset into the month. */
pd3 -> wDay = (WORD)dt;
}
/**** Set text of an edit ctl and then place selection at end. */
VOID APIENTRY SetEcText(
HWND hwnd,
CHAR * sz)
{
WPARAM iSelFirst;
WPARAM iSelLast;
SetWindowText(hwnd, sz);
iSelFirst = iSelLast = -1;
SendMessage(hwnd, EM_SETSEL, iSelFirst, iSelLast);
}