Avoid list corruption when linking window with HWND_BOTTOM (thanks to
[wine/multimedia.git] / libtest / rolex.c
blob4881600eda35a9f543509d643c32ff8c272e6f21
1 /*********************************************************************
2 * *
3 * rolex.c: Windows clock application for WINE (by Jim Peterson) *
4 * *
5 * This is a translation of a Turbo Pascal OWL application I made *
6 * once, so it's a little flaky (tons of globals, functions that *
7 * could have been in-lined, etc.). The source code should easily *
8 * compile with a standard Win32 C compiler. *
9 * *
10 * To try it out, type 'make rolex'. *
11 * *
12 *********************************************************************/
14 #include <math.h>
15 #include <string.h>
16 #include "windows.h"
18 char AppName[] = "Rolex";
19 char WindowName[] = "Rolex";
20 int WindowWidth = 100;
21 int WindowHeight = 121;
22 COLORREF FaceColor = RGB(192,192,192);
23 COLORREF HandColor = RGB(0,0,0);
24 COLORREF EtchColor = RGB(0,0,0);
26 float Pi=3.1415926;
28 typedef struct
30 int StartX,StartY,EndX,EndY;
31 } HandData;
33 int MaxX,MaxY;
34 HandData OldSecond,OldHour,OldMinute;
36 HWND HWindow;
38 void DrawFace(HDC dc)
40 int MidX, MidY, t;
42 MidX=MaxX/2;
43 MidY=MaxY/2;
44 SelectObject(dc,CreateSolidBrush(FaceColor));
45 SelectObject(dc,CreatePen(PS_SOLID,1,EtchColor));
46 Ellipse(dc,0,0,MaxX,MaxY);
48 for(t=0; t<12; t++)
50 MoveToEx(dc,MidX+sin(t*Pi/6)*0.9*MidX,MidY-cos(t*Pi/6)*0.9*MidY,NULL);
51 LineTo(dc,MidX+sin(t*Pi/6)*0.8*MidX,MidY-cos(t*Pi/6)*0.8*MidY);
53 if(MaxX>64 && MaxY>64)
54 for(t=0; t<60; t++)
55 SetPixel(dc,MidX+sin(t*Pi/30)*0.9*MidX,MidY-cos(t*Pi/30)*0.9*MidY
56 ,EtchColor);
57 DeleteObject(SelectObject(dc,GetStockObject(NULL_BRUSH)));
58 DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN)));
59 memset(&OldSecond,0,sizeof(OldSecond));
60 memset(&OldMinute,0,sizeof(OldMinute));
61 memset(&OldHour,0,sizeof(OldHour));
64 void DrawHourHand(HDC dc)
66 MoveToEx(dc, OldHour.StartX, OldHour.StartY, NULL);
67 LineTo(dc, OldHour.EndX, OldHour.EndY);
70 void DrawMinuteHand(HDC dc)
72 MoveToEx(dc, OldMinute.StartX, OldMinute.StartY, NULL);
73 LineTo(dc, OldMinute.EndX, OldMinute.EndY);
76 void DrawSecondHand(HDC dc)
78 MoveToEx(dc, OldSecond.StartX, OldSecond.StartY, NULL);
79 LineTo(dc, OldSecond.EndX, OldSecond.EndY);
82 BOOL UpdateHourHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos)
84 int Sx, Sy, Ex, Ey;
85 BOOL rv;
87 rv = FALSE;
88 Sx = MidX; Sy = MidY;
89 Ex = MidX+sin(Pos*Pi/6000)*XExt;
90 Ey = MidY-cos(Pos*Pi/6000)*YExt;
91 rv = ( Sx!=OldHour.StartX || Ex!=OldHour.EndX ||
92 Sy!=OldHour.StartY || Ey!=OldHour.EndY );
93 if(rv)DrawHourHand(dc);
94 OldHour.StartX = Sx; OldHour.EndX = Ex;
95 OldHour.StartY = Sy; OldHour.EndY = Ey;
96 return rv;
99 BOOL UpdateMinuteHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos)
101 int Sx, Sy, Ex, Ey;
102 BOOL rv;
104 rv = FALSE;
105 Sx = MidX; Sy = MidY;
106 Ex = MidX+sin(Pos*Pi/30000)*XExt;
107 Ey = MidY-cos(Pos*Pi/30000)*YExt;
108 rv = ( Sx!=OldMinute.StartX || Ex!=OldMinute.EndX ||
109 Sy!=OldMinute.StartY || Ey!=OldMinute.EndY );
110 if(rv)DrawMinuteHand(dc);
111 OldMinute.StartX = Sx; OldMinute.EndX = Ex;
112 OldMinute.StartY = Sy; OldMinute.EndY = Ey;
113 return rv;
116 BOOL UpdateSecondHand(HDC dc,int MidX,int MidY,int XExt,int YExt,WORD Pos)
118 int Sx, Sy, Ex, Ey;
119 BOOL rv;
121 rv = FALSE;
122 Sx = MidX; Sy = MidY;
123 Ex = MidX+sin(Pos*Pi/3000)*XExt;
124 Ey = MidY-cos(Pos*Pi/3000)*YExt;
125 rv = ( Sx!=OldSecond.StartX || Ex!=OldSecond.EndX ||
126 Sy!=OldSecond.StartY || Ey!=OldSecond.EndY );
127 if(rv)DrawSecondHand(dc);
128 OldSecond.StartX = Sx; OldSecond.EndX = Ex;
129 OldSecond.StartY = Sy; OldSecond.EndY = Ey;
130 return rv;
133 void Idle(HDC idc)
135 SYSTEMTIME st;
136 WORD H, M, S, F;
137 int MidX, MidY;
138 HDC dc;
139 BOOL Redraw;
141 if(idc)
142 dc=idc;
143 else
144 dc=GetDC(HWindow);
145 if(!dc)return;
147 GetLocalTime(&st);
148 H = st.wHour;
149 M = st.wMinute;
150 S = st.wSecond;
151 F = st.wMilliseconds / 10;
152 F = F + S*100;
153 M = M*1000+F/6;
154 H = H*1000+M/60;
155 MidX = MaxX/2;
156 MidY = MaxY/2;
157 SelectObject(dc,CreatePen(PS_SOLID,1,FaceColor));
158 Redraw = FALSE;
159 if(UpdateHourHand(dc,MidX,MidY,MidX*0.5,MidY*0.5,H)) Redraw = TRUE;
160 if(UpdateMinuteHand(dc,MidX,MidY,MidX*0.65,MidY*0.65,M)) Redraw = TRUE;
161 if(UpdateSecondHand(dc,MidX,MidY,MidX*0.79,MidY*0.79,F)) Redraw = TRUE;
162 DeleteObject(SelectObject(dc,CreatePen(PS_SOLID,1,HandColor)));
163 if(Redraw)
165 DrawSecondHand(dc);
166 DrawMinuteHand(dc);
167 DrawHourHand(dc);
169 DeleteObject(SelectObject(dc,GetStockObject(NULL_PEN)));
170 if(!idc) ReleaseDC(HWindow,dc);
173 LRESULT CALLBACK ProcessAppMsg(HWND wnd,UINT msg,WPARAM w,LPARAM l)
175 PAINTSTRUCT PaintInfo;
176 HDC dc;
178 switch(msg)
180 case WM_PAINT:
181 if(GetUpdateRect(wnd,NULL,FALSE))
183 dc=BeginPaint(wnd,&PaintInfo);
184 DrawFace(dc);
185 Idle(dc);
186 EndPaint(wnd,&PaintInfo);
188 break;
190 case WM_SIZE:
191 MaxX = LOWORD(l);
192 MaxY = HIWORD(l);
193 break;
195 case WM_DESTROY:
196 PostQuitMessage (0);
197 break;
199 default:
200 return DefWindowProc (wnd, msg, w, l);
202 return 0l;
205 WPARAM MessageLoop()
207 MSG msg;
209 while(1)
211 Sleep(1); /* sleep 1 millisecond */
212 if(PeekMessage(&msg,0,0,0,PM_REMOVE))
214 if(msg.message == WM_QUIT) return msg.wParam;
215 TranslateMessage(&msg);
216 DispatchMessage(&msg);
218 else
219 Idle(NULL);
223 int PASCAL WinMain (HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
225 WNDCLASS class;
226 if(!prev)
228 class.style = CS_HREDRAW | CS_VREDRAW;
229 class.lpfnWndProc = ProcessAppMsg;
230 class.cbClsExtra = 0;
231 class.cbWndExtra = 0;
232 class.hInstance = inst;
233 class.hIcon = 0; /* Draw my own icon */
234 class.hCursor = LoadCursor (0, IDC_ARROW);
235 class.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
236 class.lpszMenuName = 0;
237 class.lpszClassName = AppName;
239 if (!RegisterClass (&class)) return -1;
241 HWindow=CreateWindowEx(WS_EX_TOPMOST,AppName,WindowName,WS_OVERLAPPEDWINDOW,
242 CW_USEDEFAULT,CW_USEDEFAULT,WindowWidth,WindowHeight,
243 0,0,inst,0);
244 memset(&OldSecond,0,sizeof(OldSecond));
245 memset(&OldMinute,0,sizeof(OldMinute));
246 memset(&OldHour,0,sizeof(OldHour));
247 MaxX = WindowWidth;
248 MaxY = WindowHeight;
250 ShowWindow (HWindow, show);
251 UpdateWindow (HWindow);
253 return MessageLoop();