home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / ACLOCK2.ZIP / CLOCK2.C < prev    next >
C/C++ Source or Header  |  1989-08-28  |  13KB  |  370 lines

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