/* * 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 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); }