/*--------------------------------------
CLOCK.C -- Analog Clock Program
(c) Charles Petzold, 1998
--------------------------------------*/
#include <windows.h>
#include <math.h>
#include <stdlib.h>
#define ID_TIMER 1
#define TWOPI (2 * 3.14159)
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Clock") ;
HWND hwnd;
MSG msg;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = NULL ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("Program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, TEXT ("33Clock"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
void SetIsotropic (HDC hdc, int cxClient, int cyClient)
{
SetMapMode (hdc, MM_ISOTROPIC) ;
SetWindowExtEx (hdc, 1000, 1000, NULL) ;
SetViewportExtEx (hdc, cxClient / 2, -cyClient / 2, NULL) ;
SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL) ;
}
void RotatePoint (POINT pt[], int iNum, int iAngle)
{
int i ;
POINT ptTemp ;
for (i = 0 ; i < iNum ; i++)
{
ptTemp.x = (int) (pt[i].x * cos (TWOPI * iAngle / 360) +
pt[i].y * sin (TWOPI * iAngle / 360)) ;
ptTemp.y = (int) (pt[i].y * cos (TWOPI * iAngle / 360) -
pt[i].x * sin (TWOPI * iAngle / 360)) ;
pt[i] = ptTemp ;
}
}
void DrawClock (HDC hdc)
{
int iAngle ;
POINT pt[3] ;
HFONT hf;
HBRUSH hb;
char lpstr[]="123691245781011";
for (iAngle = 0 ; iAngle < 360 ; iAngle += 6)
{
pt[0].x = 0 ;
pt[0].y = 900 ;
RotatePoint (pt, 1, iAngle) ;
pt[2].x = pt[2].y = iAngle % 5 ? 33 : 150 ;
pt[0].x -= pt[2].x / 2 ;
pt[0].y -= pt[2].y / 2 ;
pt[1].x = pt[0].x + pt[2].x ;
pt[1].y = pt[0].y + pt[2].y ;
hb=CreateSolidBrush(0xffbb00);
SelectObject (hdc, hb) ;
hf=CreateFont(100,0,0,0,400,0,0,0,0,0,0,0,0,0);
SelectObject(hdc,hf);
SetBkColor(hdc,0xffbb00);
SetTextColor(hdc,RGB(255,123,0));
TextOut(hdc, -55, 950,&lpstr[0],2);
TextOut(hdc, 880, 50,&lpstr[2],1);
TextOut(hdc, -30, -850,&lpstr[3],1);
TextOut(hdc, -920, 50,&lpstr[4],1);
TextOut(hdc, 420, 820,&lpstr[5],1);
TextOut(hdc, 750, 500,&lpstr[6],1);
TextOut(hdc, 750, -400,&lpstr[7],1);
TextOut(hdc, 420, -730,&lpstr[8],1);
TextOut(hdc, -470, -730,&lpstr[9],1);
TextOut(hdc, -800, -400,&lpstr[10],1);
TextOut(hdc, -830, 500,&lpstr[11],2);
TextOut(hdc, -500, 820,&lpstr[13],2);
Ellipse (hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y) ;
}
}
void DrawHands (HDC hdc, SYSTEMTIME * pst, BOOL fChange)
{
static POINT pt[3][5] = { 0, -150, 100, 0, 0, 600, -100, 0, 0, -150,
0, -200, 50, 0, 0, 800, -50, 0, 0, -200,
0, 0, 0, 0, 0, 0, 0, 0, 0, 800 } ;
int i, iAngle[3] ;
POINT ptTemp[3][5] ;
HBRUSH hb;
HPEN hp;
iAngle[0] = (pst->wHour * 30) % 360 + pst->wMinute / 2 ;
iAngle[1] = pst->wMinute * 6 ;
iAngle[2] = pst->wSecond * 6 ;
memcpy (ptTemp, pt, sizeof (pt)) ;
for (i = fChange ? 0 : 2 ; i < 3 ; i++)
{
RotatePoint (ptTemp[i], 5, iAngle[i]) ;
if (i==0)
{
hb=CreateSolidBrush(RGB(255,0,0));
hp=CreatePen(PS_SOLID,1,RGB(0,255,0));
}
else
if (i==1)
{
hb=CreateSolidBrush(RGB(0,255,0));
hp=CreatePen(PS_SOLID,1,RGB(0,0,255));
}
else
{
hb=CreateSolidBrush(RGB(0,0,255));
hp=CreatePen(PS_SOLID,1,RGB(255,0,0));
}
SelectObject(hdc,hb);
SelectObject(hdc,hp);
Polygon (hdc, ptTemp[i], 5) ;
SelectObject (hdc, GetStockObject (BLACK_BRUSH)) ;
DeleteObject(hb);
}
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int cxClient, cyClient ;
static SYSTEMTIME stPrevious ;
BOOL fChange ;
HDC hdc ;
PAINTSTRUCT ps ;
SYSTEMTIME st ;
HFONT hf;
char b[]=" 年月日";
TCHAR a[4],c[2],e[2];
char m[]=":";
char k[]=" ";
char z[]="0";
switch (message)
{
case WM_CREATE :
SetTimer (hwnd, ID_TIMER, 1000, NULL) ;
GetLocalTime (&st) ;
stPrevious = st ;
return 0 ;
case WM_SIZE :
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
return 0 ;
case WM_TIMER :
GetLocalTime (&st) ;
fChange = st.wHour != stPrevious.wHour ||
st.wMinute != stPrevious.wMinute ;
hdc = GetDC (hwnd) ;
SetIsotropic (hdc, cxClient, cyClient) ;
SelectObject (hdc, GetStockObject (WHITE_PEN));
DrawHands (hdc, &stPrevious, fChange);
SelectObject (hdc, GetStockObject (BLACK_PEN));
DrawHands (hdc, &st, true);
ReleaseDC (hwnd, hdc) ;
InvalidateRect(hwnd,NULL,1);
stPrevious = st ;
return 0 ;
case WM_PAINT :
hdc = BeginPaint (hwnd, &ps) ;
GetLocalTime(&st);
hf=CreateFont(30,0,0,0,700,0,0,0,0,0,0,0,0,0);
SelectObject(hdc,hf);
SetTextColor(hdc,RGB(255,0,0));
itoa(st.wYear,a,10);
TextOut(hdc,280,80,a,sizeof(a));
TextOut(hdc,340,80,&b[1],2);
itoa(st.wMonth,c,10);
TextOut(hdc,370,80,c,sizeof(c));
TextOut(hdc,400,80,&b[3],2);
itoa(st.wDay,e,10);
TextOut(hdc,430,80,e,sizeof(e));
TextOut(hdc,460,80,&b[5],2);
itoa(st.wHour,c,10);
if(st.wHour<10)
{
TextOut(hdc,cxClient/3*1.25,cyClient/3*2.4,z,1);
TextOut(hdc,cxClient/3*1.3,400,c,1);
TextOut(hdc,cxClient/2-30,400,k,1);
}
else
{
TextOut(hdc,cxClient/3*1.25,cyClient/3*2.4,c,2);
}
TextOut(hdc,cxClient/2.15,cyClient/3*2.4,m,1);
itoa(st.wMinute,c,10);
if(st.wMinute<10)
{
TextOut(hdc,cxClient/2.06,cyClient/3*2.4,z,1);
TextOut(hdc,cxClient/2+2,cyClient/3*2.4,c,1);
TextOut(hdc,cxClient/2+17,cyClient/3*2.4,k,1);
}
else
{
TextOut(hdc,cxClient/3,cyClient/3*2.4,c,2);
}
TextOut(hdc,cxClient/2+20,cyClient/3*2.4,m,1);
itoa(st.wSecond,c,10);
if (st.wSecond<10)
{
TextOut(hdc,cxClient/1.84,cyClient/3*2.4,z,1);
TextOut(hdc,cxClient/1.777,cyClient/3*2.4,c,1);
TextOut(hdc,cxClient/2+60,cyClient/3*2.4,k,1);
}
else
{
TextOut(hdc,cxClient/1.83,cyClient/3*2.4,c,2);
}
SetIsotropic (hdc, cxClient, cyClient) ;
DrawClock (hdc) ;
DrawHands (hdc, &stPrevious, TRUE) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY :
KillTimer (hwnd, ID_TIMER) ;
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}