home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: InfoMgt / InfoMgt.zip / CPCLOCK.ZIP / CLOCK.C < prev    next >
C/C++ Source or Header  |  1989-01-09  |  8KB  |  230 lines

  1. /*-------------------------
  2.    CLOCK.C -- Analog Clock 
  3.   -------------------------*/
  4.  
  5. #define INCL_WIN
  6. #define INCL_GPI
  7. #include <os2.h>
  8. #include <stdlib.h>
  9.  
  10. #define ID_TIMER 1
  11.  
  12. typedef struct
  13.      {
  14.      SHORT cxClient ;
  15.      SHORT cyClient ;
  16.      SHORT cxPixelDiam ;
  17.      SHORT cyPixelDiam ;
  18.      }
  19.      WINDOWINFO ;
  20.  
  21. typedef WINDOWINFO *PWINDOWINFO ;
  22.  
  23. MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
  24.  
  25. int main (void)
  26.      {
  27.      static CHAR  szClientClass[] = "Clock" ;
  28.      static ULONG flFrameFlags = FCF_TITLEBAR      | FCF_SYSMENU |
  29.                                  FCF_SIZEBORDER    | FCF_MINMAX  |
  30.                                  FCF_SHELLPOSITION | FCF_TASKLIST ;
  31.      HAB          hab ;
  32.      HMQ          hmq ;
  33.      HWND         hwndFrame, hwndClient ;
  34.      QMSG         qmsg ;
  35.  
  36.      hab = WinInitialize (0) ;
  37.      hmq = WinCreateMsgQueue (hab, 0) ;
  38.  
  39.      WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;
  40.  
  41.      hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
  42.                                      &flFrameFlags, szClientClass, NULL,
  43.                      0L, NULL, 0, &hwndClient) ;
  44.  
  45.      if (WinStartTimer (hab, hwndClient, ID_TIMER, 1000))
  46.           {
  47.           while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  48.                WinDispatchMsg (hab, &qmsg) ;
  49.  
  50.           WinStopTimer (hab, hwndClient, ID_TIMER) ;
  51.           }
  52.      else
  53.           WinMessageBox (HWND_DESKTOP, hwndClient,
  54.                          "Too many clocks or timers",
  55.                          szClientClass, 0, MB_OK | MB_ICONEXCLAMATION) ;
  56.  
  57.      WinDestroyWindow (hwndFrame) ;
  58.      WinDestroyMsgQueue (hmq) ;
  59.      WinTerminate (hab) ;
  60.      return 0 ;
  61.      }
  62.  
  63. VOID RotatePoint (POINTL aptl[], SHORT sNum, SHORT sAngle)
  64.      {
  65.      static SHORT sSin [60] =
  66.                     {
  67.                        0,  105,  208,  309,  407,  500,  588,  669,  743,  809,
  68.                      866,  914,  951,  978,  995, 1000,  995,  978,  951,  914,
  69.                      866,  809,  743,  669,  588,  500,  407,  309,  208,  105,
  70.                        0, -104, -207, -308, -406, -499, -587, -668, -742, -808,
  71.                     -865, -913, -950, -977, -994, -999, -994, -977, -950, -913,
  72.                     -865, -808, -742, -668, -587, -499, -406, -308, -207, -104
  73.                     } ;
  74.      POINTL       ptlTemp ;
  75.      SHORT        sIndex ;
  76.  
  77.      for (sIndex = 0 ; sIndex < sNum ; sIndex++)
  78.           {
  79.           ptlTemp.x = (aptl[sIndex].x * sSin [(sAngle + 15) % 60] +
  80.                        aptl[sIndex].y * sSin [sAngle]) / 1000 ;
  81.  
  82.           ptlTemp.y = (aptl[sIndex].y * sSin [(sAngle + 15) % 60] -
  83.                        aptl[sIndex].x * sSin [sAngle]) / 1000 ;
  84.  
  85.           aptl[sIndex] = ptlTemp ;
  86.           }
  87.      }
  88.  
  89. VOID ScalePoint (POINTL aptl[], SHORT sNum, PWINDOWINFO pwi)
  90.      {
  91.      SHORT sIndex ;
  92.  
  93.      for (sIndex = 0 ; sIndex < sNum ; sIndex++)
  94.           {
  95.           aptl[sIndex].x = aptl[sIndex].x * pwi->cxPixelDiam / 200 ;
  96.           aptl[sIndex].y = aptl[sIndex].y * pwi->cyPixelDiam / 200 ;
  97.           }
  98.      }
  99.  
  100. VOID TranslatePoint (POINTL aptl[], SHORT sNum, PWINDOWINFO pwi)
  101.      {
  102.      SHORT sIndex ;
  103.  
  104.      for (sIndex = 0 ; sIndex < sNum ; sIndex++)
  105.           {
  106.           aptl[sIndex].x += pwi->cxClient / 2 ;
  107.           aptl[sIndex].y += pwi->cyClient / 2 ;
  108.           }
  109.      }
  110.  
  111. VOID DrawHand (HPS hps, POINTL aptlIn[], SHORT sNum, SHORT sAngle,
  112.                PWINDOWINFO pwi)
  113.      {
  114.      POINTL aptl [5] ;
  115.      SHORT  sIndex ;
  116.  
  117.      for (sIndex = 0 ; sIndex < sNum ; sIndex++)
  118.           aptl [sIndex] = aptlIn [sIndex] ;
  119.  
  120.      RotatePoint    (aptl, sNum, sAngle) ;
  121.      ScalePoint     (aptl, sNum, pwi) ;
  122.      TranslatePoint (aptl, sNum, pwi) ;
  123.  
  124.      GpiMove (hps, aptl) ;
  125.      GpiPolyLine (hps, sNum - 1L, aptl + 1) ;
  126.      }
  127.  
  128. MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  129.      {
  130.      static DATETIME   dtPrevious ;
  131.      static HDC        hdc ;
  132.      static LONG       xPixelsPerMeter, yPixelsPerMeter ;
  133.      static POINTL     aptlHour   [5] = { 0,-15, 10,0, 0,60, -10,0, 0,-15 },
  134.                        aptlMinute [5] = { 0,-20,  5,0, 0,80,  -5,0, 0,-20 },
  135.                        aptlSecond [2] = { 0,  0,  0,80 } ;
  136.      static WINDOWINFO wi ;
  137.      DATETIME          dt ;
  138.      HPS               hps ;
  139.      POINTL            aptl [3] ;
  140.      SHORT             sDiamMM, sAngle ;
  141.  
  142.      switch (msg)
  143.           {
  144.           case WM_CREATE:
  145.                hdc = WinOpenWindowDC (hwnd) ;
  146.  
  147.                DevQueryCaps (hdc, CAPS_VERTICAL_RESOLUTION,
  148.                                   1L, &yPixelsPerMeter) ;
  149.                DevQueryCaps (hdc, CAPS_HORIZONTAL_RESOLUTION,
  150.                                   1L, &xPixelsPerMeter) ;
  151.  
  152.                DosGetDateTime (&dtPrevious) ;
  153.                dtPrevious.hours = (dtPrevious.hours * 5) % 60 +
  154.                                    dtPrevious.minutes / 12 ;
  155.                return 0 ;
  156.  
  157.           case WM_SIZE:
  158.                wi.cxClient = SHORT1FROMMP (mp2) ;
  159.                wi.cyClient = SHORT2FROMMP (mp2) ;
  160.  
  161.                sDiamMM = (SHORT) min (wi.cxClient * 1000L / xPixelsPerMeter,
  162.                                       wi.cyClient * 1000L / yPixelsPerMeter) ;
  163.  
  164.                wi.cxPixelDiam = (SHORT) (xPixelsPerMeter * sDiamMM / 1000) ;
  165.                wi.cyPixelDiam = (SHORT) (yPixelsPerMeter * sDiamMM / 1000) ;
  166.                return 0 ;
  167.  
  168.           case WM_TIMER:
  169.                DosGetDateTime (&dt) ;
  170.                dt.hours = (dt.hours * 5) % 60 + dt.minutes / 12 ;
  171.  
  172.                hps = WinGetPS (hwnd) ;
  173.                GpiSetColor (hps, CLR_BACKGROUND) ;
  174.  
  175.                DrawHand (hps, aptlSecond, 2, dtPrevious.seconds, &wi) ;
  176.  
  177.                if (dt.hours   != dtPrevious.hours ||
  178.                    dt.minutes != dtPrevious.minutes)
  179.                     {
  180.                     DrawHand (hps, aptlHour,   5, dtPrevious.hours,   &wi) ;
  181.                     DrawHand (hps, aptlMinute, 5, dtPrevious.minutes, &wi) ;
  182.                     }
  183.  
  184.                GpiSetColor (hps, CLR_NEUTRAL) ;
  185.  
  186.                DrawHand (hps, aptlHour,   5, dt.hours,   &wi) ;
  187.                DrawHand (hps, aptlMinute, 5, dt.minutes, &wi) ;
  188.                DrawHand (hps, aptlSecond, 2, dt.seconds, &wi) ;
  189.  
  190.                WinReleasePS (hps) ;
  191.                dtPrevious = dt ;
  192.                return 0 ;
  193.  
  194.           case WM_PAINT:
  195.                hps = WinBeginPaint (hwnd, NULL, NULL) ;
  196.                GpiErase (hps) ;
  197.  
  198.                for (sAngle = 0 ; sAngle < 60 ; sAngle++)
  199.                     {
  200.                     aptl[0].x = 0 ;
  201.                     aptl[0].y = 90 ;
  202.  
  203.                     RotatePoint    (aptl, 1, sAngle) ;
  204.                     ScalePoint     (aptl, 1, &wi) ;
  205.                     TranslatePoint (aptl, 1, &wi) ;
  206.  
  207.                     aptl[2].x = aptl[2].y = sAngle % 5 ? 2 : 10 ;
  208.  
  209.                     ScalePoint (aptl + 2, 1, &wi) ;
  210.  
  211.                     aptl[0].x -= aptl[2].x / 2 ;
  212.                     aptl[0].y -= aptl[2].y / 2 ;
  213.  
  214.                     aptl[1].x = aptl[0].x + aptl[2].x ;
  215.                     aptl[1].y = aptl[0].y + aptl[2].y ;
  216.  
  217.                     GpiMove (hps, aptl) ;
  218.                     GpiBox (hps, DRO_OUTLINEFILL, aptl + 1,
  219.                                  aptl[2].x, aptl[2].y) ;
  220.                     }
  221.                DrawHand (hps, aptlHour,   5, dtPrevious.hours,   &wi) ;
  222.                DrawHand (hps, aptlMinute, 5, dtPrevious.minutes, &wi) ;
  223.                DrawHand (hps, aptlSecond, 2, dtPrevious.seconds, &wi) ;
  224.  
  225.                WinEndPaint (hps) ;
  226.                return 0 ;
  227.           }
  228.      return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  229.      }
  230.