home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: InfoMgt / InfoMgt.zip / CLOCK2.ZIP / CLOCK2.C < prev    next >
Text File  |  1991-12-14  |  13KB  |  372 lines

  1. /*
  2.  *  -------------------------------------
  3.  *     CLOCK.C -- Analog Clock w/ Alarm
  4.  *  -------------------------------------
  5.  */
  6.  
  7. #define INCL_WIN
  8. #define INCL_GPI
  9. #include <os2.h>
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include "clock2.h"
  13.  
  14. #define ID_TIMER 1
  15.  
  16. char     alarm_status = 0x00;
  17. INITDATA init;
  18. HBITMAP  hbm;
  19. HAB      hab ;
  20. HWND     hwndFrame, hwndClient ;
  21.  
  22. MRESULT EXPENTRY AlarmSet(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
  23. MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
  24.  
  25. int cdecl main (void)
  26.      {
  27.      static CHAR  szClientClass[] = "Clock" ;
  28.      static ULONG flFrameFlags = FCF_TITLEBAR      | FCF_SYSMENU | FCF_ACCELTABLE |
  29.                                  FCF_SIZEBORDER    | FCF_MINMAX  |
  30.                                  FCF_SHELLPOSITION | FCF_TASKLIST | FCF_MENU ;
  31.      HMQ          hmq ;
  32.      QMSG         qmsg ;
  33.      SHORT        i = sizeof(init);
  34.  
  35.      hab = WinInitialize (0) ;
  36.      hmq = WinCreateMsgQueue (hab, 0) ;
  37.  
  38.      WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;
  39.  
  40.      if ( ! WinQueryProfileData(hab, szClientClass, "Clock Data", &init, &i))
  41.        {
  42.        init.background = CLR_WHITE;
  43.        init.text_color = CLR_BLACK;
  44.        init.wp.x       = 50;
  45.        init.wp.y       = 100;
  46.        init.wp.cx      = 365;
  47.        init.wp.cy      = 300;
  48.        }
  49.      
  50.      hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_DISABLED, 
  51.                                      &flFrameFlags, szClientClass, NULL,
  52.                      0L, NULL, ID_CLOCK, &hwndClient) ;
  53.  
  54.      WinSetWindowPos(hwndFrame, HWND_TOP, init.wp.x,
  55.                      init.wp.y, init.wp.cx, init.wp.cy, 
  56.                      SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_SHOW);
  57.  
  58.      WinEnableWindow(hwndFrame, TRUE);
  59.      
  60.      if (WinStartTimer (hab, hwndClient, ID_TIMER, 1000))
  61.        {
  62.        while (WinGetMsg (hab, &qmsg, NULL, 0, 0)) 
  63.          WinDispatchMsg (hab, &qmsg) ;
  64.  
  65.        WinStopTimer (hab, hwndClient, ID_TIMER) ;
  66.        }
  67.      else
  68.        WinMessageBox (HWND_DESKTOP, hwndClient,
  69.                       "Too many clocks or timers",
  70.                       szClientClass, 0, MB_OK | MB_ICONEXCLAMATION) ;
  71.  
  72.      WinQueryWindowPos(hwndFrame, &init.wp);
  73.      WinWriteProfileData(hab, szClientClass, "Clock Data", &init, sizeof(init));
  74.      WinDestroyWindow (hwndFrame) ;
  75.      WinDestroyMsgQueue (hmq) ;
  76.      WinTerminate (hab) ;
  77.      return 0 ;
  78.      }
  79.  
  80. VOID RotatePoint (POINTL aptl[], SHORT sNum, SHORT sAngle)
  81.      {
  82.      static SHORT sSin [60] =
  83.                     {
  84.                        0,  105,  208,  309,  407,  500,  588,  669,  743,  809,
  85.                      866,  914,  951,  978,  995, 1000,  995,  978,  951,  914,
  86.                      866,  809,  743,  669,  588,  500,  407,  309,  208,  105,
  87.                        0, -104, -207, -308, -406, -499, -587, -668, -742, -808,
  88.                     -865, -913, -950, -977, -994, -999, -994, -977, -950, -913,
  89.                     -865, -808, -742, -668, -587, -499, -406, -308, -207, -104
  90.                     } ;
  91.      POINTL       ptlTemp ;
  92.      SHORT        sIndex ;
  93.  
  94.      for (sIndex = 0 ; sIndex < sNum ; sIndex++)
  95.           {
  96.           ptlTemp.x = (aptl[sIndex].x * sSin [(sAngle + 15) % 60] +
  97.                        aptl[sIndex].y * sSin [sAngle]) / 1000 ;
  98.  
  99.           ptlTemp.y = (aptl[sIndex].y * sSin [(sAngle + 15) % 60] -
  100.                        aptl[sIndex].x * sSin [sAngle]) / 1000 ;
  101.  
  102.           aptl[sIndex] = ptlTemp ;
  103.           }
  104.      }
  105.  
  106. VOID ScalePoint (POINTL aptl[], SHORT sNum, PWINDOWINFO pwi)
  107.      {
  108.      SHORT sIndex ;
  109.  
  110.      for (sIndex = 0 ; sIndex < sNum ; sIndex++)
  111.           {
  112.           aptl[sIndex].x = aptl[sIndex].x * pwi->cxPixelDiam / 200 ;
  113.           aptl[sIndex].y = aptl[sIndex].y * pwi->cyPixelDiam / 200 ;
  114.           }
  115.      }
  116.  
  117. VOID TranslatePoint (POINTL aptl[], SHORT sNum, PWINDOWINFO pwi)
  118.      {
  119.      SHORT sIndex ;
  120.  
  121.      for (sIndex = 0 ; sIndex < sNum ; sIndex++)
  122.           {
  123.           aptl[sIndex].x += pwi->cxClient / 2 ;
  124.           aptl[sIndex].y += pwi->cyClient / 2 ;
  125.           }
  126.      }
  127.  
  128. VOID DrawHand (HPS hps, POINTL aptlIn[], SHORT sNum, SHORT sAngle,
  129.                PWINDOWINFO pwi)
  130.      {
  131.      POINTL aptl [5] ;
  132.      SHORT  sIndex ;
  133.  
  134.      for (sIndex = 0 ; sIndex < sNum ; sIndex++)
  135.           aptl [sIndex] = aptlIn [sIndex] ;
  136.  
  137.      RotatePoint    (aptl, sNum, sAngle) ;
  138.      ScalePoint     (aptl, sNum, pwi) ;
  139.      TranslatePoint (aptl, sNum, pwi) ;
  140.  
  141.      GpiMove (hps, aptl) ;
  142.      GpiPolyLine (hps, sNum - 1L, aptl + 1) ;
  143.      }
  144.  
  145. MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  146.      {
  147.      static DATETIME   dtPrevious ;
  148.      static HDC        hdc ;
  149.      static LONG       xPixelsPerMeter, yPixelsPerMeter ;
  150.      static POINTL     aptlHour   [5] = { 0,-15, 10,0, 0,60, -10,0, 0,-15 },
  151.                        aptlMinute [5] = { 0,-20,  5,0, 0,80,  -5,0, 0,-20 },
  152.                        aptlSecond [2] = { 0,  0,  0,80 } ;
  153.      static WINDOWINFO wi ;
  154.      DATETIME          dt ;
  155.      HPS               hps ;
  156.      SHORT             sDiamMM;
  157.      USHORT            color;
  158.      RECTL             PArea;
  159.      LONG              x, y;
  160.  
  161.      switch (msg)
  162.           {
  163.           case WM_CREATE:
  164.                hdc = WinOpenWindowDC (hwnd) ;
  165.  
  166.                DevQueryCaps (hdc, CAPS_VERTICAL_RESOLUTION,
  167.                                   1L, &yPixelsPerMeter) ;
  168.                DevQueryCaps (hdc, CAPS_HORIZONTAL_RESOLUTION,
  169.                                   1L, &xPixelsPerMeter) ;
  170.  
  171.                DosGetDateTime (&dtPrevious) ;
  172.                dtPrevious.hours = (dtPrevious.hours * 5) % 60 +
  173.                                    dtPrevious.minutes / 12 ;
  174.  
  175.                hps = WinGetPS (hwnd) ;
  176.                hbm = GpiLoadBitmap(hps, NULL, ID_BITMAP, 0L, 0L);
  177.                WinReleasePS (hps) ;
  178.                return 0 ;
  179.  
  180.           case WM_SIZE:
  181.                wi.cxClient = SHORT1FROMMP (mp2) ;
  182.                wi.cyClient = SHORT2FROMMP (mp2) ;
  183.  
  184.                sDiamMM = (SHORT) min (wi.cxClient * 1000L / xPixelsPerMeter,
  185.                                       wi.cyClient * 1000L / yPixelsPerMeter) ;
  186.  
  187.                wi.cxPixelDiam = (SHORT) (xPixelsPerMeter * sDiamMM / 1000) ;
  188.                wi.cyPixelDiam = (SHORT) (yPixelsPerMeter * sDiamMM / 1000) ;
  189.                return 0 ;
  190.  
  191.           case WM_TIMER:
  192.                DosGetDateTime (&dt);
  193.                if (init.on_off)
  194.                  if ((dt.hours == (UCHAR)init.alarm_time.hours) &&
  195.                      (dt.minutes == (UCHAR)init.alarm_time.mins))
  196.                    {
  197.                    if ( ! alarm_status)
  198.                      {
  199.                      alarm_status = 0xff;  WinFlashWindow(hwndFrame, TRUE);
  200.                      }
  201.                    }
  202.                  else
  203.                    if (alarm_status) 
  204.                      {
  205.                      alarm_status = 0;  WinFlashWindow(hwndFrame, FALSE);
  206.                      }
  207.  
  208.                dt.hours = (dt.hours * 5) % 60 + dt.minutes / 12 ;
  209.  
  210.                hps = WinGetPS (hwnd) ;
  211.                GpiSetColor(hps, ((init.on_off) ? init.text_color 
  212.                                                : init.background));
  213.  
  214.                DrawHand (hps, aptlSecond, 2, dtPrevious.seconds, &wi) ;
  215.  
  216.                if (dt.hours   != dtPrevious.hours ||
  217.                    dt.minutes != dtPrevious.minutes)
  218.                     {
  219.                     DrawHand (hps, aptlHour,   5, dtPrevious.hours,   &wi) ;
  220.                     DrawHand (hps, aptlMinute, 5, dtPrevious.minutes, &wi) ;
  221.                     }
  222.  
  223.                GpiSetColor(hps, ((init.on_off) ? init.background
  224.                                                : init.text_color));
  225.  
  226.                DrawHand (hps, aptlHour,   5, dt.hours,   &wi) ;
  227.                DrawHand (hps, aptlMinute, 5, dt.minutes, &wi) ;
  228.                DrawHand (hps, aptlSecond, 2, dt.seconds, &wi) ;
  229.  
  230.                WinReleasePS (hps) ;
  231.                dtPrevious = dt ;
  232.                return 0 ;
  233.  
  234.           case WM_PAINT: 
  235.                hps = WinBeginPaint (hwnd, NULL, NULL) ;
  236.                WinQueryWindowRect(hwnd, (PRECTL)&PArea);
  237.    
  238.                WinFillRect(hps, (PRECTL)&PArea, 
  239.                       ((init.on_off) ? init.text_color : init.background));
  240.                if ((y = (PArea.yTop - PArea.yBottom)) >= 
  241.                    (x = (PArea.xRight - PArea.xLeft)))
  242.                  {
  243.                  PArea.yTop    -= ((y - x) / 2);
  244.                  PArea.yBottom += ((y - x) / 2);
  245.                  }
  246.                else
  247.                  {
  248.                  PArea.xLeft   += ((x - y) / 2);
  249.                  PArea.xRight  -= ((x - y) / 2);
  250.                  }
  251.  
  252.                if (init.on_off)
  253.                  WinDrawBitmap(hps, hbm, NULL, (PPOINTL)&PArea, 
  254.                     init.background, init.text_color, DBM_STRETCH);
  255.                else
  256.                  WinDrawBitmap(hps, hbm, NULL, (PPOINTL)&PArea,
  257.                     init.text_color, init.background, DBM_STRETCH);   
  258.  
  259.                DrawHand (hps, aptlHour,   5, dtPrevious.hours,   &wi) ;
  260.                DrawHand (hps, aptlMinute, 5, dtPrevious.minutes, &wi) ;
  261.                DrawHand (hps, aptlSecond, 2, dtPrevious.seconds, &wi) ;
  262.  
  263.                WinEndPaint (hps) ; 
  264.                return 0 ;
  265.              
  266.           case WM_COMMAND:
  267.             switch (color = LOUSHORT(mp1))
  268.               {
  269.               case IDM_STOP: 
  270.                 WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
  271.                 return(0);
  272.  
  273.               case IDM_FCOLOR: 
  274.               case IDM_BCOLOR:
  275.                 if (((color == IDM_FCOLOR) && ( ! init.on_off)) ||
  276.                     ((color == IDM_BCOLOR) && (init.on_off)))
  277.                   {
  278.                   if (++(init.text_color) > 15) init.text_color = 0;
  279.                   }
  280.                 else
  281.                   {
  282.                   if (++(init.background) > 15) init.background = 0;
  283.                   }
  284.                 WinInvalidateRect(hwnd, NULL, TRUE);
  285.                 return(0);
  286.  
  287.               case IDM_ALARM_ON:
  288.                 WinInvalidateRect(hwnd, NULL, TRUE);
  289.                 init.on_off = 0xff;  return(0);
  290.  
  291.               case IDM_ALARM_OFF: 
  292.                 init.on_off = 0;  WinInvalidateRect(hwnd, NULL, TRUE);
  293.                 if (alarm_status) 
  294.                   {
  295.                   alarm_status = 0;  WinFlashWindow(hwndFrame, FALSE);
  296.                   }
  297.                 return(0);
  298.                  
  299.               case IDM_ALARM_SET: 
  300.                 WinDlgBox(HWND_DESKTOP, hwndFrame, (PFNWP)AlarmSet,
  301.                           NULL, IDD_ALARM_SET, (PCH)NULL);
  302.                 WinInvalidateRect(hwnd, NULL, TRUE);
  303.                 return(0);
  304.               }
  305.           }
  306.      return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  307.      }
  308.  
  309. static UCHAR    OldOnOff;
  310. static TIMEINFO OldTime;
  311. char            wstr[11];
  312. int    hh, mm;
  313.  
  314. MRESULT EXPENTRY AlarmSet(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  315. {
  316. switch (msg)
  317.   {
  318.   case WM_INITDLG: 
  319.     OldOnOff = init.on_off;
  320.     OldTime  = init.alarm_time;
  321.     sprintf(wstr, "%2.2u:%2.2u", OldTime.hours, OldTime.mins);
  322.  
  323.     if (init.on_off)
  324.       WinPostMsg(WinWindowFromID(hwnd, IDD_ALARM_ONOFF), 
  325.                  BM_SETCHECK, MPFROM2SHORT(TRUE, 0), 0L);
  326.  
  327.     WinSendDlgItemMsg(hwnd, IDD_ALARM_TIME, EM_SETTEXTLIMIT, MPFROM2SHORT(5, 0), (MPARAM)0 );
  328.        WinSetWindowText(WinWindowFromID(hwnd, IDD_ALARM_TIME), wstr);
  329.     return(FALSE);
  330.  
  331.   case WM_COMMAND: 
  332.     switch (COMMANDMSG(&msg)->cmd)
  333.       {
  334.       case DID_OK:
  335.         WinQueryDlgItemText(hwnd, IDD_ALARM_TIME, 9, (PSZ)&wstr[0]);
  336.         if (sscanf(wstr, "%u:%u", &hh, &mm) == 2)
  337.           if ((hh >= 0) && (mm >= 0) && (hh < 24) && (mm < 60))
  338.             {
  339.             init.alarm_time.hours = hh;
  340.             init.alarm_time.mins  = mm;  
  341.             return((MRESULT)WinDismissDlg(hwnd, TRUE));
  342.             }
  343.         sprintf(wstr, "%2.2u:%2.2u", OldTime.hours, OldTime.mins);
  344.            WinSetWindowText(WinWindowFromID(hwnd, IDD_ALARM_TIME), wstr);
  345.         WinAlarm(hwnd, WA_ERROR);
  346.         return(FALSE);
  347.  
  348.       case DID_CANCEL:
  349.         init.on_off = OldOnOff;
  350.         init.alarm_time = OldTime;
  351.         return((MRESULT)WinDismissDlg(hwnd, FALSE));
  352.       }
  353.     return(0);
  354.  
  355.   case WM_CONTROL: 
  356.     if (SHORT2FROMMP(mp1) == BN_CLICKED)
  357.       switch (SHORT1FROMMP(mp1))
  358.         {
  359.         case IDD_ALARM_ONOFF: 
  360.            init.on_off ^= 0xff;  WinInvalidateRect(hwndClient, NULL, TRUE);
  361.            if ((! init.on_off) && (alarm_status))
  362.              {
  363.              alarm_status = 0;  WinFlashWindow(hwndFrame, FALSE);
  364.              }
  365.          }
  366.     return(FALSE); /****** Note! Original file was Corrupt %Jo !!!   XTAE); *******/
  367.  
  368.   default: return(WinDefDlgProc(hwnd, msg, mp1, mp2));
  369.   }
  370. return(MRFROMLONG(NULL));
  371. }
  372.