home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: InfoMgt
/
InfoMgt.zip
/
CPCLOCK.ZIP
/
CLOCK.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-01-09
|
8KB
|
230 lines
/*-------------------------
CLOCK.C -- Analog Clock
-------------------------*/
#define INCL_WIN
#define INCL_GPI
#include <os2.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" ;
static ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
FCF_SIZEBORDER | FCF_MINMAX |
FCF_SHELLPOSITION | FCF_TASKLIST ;
HAB hab ;
HMQ hmq ;
HWND hwndFrame, hwndClient ;
QMSG qmsg ;
hab = WinInitialize (0) ;
hmq = WinCreateMsgQueue (hab, 0) ;
WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;
hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
&flFrameFlags, szClientClass, NULL,
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:
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) ;
}