|  | /********************************************************************* | 
|  | *                                                                   * | 
|  | *  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'.                                * | 
|  | * | 
|  | * Copyright Jim Peterson | 
|  | * | 
|  | * This library is free software; you can redistribute it and/or | 
|  | * modify it under the terms of the GNU Lesser General Public | 
|  | * License as published by the Free Software Foundation; either | 
|  | * version 2.1 of the License, or (at your option) any later version. | 
|  | * | 
|  | * This library is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | * Lesser General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU Lesser General Public | 
|  | * License along with this library; if not, write to the Free Software | 
|  | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | 
|  | *********************************************************************/ | 
|  |  | 
|  | #include <math.h> | 
|  | #include <string.h> | 
|  | #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(); | 
|  | } |