home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: InfoMgt / InfoMgt.zip / PMCAL.ZIP / PMCAL.C < prev    next >
Text File  |  1991-04-12  |  17KB  |  540 lines

  1. /*
  2.  * OS/2 PM Perpetual Calendar utility - SOURCE CODE
  3.  *
  4.  * 04/11/91 1.00 - Robert Mahoney initial creation.
  5.  *
  6.  */
  7.  
  8. #define INCL_DOSDATETIME
  9. #define INCL_WINWINDOWMGR
  10. #define INCL_WINDIALOGS
  11. #define INCL_WINBUTTONS
  12. #define INCL_WINENTRYFIELDS
  13. #define INCL_WINLISTBOXES
  14. #define INCL_WINMENUS
  15. #define INCL_WINFRAMEMGR
  16. #define INCL_WINSYS
  17. #define INCL_WINPOINTERS
  18. #define NUL '\0'
  19.  
  20. #include <os2.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <process.h>
  24. #include <string.h>
  25.  
  26. #include "pmcal.h"
  27.  
  28.  
  29. HAB         hab;                        /* handle to anchor block   */
  30. int iSavedMonth;        /* contains value for saved month    */
  31. int iSavedYear;         /* contains value for saved year     */
  32. /* */
  33.  
  34. /*
  35.  * main( VOID ) : VOID;
  36.  *
  37.  * This function is the system entry point for the application
  38.  * and is responsible for defining the appropriate window
  39.  * classes and for processing all the messages.  Note how
  40.  * the dialog box manager is responsible for the operation of
  41.  * the file chksum window.
  42.  *
  43.  */
  44.  
  45. void cdecl main( VOID )
  46. {
  47.   HMQ         hmq;                        /* handle to message queue  */
  48.   HWND        hwnd;                       /* handle to main window    */
  49.   HPOINTER    hptr;                       /* handle to window's icon  */
  50.  
  51.   /* initialize thread & create message queue */
  52.   hab = WinInitialize( 0 );
  53.   hmq = WinCreateMsgQueue( hab, DEFAULT_QUEUE_SIZE );
  54.  
  55.   /* load the main dialog */
  56.   hwnd = WinLoadDlg(
  57.     HWND_DESKTOP,
  58.     HWND_DESKTOP,
  59.     PmcalDlgProc,
  60.     NUL,
  61.     ID_PMCAL,
  62.     NUL
  63.   );
  64.  
  65.   /* set an icon for the dialog */
  66.   hptr = WinLoadPointer( HWND_DESKTOP, NUL, ID_PMCAL );
  67.   WinSendMsg( hwnd, WM_SETICON, (MPARAM)hptr, 0L );
  68.  
  69.   /* process the dialog */
  70.   WinProcessDlg( hwnd );
  71.  
  72.   /* destroy the dialog and its icon */
  73.   WinDestroyWindow( hwnd );
  74.   WinDestroyPointer( hptr );
  75.  
  76.   /* destroy message queue & terminate thread */
  77.   WinDestroyMsgQueue( hmq );
  78.   WinTerminate( hab );
  79. }
  80.  
  81. /* */
  82.  
  83. /*
  84.  * PmcalDlgProc( hwnd, usMsg, mp1, mp2 ) : MRESULT;
  85.  *
  86.  *    hwnd          handle to main dialog window
  87.  *    usMsg         message number
  88.  *    mp1           message parameter 1
  89.  *    mp2           message parameter 2
  90.  *
  91.  * This function is responsible for processing all the messages
  92.  * which relate to the calendar dialog box.  This mainly
  93.  * involves the definition and retrieval of the various
  94.  * events generated by the user.
  95.  *
  96.  */
  97.  
  98. MRESULT EXPENTRY PmcalDlgProc(
  99.   HWND        hwnd,
  100.   USHORT      usMsg,
  101.   MPARAM      mp1,
  102.   MPARAM      mp2 )
  103. {
  104. /* variable definition  starts */
  105.  
  106.   MRESULT     mresRtnVal;                 /* function return value    */
  107.   BOOL        fPassToDef;                 /* pass to def window proc? */
  108.   static HWND hwndDayText;     /* hwnd for the days static text */
  109.   static HWND hwndNumText;     /* hwnd for the numbers static text */
  110.   static char days[31] = "Sun Mon Tue Wed Thu Fri Sat";
  111.   static char szMonthNumber[134]; /* string for the numbers in the mon*/
  112.   static char szMonth[16];     /* holds the month for the calendar */
  113.   char szInputMon[3];          /* string for month from entryfield */
  114.   char szInputYear[5];         /* string for year from entryfield */
  115.   DATETIME date_time;          /* date_time of struct DateTime */
  116.   int iWeekDay;                /* contains value for weekday  */
  117.   int iMonth;                  /* contains value for  month    */
  118.   int iYear;                   /* contains value for  year     */
  119.   static BOOL bMonth ;         /* if true than month is bMonth*/
  120.  
  121. /* variable definition  ends   */
  122.  
  123.   mresRtnVal = FALSE;
  124.   fPassToDef = FALSE;
  125.  
  126.   switch ( usMsg ) {
  127.  
  128.     case WM_INITDLG:
  129.       {
  130.         HWND        hwndSysMenu;          /* system menu handle       */
  131.         USHORT      idSysMenu;            /* system menu id           */
  132.         MENUITEM    miSysMenu;            /* system menu item info    */
  133.         MENUITEM    miAbout;              /* About menu item info     */
  134.  
  135.         /* add About item to system menu */
  136.         if ( hwndSysMenu = WinWindowFromID( hwnd, FID_SYSMENU ) ) {
  137.  
  138.           /* get handle of system submenu */
  139.           idSysMenu = SHORT1FROMMR( WinSendMsg( hwndSysMenu, MM_ITEMIDFROMPOSITION, MPFROMSHORT( 0 ), 0L ) );
  140.           WinSendMsg( hwndSysMenu, MM_QUERYITEM, MPFROM2SHORT( idSysMenu, FALSE ), MPFROMP( &miSysMenu ) );
  141.           hwndSysMenu = miSysMenu.hwndSubMenu;
  142.  
  143.           /* add menu separator */
  144.           miAbout.iPosition = MIT_END;
  145.           miAbout.afStyle = MIS_SEPARATOR;
  146.           miAbout.afAttribute = 0;
  147.           miAbout.id = 0;
  148.           miAbout.hwndSubMenu = NUL;
  149.           miAbout.hItem = NUL;
  150.           WinSendMsg( hwndSysMenu, MM_INSERTITEM, MPFROMP( &miAbout ), NUL );
  151.  
  152.           /* add About item */
  153.           miAbout.afStyle = MIS_TEXT;
  154.           miAbout.id = IDM_ABOUT;
  155.           WinSendMsg( hwndSysMenu, MM_INSERTITEM, MPFROMP( &miAbout ), MPFROMP( "A~bout..." ) );
  156.  
  157.           }
  158.           /* change the static text font to monospace */
  159.           hwndDayText=WinWindowFromID(hwnd,IDT_CALDAY);
  160.           WinSetPresParam(hwndDayText,
  161.                              PP_FONTNAMESIZE,
  162.                              24L,
  163.                              (PVOID) "10.System Monospaced");
  164.  
  165.           hwndNumText=WinWindowFromID(hwnd,IDT_CALNUM);
  166.           WinSetPresParam(hwndNumText,
  167.                              PP_FONTNAMESIZE,
  168.                              24L,
  169.                              (PVOID) "10.System Monospaced");
  170.  
  171.           /* get todays month and year */
  172.           DosGetDateTime((PDATETIME)&date_time);
  173.           iMonth = (int) date_time.month;
  174.           iYear = (int) date_time.year ;
  175.  
  176.           /* save to month and year */
  177.           iSavedMonth = iMonth;
  178.           iSavedYear = iYear;
  179.  
  180.           /* get what day of the week the first of the month is */
  181.           /* Sun = 0....Sat = 6 */
  182.           iWeekDay = CalculateDayOfWeek(iMonth,iYear);
  183.  
  184.           /* Fill the month numbers static text with the digits of */
  185.           /* the month                           */
  186.           FillDateNumbers( iWeekDay,iMonth,iYear,szMonthNumber);
  187.  
  188.           /* Show month and year */
  189.           FillMonthString( iMonth,iYear,szMonth);
  190.  
  191.           /* set the text */
  192.           WinSetDlgItemText (hwnd, IDT_CALNUM, szMonthNumber);
  193.           WinSetDlgItemText (hwnd, IDT_MONTH, szMonth);
  194.  
  195.           /* set the entryfield text limit for month and year */
  196.           WinSendDlgItemMsg(hwnd,IDE_MONTH,
  197.                             EM_SETTEXTLIMIT,
  198.                             MPFROM2SHORT(2,0),
  199.                             NUL);
  200.           WinSendDlgItemMsg(hwnd,IDE_YEAR,
  201.                             EM_SETTEXTLIMIT,
  202.                             MPFROM2SHORT(4,0),
  203.                             NUL);
  204.  
  205.           /* check the month selection and set the bool to true */
  206.           WinSendDlgItemMsg(hwnd,IDB_MONTH,
  207.                             BM_SETCHECK,
  208.                             MPFROM2SHORT(TRUE,0),
  209.                             NUL);
  210.           bMonth = TRUE;
  211.          }
  212.          break;
  213.  
  214.     case WM_CONTROL:
  215.       switch ( SHORT1FROMMP (mp1) ) {
  216.                 /* checked radio button so set the bool */
  217.  
  218.                 case IDB_MONTH:
  219.                  bMonth = TRUE;
  220.                  break;
  221.  
  222.                 case IDB_YEAR:
  223.                  bMonth = FALSE;
  224.                  break;
  225.  
  226.                 default:
  227.                  fPassToDef = TRUE;
  228.                  break;
  229.       }
  230.  
  231.     case WM_COMMAND:
  232.       switch ( COMMANDMSG( &usMsg )->cmd ) {
  233.          /* a button was pressed */
  234.  
  235.          case IDB_NEXT:
  236.            if( bMonth )
  237.                /* if month is checked show the next month calendar */
  238.                {
  239.                   iSavedMonth += 1;
  240.                   if (iSavedMonth > 12)
  241.                     {
  242.                        iSavedYear +=1;
  243.                        iSavedMonth = 1;
  244.                     }
  245.                     iMonth = iSavedMonth;
  246.                     iYear = iSavedYear;
  247.                }
  248.                else
  249.                /* else show the same month next year */
  250.                {
  251.                   iSavedYear += 1;
  252.                   iMonth = iSavedMonth;
  253.                   iYear = iSavedYear;
  254.               }
  255.                   iWeekDay = CalculateDayOfWeek(iMonth,iYear);
  256.  
  257.                   FillDateNumbers(iWeekDay,
  258.                                   iMonth,
  259.                                   iYear,
  260.                                   szMonthNumber);
  261.  
  262.                   FillMonthString(iMonth,iYear,szMonth);
  263.  
  264.                   WinSetDlgItemText (hwnd, IDT_CALNUM, szMonthNumber);
  265.                   WinSetDlgItemText (hwnd, IDT_MONTH, szMonth);
  266.                  break;
  267.  
  268.          case IDB_PREV:
  269.                    if( bMonth )
  270.                   /* if month is checked show the prev month calendar */
  271.                    {
  272.                      iSavedMonth -= 1;
  273.                      if (iSavedMonth < 1)
  274.                        {
  275.                           iSavedYear -=1;
  276.                           iSavedMonth = 12;
  277.                        }
  278.                        iMonth = iSavedMonth;
  279.                        iYear = iSavedYear;
  280.                    }
  281.                    else
  282.                    /* else show the same month prev year */
  283.                    {
  284.                      iSavedYear -= 1;
  285.                      iMonth = iSavedMonth;
  286.                      iYear = iSavedYear;
  287.                    }
  288.                   iWeekDay = CalculateDayOfWeek(iMonth,iYear);
  289.  
  290.                   FillDateNumbers(iWeekDay,
  291.                                   iMonth,
  292.                                   iYear,
  293.                                   szMonthNumber);
  294.                   FillMonthString(iMonth,iYear,szMonth);
  295.  
  296.                   WinSetDlgItemText (hwnd, IDT_CALNUM, szMonthNumber);
  297.                   WinSetDlgItemText (hwnd, IDT_MONTH, szMonth);
  298.                    break;
  299.  
  300.          case IDB_ENTER:
  301.              /* Get data from the entryfields */
  302.                     WinQueryDlgItemText(
  303.                                   hwnd,
  304.                                   IDE_MONTH,
  305.                                   sizeof(szInputMon),
  306.                                   szInputMon );
  307.                     WinQueryDlgItemText(
  308.                                   hwnd,
  309.                                   IDE_YEAR,
  310.                                   sizeof(szInputYear),
  311.                                   szInputYear );
  312.  
  313.                  /* validate the data */
  314.                   iMonth = atoi(szInputMon);
  315.                   iYear = atoi(szInputYear);
  316.                   if (iMonth < 1 || iMonth > 12)
  317.                          WinMessageBox (HWND_DESKTOP,hwnd,
  318.                            "Enter a Month between 1 and 12",
  319.                            "Incorrect Month",
  320.                            0,MB_OK | MB_ERROR);
  321.                   else
  322.                      if (iYear < 1583)
  323.                             WinMessageBox (HWND_DESKTOP,hwnd,
  324.                               "Enter a Year greater than 1582",
  325.                               "Incorrect Year",
  326.                               0,MB_OK | MB_ERROR);
  327.                      else
  328.                      {
  329.                      /* show the calendar for the entered values */
  330.                         iSavedMonth = iMonth;
  331.                         iSavedYear = iYear;
  332.  
  333.                         iWeekDay = CalculateDayOfWeek(iMonth,iYear);
  334.  
  335.                         FillDateNumbers(iWeekDay,
  336.                                         iMonth,
  337.                                         iYear,
  338.                                         szMonthNumber);
  339.                         FillMonthString(iMonth,iYear,szMonth);
  340.  
  341.                         WinSetDlgItemText (hwnd, IDT_CALNUM, szMonthNumber);
  342.                         WinSetDlgItemText (hwnd, IDT_MONTH, szMonth);
  343.                      }
  344.                   break;
  345.  
  346.  
  347.          case IDM_ABOUT:
  348.           WinDlgBox( HWND_DESKTOP, hwnd, AboutDlgProc, NUL, IDD_ABOUTDLG, NUL );
  349.           break;
  350.  
  351.  
  352.          default:
  353.           fPassToDef = TRUE;
  354.           break;
  355.  
  356.       }
  357.       break;
  358.  
  359.  
  360.     case WM_MINMAXFRAME:
  361.       {
  362.         PSWP        pswp;                     /* pos change structure */
  363.  
  364.         /* hide number static text when minimized  */
  365.         /* so it doesn't overwrite icon */
  366.         pswp = PVOIDFROMMP( mp1 );
  367.         WinShowWindow(
  368.           WinWindowFromID( hwnd, IDT_CALNUM ),
  369.           !(pswp->fs & SWP_MINIMIZE)
  370.         );
  371.       }
  372.       break;
  373.  
  374.  
  375.     default:
  376.       fPassToDef = TRUE;
  377.       break;
  378.  
  379.   }
  380.  
  381.   /* pass to def dialog proc if needed */
  382.   if ( fPassToDef )
  383.     mresRtnVal = WinDefDlgProc( hwnd, usMsg, mp1, mp2 );
  384.  
  385.   return mresRtnVal;
  386. }
  387.  
  388. /* */
  389.  
  390. /*
  391.  * AboutDlgProc( hwndDlg, usMsg, mp1, mp2 ) : MRESULT;
  392.  *
  393.  *    hwndDlg        handle to dialog box
  394.  *    usMsg          message number
  395.  *    mp1            message parameter 1
  396.  *    mp2            message parameter 2
  397.  *
  398.  * This is the dialog procedure for the About dialog box.
  399.  *
  400.  */
  401.  
  402. MRESULT EXPENTRY AboutDlgProc( HWND hwndDlg, USHORT usMsg, MPARAM mp1, MPARAM mp2 )
  403. {
  404.   MRESULT       mresRtnVal;                 /* function return value  */
  405.   BOOL          fPassToDef;                 /* pass to def dlg proc?  */
  406.  
  407.   mresRtnVal = FALSE;
  408.   fPassToDef = FALSE;
  409.  
  410.   switch ( usMsg ) {
  411.  
  412.  
  413.     case WM_COMMAND:
  414.       switch ( COMMANDMSG( &usMsg )->cmd ) {
  415.         case IDB_OK:
  416.           WinDismissDlg( hwndDlg, TRUE );
  417.           break;
  418.         default:
  419.           fPassToDef = TRUE;
  420.           break;
  421.       }
  422.       break;
  423.  
  424.     default:
  425.       fPassToDef = TRUE;
  426.       break;
  427.  
  428.   }
  429.  
  430.   if ( fPassToDef )
  431.     mresRtnVal = WinDefDlgProc( hwndDlg, usMsg, mp1, mp2 );
  432.  
  433.   return mresRtnVal;
  434. }
  435.  
  436. /* */
  437.  
  438. /* Calculate the weekday number of the first day of the month */
  439. /* using Zeller's Congruence                                  */
  440.  
  441. int CalculateDayOfWeek(int iMonth, int iYear)
  442. {
  443.    int iDay = 1;  /* day of the month will be 1 */
  444.    int iWeekDay ;  /* weekday of the first of the month
  445.                       0=Sun..6=Sat                      */
  446.  
  447.    if (iMonth < 3 )
  448.        {
  449.          iMonth = iMonth + 12;
  450.          iYear = iYear - 1;
  451.        }
  452.    iWeekDay = (iDay+1 + (iMonth*2) +
  453.                ((int) (iMonth + 1) * 3 / 5) +
  454.                iYear +
  455.                (int) (iYear / 4) -
  456.                (int) (iYear / 100) +
  457.                (int) (iYear / 400) ) % 7;
  458.  
  459.  return(iWeekDay);
  460. }
  461.  
  462. /* */
  463. /* fill the numbers static text with the numbers of the month */
  464. void FillDateNumbers(int DayOfWeek,int iMonth,int iYear,PSZ szMonthNumber)
  465. {
  466.  int     i;
  467.  /* all months have 28 days */
  468.  static char *szNumbers[28] ={
  469.    " 1  ", " 2  "," 3  ", " 4  "," 5  "," 6  ", " 7  ",
  470.    " 8  ", " 9  ", " 10 ", " 11 "," 12 "," 13 "," 14 ",
  471.    " 15 "," 16 "," 17 ", " 18 "," 19 "," 20 "," 21 ",
  472.    " 22 "," 23 "," 24 "," 25 "," 26 "," 27 "," 28 "};
  473.  
  474.  
  475.             szMonthNumber[0] = '\0';
  476.  
  477.             /* format dlgbox string for display  */
  478.             /* put a blank instead of a number */
  479.             for (i=0;i<DayOfWeek;i++)
  480.                strcat (szMonthNumber,"    ");
  481.  
  482.             /* concatenate the numbers to the spaces*/
  483.             for (i=0;i<28;i++)
  484.                strcat (szMonthNumber,szNumbers[i]);
  485.  
  486.             /*  add the extra days according to month */
  487.               switch ( iMonth ) {
  488.  
  489.                 case 1:
  490.                 case 3:
  491.                 case 5:
  492.                 case 7:
  493.                 case 8:
  494.                 case 10:
  495.                 case 12:
  496.                    strcat (szMonthNumber," 29 ");
  497.                    strcat (szMonthNumber," 30 ");
  498.                    strcat (szMonthNumber," 31 ");
  499.                    break;
  500.  
  501.                 case 2:
  502.                 /* do Feburary processing */
  503.                     if (!(iYear % 4))
  504.                     /* evenly divisible by 4 - maybe a leap year */
  505.                     {
  506.                         if (!(iYear % 100))
  507.                         /* leap yr cannot be evenly divisible by 100*/
  508.                         {
  509.                           if (!(iYear % 400))
  510.                           /* leap yr can be evenly divisible by 400*/
  511.                           {
  512.                             strcat (szMonthNumber," 29 ");
  513.                           }
  514.                         }
  515.                         else
  516.                         /* it's not evenly divisible by 100*/
  517.                            strcat (szMonthNumber," 29 ");
  518.                     }
  519.                     break;
  520.  
  521.                 default:
  522.                    strcat (szMonthNumber," 29 ");
  523.                    strcat (szMonthNumber," 30 ");
  524.                    break;
  525.                 }
  526. }
  527. /* */
  528. /* Give the heading to the calendar - Month Year */
  529. void FillMonthString(int iMonth,int iYear,PSZ szMonthString)
  530. {
  531.  static char *szMonths[12] ={
  532.    "January","February","March","April","May","June",
  533.    "July","August","September","October","November","December"};
  534.  char szHoldStr[5];
  535.         strcpy(szMonthString,szMonths[iMonth-1]);
  536.         itoa(iYear,szHoldStr,10);
  537.         strcat(szMonthString," ");
  538.         strcat(szMonthString,szHoldStr);
  539.  }
  540.