/********************************************************************* * * * rolex.c: Windows clock application for WINE (by Jim Peterson) * * * * This is a translation of a Turbo Pascal OWL application I made * * once, so it's a little flaky (tons of globals, functions that * * could have been in-lined, etc.). The source code should easily * * compile with a standard Win32 C compiler. * * * * To try it out, type 'make rolex'. * * * *********************************************************************/ #include #include #include "windows.h" char AppName[] = "Rolex"; char WindowName[] = "Rolex"; int WindowWidth = 100; int WindowHeight = 121; COLORREF FaceColor = RGB(192,192,192); COLORREF HandColor = RGB(0,0,0); COLORREF EtchColor = RGB(0,0,0); float Pi=3.1415926; typedef struct { int StartX,StartY,EndX,EndY; } HandData; int MaxX,MaxY; HandData OldSecond,OldHour,OldMinute; HWND HWindow; void DrawFace(HDC dc) { int MidX, MidY, t; MidX=MaxX/2; MidY=MaxY/2; SelectObject(dc,CreateSolidBrush(FaceColor)); SelectObject(dc,CreatePen(PS_SOLID,1,EtchColor)); Ellipse(dc,0,0,MaxX,MaxY); for(t=0; t<12; t++) { MoveToEx(dc,MidX+sin(t*Pi/6)*0.9*MidX,MidY-cos(t*Pi/6)*0.9*MidY,NULL); LineTo(dc,MidX+sin(t*Pi/6)*0.8*MidX,MidY-cos(t*Pi/6)*0.8*MidY); } if(MaxX>64 && MaxY>64) for(t=0; t<60; t++) SetPixel(dc,MidX+sin(t*Pi/30)*0.9*MidX,MidY-cos(t*Pi/30)*0.9*MidY ,EtchColor); DeleteObject(SelectObject(dc,GetStockObject(NULL_BRUSH))); DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN))); memset(&OldSecond,0,sizeof(OldSecond)); memset(&OldMinute,0,sizeof(OldMinute)); memset(&OldHour,0,sizeof(OldHour)); } void DrawHourHand(HDC dc) { MoveToEx(dc, OldHour.StartX, OldHour.StartY, NULL); LineTo(dc, OldHour.EndX, OldHour.EndY); } void DrawMinuteHand(HDC dc) { MoveToEx(dc, OldMinute.StartX, OldMinute.StartY, NULL); LineTo(dc, OldMinute.EndX, OldMinute.EndY); } void DrawSecondHand(HDC dc) { MoveToEx(dc, OldSecond.StartX, OldSecond.StartY, NULL); LineTo(dc, OldSecond.EndX, OldSecond.EndY); } BOOL UpdateHourHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos) { int Sx, Sy, Ex, Ey; BOOL rv; rv = FALSE; Sx = MidX; Sy = MidY; Ex = MidX+sin(Pos*Pi/6000)*XExt; Ey = MidY-cos(Pos*Pi/6000)*YExt; rv = ( Sx!=OldHour.StartX || Ex!=OldHour.EndX || Sy!=OldHour.StartY || Ey!=OldHour.EndY ); if(rv)DrawHourHand(dc); OldHour.StartX = Sx; OldHour.EndX = Ex; OldHour.StartY = Sy; OldHour.EndY = Ey; return rv; } BOOL UpdateMinuteHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos) { int Sx, Sy, Ex, Ey; BOOL rv; rv = FALSE; Sx = MidX; Sy = MidY; Ex = MidX+sin(Pos*Pi/30000)*XExt; Ey = MidY-cos(Pos*Pi/30000)*YExt; rv = ( Sx!=OldMinute.StartX || Ex!=OldMinute.EndX || Sy!=OldMinute.StartY || Ey!=OldMinute.EndY ); if(rv)DrawMinuteHand(dc); OldMinute.StartX = Sx; OldMinute.EndX = Ex; OldMinute.StartY = Sy; OldMinute.EndY = Ey; return rv; } BOOL UpdateSecondHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos) { int Sx, Sy, Ex, Ey; BOOL rv; rv = FALSE; Sx = MidX; Sy = MidY; Ex = MidX+sin(Pos*Pi/3000)*XExt; Ey = MidY-cos(Pos*Pi/3000)*YExt; rv = ( Sx!=OldSecond.StartX || Ex!=OldSecond.EndX || Sy!=OldSecond.StartY || Ey!=OldSecond.EndY ); if(rv)DrawSecondHand(dc); OldSecond.StartX = Sx; OldSecond.EndX = Ex; OldSecond.StartY = Sy; OldSecond.EndY = Ey; return rv; } void Idle(HDC idc) { SYSTEMTIME st; WORD H, M, S, F; int MidX, MidY; HDC dc; BOOL Redraw; if(idc) dc=idc; else dc=GetDC(HWindow); if(!dc)return; GetLocalTime(&st); H = st.wHour; M = st.wMinute; S = st.wSecond; F = st.wMilliseconds / 10; F = F + S*100; M = M*1000+F/6; H = H*1000+M/60; MidX = MaxX/2; MidY = MaxY/2; SelectObject(dc,CreatePen(PS_SOLID,1,FaceColor)); Redraw = FALSE; if(UpdateHourHand(dc,MidX,MidY,MidX*0.5,MidY*0.5,H)) Redraw = TRUE; if(UpdateMinuteHand(dc,MidX,MidY,MidX*0.65,MidY*0.65,M)) Redraw = TRUE; if(UpdateSecondHand(dc,MidX,MidY,MidX*0.79,MidY*0.79,F)) Redraw = TRUE; DeleteObject(SelectObject(dc,CreatePen(PS_SOLID,1,HandColor))); if(Redraw) { DrawSecondHand(dc); DrawMinuteHand(dc); DrawHourHand(dc); } DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN))); if(!idc) ReleaseDC(HWindow,dc); } LRESULT CALLBACK ProcessAppMsg(HWND wnd,UINT msg,WPARAM w,LPARAM l) { PAINTSTRUCT PaintInfo; HDC dc; switch(msg) { case WM_PAINT: if(GetUpdateRect(wnd,NULL,FALSE)) { dc=BeginPaint(wnd,&PaintInfo); DrawFace(dc); Idle(dc); EndPaint(wnd,&PaintInfo); } break; case WM_SIZE: MaxX = LOWORD(l); MaxY = HIWORD(l); break; case WM_DESTROY: PostQuitMessage (0); break; default: return DefWindowProc (wnd, msg, w, l); } return 0l; } WPARAM MessageLoop() { MSG msg; while(1) { Sleep(1); /* sleep 1 millisecond */ if(PeekMessage(&msg,0,0,0,PM_REMOVE)) { if(msg.message == WM_QUIT) return msg.wParam; TranslateMessage(&msg); DispatchMessage(&msg); } else Idle(NULL); } } int PASCAL WinMain (HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { WNDCLASS class; if(!prev) { class.style = CS_HREDRAW | CS_VREDRAW; class.lpfnWndProc = ProcessAppMsg; class.cbClsExtra = 0; class.cbWndExtra = 0; class.hInstance = inst; class.hIcon = 0; /* Draw my own icon */ class.hCursor = LoadCursor (0, IDC_ARROW); class.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1); class.lpszMenuName = 0; class.lpszClassName = AppName; } if (!RegisterClass (&class)) return -1; HWindow=CreateWindowEx(WS_EX_TOPMOST,AppName,WindowName,WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,WindowWidth,WindowHeight, 0,0,inst,0); memset(&OldSecond,0,sizeof(OldSecond)); memset(&OldMinute,0,sizeof(OldMinute)); memset(&OldHour,0,sizeof(OldHour)); MaxX = WindowWidth; MaxY = WindowHeight; ShowWindow (HWindow, show); UpdateWindow (HWindow); return MessageLoop(); }