ReactOS  0.4.15-dev-1206-g731eddf
clock.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Timedate Control Panel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: dll/cpl/timedate/clock.c
5  * PURPOSE: Draws the analog clock
6  * COPYRIGHT: Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
7  * Copyright 2007 Eric Kohl
8  */
9 
10 /* Code based on clock.c from Programming Windows, Charles Petzold */
11 
12 #include "timedate.h"
13 
14 #include <math.h>
15 
16 typedef struct _CLOCKDATA
17 {
18  HBRUSH hGreyBrush;
19  HPEN hGreyPen;
26 
27 
28 #define TWOPI (2 * 3.14159)
29 
30 static const WCHAR szClockWndClass[] = L"ClockWndClass";
31 
32 static VOID
33 RotatePoint(POINT pt[], INT iNum, INT iAngle)
34 {
35  INT i;
36  POINT ptTemp;
37 
38  for (i = 0 ; i < iNum ; i++)
39  {
40  ptTemp.x = (INT) (pt[i].x * cos (TWOPI * iAngle / 360) +
41  pt[i].y * sin (TWOPI * iAngle / 360));
42 
43  ptTemp.y = (INT) (pt[i].y * cos (TWOPI * iAngle / 360) -
44  pt[i].x * sin (TWOPI * iAngle / 360));
45 
46  pt[i] = ptTemp;
47  }
48 }
49 
50 
51 static INT
53 {
54  INT iAngle,Radius;
55  POINT pt[3];
56  HBRUSH hBrushOld;
57  HPEN hPenOld = NULL;
58 
59  /* Grey brush to fill the dots */
60  hBrushOld = SelectObject(hdc, pClockData->hGreyBrush);
61 
62  hPenOld = GetCurrentObject(hdc, OBJ_PEN);
63 
64  // TODO: Check if this conversion is correct resp. usable
65  Radius = min(pClockData->cxClient,pClockData->cyClient) * 2;
66 
67  for (iAngle = 0; iAngle < 360; iAngle += 6)
68  {
69  /* Starting coords */
70  pt[0].x = 0;
71  pt[0].y = Radius;
72 
73  /* Rotate start coords */
74  RotatePoint(pt, 1, iAngle);
75 
76  /* Determine whether it's a big dot or a little dot
77  * i.e. 1-4 or 5, 6-9 or 10, 11-14 or 15 */
78  if (iAngle % 5)
79  {
80  pt[2].x = pt[2].y = 7;
81  SelectObject(hdc, pClockData->hGreyPen);
82  }
83  else
84  {
85  pt[2].x = pt[2].y = 16;
87  }
88 
89  pt[0].x -= pt[2].x / 2;
90  pt[0].y -= pt[2].y / 2;
91 
92  pt[1].x = pt[0].x + pt[2].x;
93  pt[1].y = pt[0].y + pt[2].y;
94 
95  Ellipse(hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y);
96  }
97 
98  SelectObject(hdc, hBrushOld);
99  SelectObject(hdc, hPenOld);
100  return Radius;
101 }
102 
103 
104 static VOID
105 DrawHands(HDC hdc, SYSTEMTIME * pst, BOOL fChange, INT Radius)
106 {
107  POINT pt[3][5] = { {{0, (INT)-Radius/6}, {(INT)Radius/9, 0},
108  {0, (INT)Radius/1.8}, {(INT)-Radius/9, 0}, {0, (INT)-Radius/6}},
109  {{0, (INT)-Radius/4.5}, {(INT)Radius/18, 0}, {0, (INT) Radius*0.89},
110  {(INT)-Radius/18, 0}, {0, (INT)-Radius/4.5}},
111  {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, (INT) Radius*0.89}} };
112  INT i, iAngle[3];
113  POINT ptTemp[3][5];
114 
115  /* Black pen for outline, white brush for fill */
118 
119  iAngle[0] = (pst->wHour * 30) % 360 + pst->wMinute / 2;
120  iAngle[1] = pst->wMinute * 6;
121  iAngle[2] = pst->wSecond * 6;
122 
123  CopyMemory(ptTemp, pt, sizeof(pt));
124 
125  for (i = fChange ? 0 : 2; i < 3; i++)
126  {
127  RotatePoint(ptTemp[i], 5, iAngle[i]);
128 
129  Polygon(hdc, ptTemp[i], 5);
130  }
131 }
132 
133 
134 static LRESULT CALLBACK
136  UINT uMsg,
137  WPARAM wParam,
138  LPARAM lParam)
139 {
140  PCLOCKDATA pClockData;
141  HDC hdc, hdcMem;
142  PAINTSTRUCT ps;
143 
145 
146  switch (uMsg)
147  {
148  case WM_CREATE:
149  pClockData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLOCKDATA));
151 
152  pClockData->hGreyPen = CreatePen(PS_SOLID, 1, RGB(128, 128, 128));
153  pClockData->hGreyBrush = CreateSolidBrush(RGB(128, 128, 128));
154 
155  SetTimer(hwnd, ID_TIMER, 1000, NULL);
156  pClockData->bTimer = TRUE;
157  GetLocalTime(&pClockData->stCurrent);
158  pClockData->stPrevious = pClockData->stCurrent;
159  break;
160 
161  case WM_SIZE:
162  pClockData->cxClient = LOWORD(lParam);
163  pClockData->cyClient = HIWORD(lParam);
164  break;
165 
166  case WM_TIMECHANGE:
167  case WM_TIMER:
168  GetLocalTime(&pClockData->stCurrent);
170  pClockData->stPrevious = pClockData->stCurrent;
171  break;
172 
173  case WM_PAINT:
174  hdc = BeginPaint(hwnd, &ps);
175 
177  if (hdcMem)
178  {
179  HBITMAP hBmp, hBmpOld;
180 
182  pClockData->cxClient,
183  pClockData->cyClient);
184  if (hBmp)
185  {
186  RECT rcParent;
187  HWND hParentWnd = GetParent(hwnd);
188  INT oldMap, Radius;
189  POINT oldOrg;
190 
191  hBmpOld = SelectObject(hdcMem, hBmp);
192 
193  SetRect(&rcParent, 0, 0, pClockData->cxClient, pClockData->cyClient);
194  MapWindowPoints(hwnd, hParentWnd, (POINT*)&rcParent, 2);
195  OffsetViewportOrgEx(hdcMem, -rcParent.left, -rcParent.top, &oldOrg);
197  SetViewportOrgEx(hdcMem, oldOrg.x, oldOrg.y, NULL);
198 
199  oldMap = SetMapMode(hdcMem, MM_ISOTROPIC);
200  SetWindowExtEx(hdcMem, 3600, 2700, NULL);
201  SetViewportExtEx(hdcMem, 800, -600, NULL);
203  pClockData->cxClient / 2,
204  pClockData->cyClient / 2,
205  &oldOrg);
206 
207  Radius = DrawClock(hdcMem, pClockData);
208  DrawHands(hdcMem, &pClockData->stPrevious, TRUE, Radius);
209 
210  SetMapMode(hdcMem, oldMap);
211  SetViewportOrgEx(hdcMem, oldOrg.x, oldOrg.y, NULL);
212 
213  BitBlt(hdc,
214  0,
215  0,
216  pClockData->cxClient,
217  pClockData->cyClient,
218  hdcMem,
219  0,
220  0,
221  SRCCOPY);
222 
223  SelectObject(hdcMem, hBmpOld);
224  DeleteObject(hBmp);
225  }
226 
227  DeleteDC(hdcMem);
228  }
229 
230  EndPaint(hwnd, &ps);
231  break;
232 
233  /* No need to erase background, handled during paint */
234  case WM_ERASEBKGND:
235  return 1;
236 
237  case WM_DESTROY:
238  DeleteObject(pClockData->hGreyPen);
239  DeleteObject(pClockData->hGreyBrush);
240 
241  if (pClockData->bTimer)
243 
244  HeapFree(GetProcessHeap(), 0, pClockData);
245  break;
246 
247  case CLM_STOPCLOCK:
248  if (pClockData->bTimer)
249  {
251  pClockData->bTimer = FALSE;
252  }
253  break;
254 
255  case CLM_STARTCLOCK:
256  if (!pClockData->bTimer)
257  {
258  SetTimer(hwnd, ID_TIMER, 1000, NULL);
259  pClockData->bTimer = TRUE;
260  }
261  break;
262 
263  default:
265  uMsg,
266  wParam,
267  lParam);
268  }
269 
270  return TRUE;
271 }
272 
273 
274 BOOL
276 {
277  WNDCLASSEXW wc = {0};
278 
279  wc.cbSize = sizeof(WNDCLASSEXW);
281  wc.hInstance = hApplet;
283  wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
285 
286  return RegisterClassExW(&wc) != (ATOM)0;
287 }
288 
289 
290 VOID
292 {
294  hApplet);
295 }
HGDIOBJ WINAPI GetStockObject(_In_ int)
#define MM_ISOTROPIC
Definition: wingdi.h:869
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
BOOL WINAPI SetViewportOrgEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
Definition: coord.c:655
SYSTEMTIME stPrevious
Definition: clock.c:23
HPEN WINAPI CreatePen(_In_ int, _In_ int, _In_ COLORREF)
BOOL WINAPI SetWindowExtEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPSIZE)
long y
Definition: polytest.cpp:48
int WINAPI MapWindowPoints(_In_opt_ HWND hWndFrom, _In_opt_ HWND hWndTo, _Inout_updates_(cPoints) LPPOINT lpPoints, _In_ UINT cPoints)
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
BOOL Polygon(CONST PPOINT UnsafePoints, int Count, int polyFillMode)
Definition: polytest.cpp:730
#define RGB(r, g, b)
Definition: precomp.h:62
long x
Definition: polytest.cpp:48
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
WORD ATOM
Definition: dimm.idl:113
static INT DrawClock(HDC hdc, PCLOCKDATA pClockData)
Definition: clock.c:52
#define TRUE
Definition: types.h:120
#define pt(x, y)
Definition: drawing.c:79
struct _CLOCKDATA * PCLOCKDATA
#define INT
Definition: polytest.cpp:20
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:35
BOOL WINAPI OffsetViewportOrgEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
Definition: coord.c:858
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1499
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define WHITE_BRUSH
Definition: wingdi.h:901
HINSTANCE hApplet
Definition: access.c:17
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
UINT_PTR WPARAM
Definition: windef.h:207
#define TWOPI
Definition: clock.c:28
struct _WNDCLASSEXW WNDCLASSEXW
#define GetWindowLongPtrW
Definition: winuser.h:4804
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
int32_t INT
Definition: typedefs.h:58
WPARAM wParam
Definition: combotst.c:138
SYSTEMTIME stCurrent
Definition: clock.c:22
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define OBJ_PEN
Definition: objidl.idl:1409
ATOM WINAPI RegisterClassExW(_In_ CONST WNDCLASSEXW *)
INT cyClient
Definition: clock.c:21
#define PS_SOLID
Definition: wingdi.h:585
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
int WINAPI SetMapMode(_In_ HDC, _In_ int)
HBRUSH hGreyBrush
Definition: clock.c:18
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
#define GWLP_USERDATA
Definition: treelist.c:63
static VOID RotatePoint(POINT pt[], INT iNum, INT iAngle)
Definition: clock.c:33
WORD wMinute
Definition: winbase.h:888
_STLP_DECLSPEC complex< float > _STLP_CALL cos(const complex< float > &)
smooth NULL
Definition: ftsmooth.c:416
HPEN hGreyPen
Definition: clock.c:19
LONG_PTR LPARAM
Definition: windef.h:208
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:286
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
LPCWSTR lpszClassName
Definition: winuser.h:3201
#define WM_DESTROY
Definition: winuser.h:1591
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
VOID UnregisterClockControl(VOID)
Definition: clock.c:291
#define PRF_ERASEBKGND
Definition: winuser.h:2501
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define WM_SIZE
Definition: winuser.h:1593
HBRUSH hbrBackground
Definition: winuser.h:3199
UINT cbSize
Definition: winuser.h:3191
#define WM_TIMER
Definition: winuser.h:1724
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
#define CopyMemory
Definition: winbase.h:1646
static VOID DrawHands(HDC hdc, SYSTEMTIME *pst, BOOL fChange, INT Radius)
Definition: clock.c:105
INT cxClient
Definition: clock.c:20
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2074
BOOL bTimer
Definition: clock.c:24
#define WM_PRINT
Definition: winuser.h:1862
HINSTANCE hInstance
Definition: winuser.h:3196
WORD wSecond
Definition: winbase.h:889
#define WM_PAINT
Definition: winuser.h:1602
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
static const WCHAR L[]
Definition: oid.c:1250
HDC hdc
Definition: main.c:9
#define COLOR_BTNFACE
Definition: winuser.h:918
#define ID_TIMER
Definition: resource.h:23
HCURSOR hCursor
Definition: winuser.h:3198
WNDPROC lpfnWndProc
Definition: winuser.h:3193
HWND WINAPI GetParent(_In_ HWND)
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
BOOL WINAPI DeleteDC(_In_ HDC)
struct _CLOCKDATA CLOCKDATA
BOOL WINAPI Ellipse(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
#define BLACK_PEN
Definition: wingdi.h:902
WORD wHour
Definition: winbase.h:887
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
static const WCHAR szClockWndClass[]
Definition: clock.c:30
#define IDC_ARROW
Definition: winuser.h:682
static LRESULT CALLBACK ClockWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: clock.c:135
#define SendMessage
Definition: winuser.h:5818
#define WM_CREATE
Definition: winuser.h:1590
#define HIWORD(l)
Definition: typedefs.h:247
#define CLM_STOPCLOCK
Definition: timedate.h:73
#define SetWindowLongPtrW
Definition: winuser.h:5321
static HBITMAP
Definition: button.c:44
_STLP_DECLSPEC complex< float > _STLP_CALL sin(const complex< float > &)
#define CLM_STARTCLOCK
Definition: timedate.h:74
#define WM_ERASEBKGND
Definition: winuser.h:1607
BOOL WINAPI SetViewportExtEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPSIZE)
Definition: coord.c:465
#define PRF_CLIENT
Definition: winuser.h:2500
LONG_PTR LRESULT
Definition: windef.h:209
BOOL RegisterClockControl(VOID)
Definition: clock.c:275
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
#define HeapFree(x, y, z)
Definition: compat.h:594
#define SRCCOPY
Definition: wingdi.h:332
HGDIOBJ WINAPI GetCurrentObject(_In_ HDC, _In_ UINT)
Definition: dc.c:441
HDC hdcMem
Definition: welcome.c:104
static VOID NTAPI BitBlt(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_reads_bytes_(Delta *Height) PUCHAR Buffer, _In_ ULONG BitsPerPixel, _In_ ULONG Delta)
Definition: common.c:49
#define WM_TIMECHANGE
Definition: winuser.h:1616