File:  [OS/2 SDKs] / pmsdk / samples / petzold / chap07 / clock.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 12:28:12 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: pmsdk-1988, HEAD
Microsoft OS/2 SDK PM 08-08-1988

/*-------------------------
   CLOCK.C -- Analog Clock 
  -------------------------*/

#define INCL_WIN
#define INCL_GPI

#include <os2.h>
#include <stddef.h>
#include <stdlib.h>

#define ID_TIMER 1

typedef struct
     {
     SHORT cxClient ;
     SHORT cyClient ;
     SHORT cxPixelDiam ;
     SHORT cyPixelDiam ;
     }
     WINDOWINFO ;

typedef WINDOWINFO *PWINDOWINFO ;

MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;

int main (void)
     {
     static CHAR szClientClass[] = "Clock" ;
     HAB         hab ;
     HMQ         hmq ;
     HWND        hwndClient, hwndFrame ;
     QMSG        qmsg ;
     ULONG       flFrameFlags = FCF_STANDARD & ~FCF_MENU ;
     ULONG       flFrameStyle = WS_VISIBLE ;

     hab = WinInitialize (0) ;
     hmq = WinCreateMsgQueue (hab, 0) ;

     WinRegisterClass (hab, szClientClass, ClientWndProc,
                       CS_SIZEREDRAW | CS_SYNCPAINT, 0) ;

     hwndFrame = WinCreateStdWindow (HWND_DESKTOP, flFrameStyle,
                                     &flFrameFlags, szClientClass,
                                     szClientClass,
				     0L, NULL, 0, &hwndClient) ;

     if (WinStartTimer (hab, hwndClient, ID_TIMER, 1000))
          {
          while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
               WinDispatchMsg (hab, &qmsg) ;

          WinStopTimer (hab, hwndClient, ID_TIMER) ;
          }
     else
          WinMessageBox (HWND_DESKTOP, hwndClient,
                         "Too many clocks or timers",
                         szClientClass, 0, MB_OK | MB_ICONEXCLAMATION) ;

     WinDestroyWindow (hwndFrame) ;
     WinDestroyMsgQueue (hmq) ;
     WinTerminate (hab) ;

     return 0 ;
     }

VOID RotatePoint (POINTL aptl[], SHORT sNum, SHORT sAngle)
     {
     static SHORT sSin [60] =
                    {
                       0,  105,  208,  309,  407,  500,  588,  669,  743,  809,
                     866,  914,  951,  978,  995, 1000,  995,  978,  951,  914,
                     866,  809,  743,  669,  588,  500,  407,  309,  208,  105,
                       0, -104, -207, -308, -406, -499, -587, -668, -742, -808,
                    -865, -913, -950, -977, -994, -999, -994, -977, -950, -913,
                    -865, -808, -742, -668, -587, -499, -406, -308, -207, -104
                    } ;
     POINTL       ptlTemp ;
     SHORT        sIndex ;

     for (sIndex = 0 ; sIndex < sNum ; sIndex++)
          {
          ptlTemp.x = (aptl[sIndex].x * sSin [(sAngle + 15) % 60] +
                       aptl[sIndex].y * sSin [sAngle]) / 1000 ;

          ptlTemp.y = (aptl[sIndex].y * sSin [(sAngle + 15) % 60] -
                       aptl[sIndex].x * sSin [sAngle]) / 1000 ;

          aptl[sIndex] = ptlTemp ;
          }
     }

VOID ScalePoint (POINTL aptl[], SHORT sNum, PWINDOWINFO pwi)
     {
     SHORT sIndex ;

     for (sIndex = 0 ; sIndex < sNum ; sIndex++)
          {
          aptl[sIndex].x = aptl[sIndex].x * pwi->cxPixelDiam / 200 ;
          aptl[sIndex].y = aptl[sIndex].y * pwi->cyPixelDiam / 200 ;
          }
     }

VOID TranslatePoint (POINTL aptl[], SHORT sNum, PWINDOWINFO pwi)
     {
     SHORT sIndex ;

     for (sIndex = 0 ; sIndex < sNum ; sIndex++)
          {
          aptl[sIndex].x += pwi->cxClient / 2 ;
          aptl[sIndex].y += pwi->cyClient / 2 ;
          }
     }

VOID DrawHand (HPS hps, POINTL aptlIn[], SHORT sNum, SHORT sAngle,
               PWINDOWINFO pwi)
     {
     POINTL aptl [5] ;
     SHORT  sIndex ;

     for (sIndex = 0 ; sIndex < sNum ; sIndex++)
          aptl [sIndex] = aptlIn [sIndex] ;

     RotatePoint    (aptl, sNum, sAngle) ;
     ScalePoint     (aptl, sNum, pwi) ;
     TranslatePoint (aptl, sNum, pwi) ;

     GpiMove (hps, aptl) ;

     GpiPolyLine (hps, sNum - 1L, aptl + 1) ;
     }

MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
     {
     static DATETIME   dtPrevious ;
     static HDC        hdc ;
     static LONG       xPixelsPerMeter, yPixelsPerMeter ;
     static POINTL     aptlHour   [5] = { 0,-15, 10,0, 0,60, -10,0, 0,-15 },
                       aptlMinute [5] = { 0,-20,  5,0, 0,80,  -5,0, 0,-20 },
                       aptlSecond [2] = { 0,  0,  0,80 } ;
     static WINDOWINFO wi ;
     DATETIME          dt ;
     HPS               hps ;
     POINTL            aptl [3] ;
     SHORT             sDiamMM, sAngle ;

     switch (msg)
          {
          case WM_CREATE:
               hdc = WinOpenWindowDC (hwnd) ;

               DevQueryCaps (hdc, CAPS_VERTICAL_RESOLUTION,
                                  1L, &yPixelsPerMeter) ;
               DevQueryCaps (hdc, CAPS_HORIZONTAL_RESOLUTION,
                                  1L, &xPixelsPerMeter) ;

               DosGetDateTime (&dtPrevious) ;
               dtPrevious.hours = (dtPrevious.hours * 5) % 60 +
                                   dtPrevious.minutes / 12 ;
               return 0 ;

          case WM_SIZE:
               wi.cxClient = SHORT1FROMMP (mp2) ;
               wi.cyClient = SHORT2FROMMP (mp2) ;

               sDiamMM = (SHORT) min (wi.cxClient * 1000L / xPixelsPerMeter,
                                      wi.cyClient * 1000L / yPixelsPerMeter) ;

               wi.cxPixelDiam = (SHORT) (xPixelsPerMeter * sDiamMM / 1000) ;
               wi.cyPixelDiam = (SHORT) (yPixelsPerMeter * sDiamMM / 1000) ;
               return 0 ;

          case WM_TIMER:
               if (0L == WinQuerySysValue (HWND_DESKTOP, SV_TRACKRECTLEVEL))
                    break ;

               DosGetDateTime (&dt) ;
               dt.hours = (dt.hours * 5) % 60 + dt.minutes / 12 ;

               hps = WinGetPS (hwnd) ;

               GpiSetColor (hps, CLR_BACKGROUND) ;
               DrawHand (hps, aptlSecond, 2, dtPrevious.seconds, &wi) ;

               if (dt.hours   != dtPrevious.hours ||
                   dt.minutes != dtPrevious.minutes)
                    {
                    DrawHand (hps, aptlHour,   5, dtPrevious.hours,   &wi) ;
                    DrawHand (hps, aptlMinute, 5, dtPrevious.minutes, &wi) ;
                    }

               GpiSetColor (hps, CLR_NEUTRAL) ;
               DrawHand (hps, aptlHour,   5, dt.hours,   &wi) ;
               DrawHand (hps, aptlMinute, 5, dt.minutes, &wi) ;
               DrawHand (hps, aptlSecond, 2, dt.seconds, &wi) ;

               WinReleasePS (hps) ;
               dtPrevious = dt ;
               return 0 ;

          case WM_PAINT:
               hps = WinBeginPaint (hwnd, NULL, NULL) ;
               GpiErase (hps) ;

               for (sAngle = 0 ; sAngle < 60 ; sAngle++)
                    {
                    aptl[0].x = 0 ;
                    aptl[0].y = 90 ;

                    RotatePoint    (aptl, 1, sAngle) ;
                    ScalePoint     (aptl, 1, &wi) ;
                    TranslatePoint (aptl, 1, &wi) ;

                    aptl[2].x = aptl[2].y = sAngle % 5 ? 2 : 10 ;

                    ScalePoint (aptl + 2, 1, &wi) ;

                    aptl[0].x -= aptl[2].x / 2 ;
                    aptl[0].y -= aptl[2].y / 2 ;

                    aptl[1].x = aptl[0].x + aptl[2].x ;
                    aptl[1].y = aptl[0].y + aptl[2].y ;

                    GpiMove (hps, aptl) ;
                    GpiBox (hps, DRO_OUTLINEFILL, aptl + 1,
                            aptl[2].x, aptl[2].y) ;

                    }
               DrawHand (hps, aptlHour,   5, dtPrevious.hours,   &wi) ;
               DrawHand (hps, aptlMinute, 5, dtPrevious.minutes, &wi) ;
               DrawHand (hps, aptlSecond, 2, dtPrevious.seconds, &wi) ;

               WinEndPaint (hps) ;
               return 0 ;
          }
     return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
     }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.