Author: ekohl Date: Sat May 12 16:37:23 2007 New Revision: 26720
URL: http://svn.reactos.org/svn/reactos?rev=26720&view=rev Log: - Attach clock specific data to the window instead of storing them in global variables. - Stop the clock and show the system time when the user changes the system time.
See issue #2241 for more details.
Modified: trunk/reactos/dll/cpl/timedate/clock.c trunk/reactos/dll/cpl/timedate/dateandtime.c trunk/reactos/dll/cpl/timedate/timedate.h
Modified: trunk/reactos/dll/cpl/timedate/clock.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/timedate/clock.c?re... ============================================================================== --- trunk/reactos/dll/cpl/timedate/clock.c (original) +++ trunk/reactos/dll/cpl/timedate/clock.c Sat May 12 16:37:23 2007 @@ -1,31 +1,42 @@ /* * PROJECT: ReactOS Timedate Control Panel * LICENSE: GPL - See COPYING in the top level directory - * FILE: lib/cpl/timedate/clock.c + * FILE: dll/cpl/timedate/clock.c * PURPOSE: Draws the analog clock * COPYRIGHT: Copyright 2006 Ged Murphy gedmurphy@gmail.com - * + * Copyright 2007 Eric Kohl */
/* Code based on clock.c from Programming Windows, Charles Petzold */
#include <timedate.h>
+typedef struct _CLOCKDATA +{ + HBRUSH hGreyBrush; + HPEN hGreyPen; + INT cxClient; + INT cyClient; + SYSTEMTIME stCurrent; + SYSTEMTIME stPrevious; + BOOL bTimer; +} CLOCKDATA, *PCLOCKDATA; + + #define TWOPI (2 * 3.14159)
static const TCHAR szClockWndClass[] = TEXT("ClockWndClass");
-static HBRUSH hGreyBrush = NULL; -static HPEN hGreyPen = NULL; - -static VOID -SetIsotropic(HDC hdc, INT cxClient, INT cyClient) + +static VOID +SetIsotropic(HDC hdc, PCLOCKDATA pClockData) { /* set isotropic mode */ SetMapMode(hdc, MM_ISOTROPIC); /* position axis in centre of window */ - SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL); -} + SetViewportOrgEx(hdc, pClockData->cxClient / 2, pClockData->cyClient / 2, NULL); +} +
static VOID RotatePoint(POINT pt[], INT iNum, INT iAngle) @@ -45,20 +56,21 @@ } }
-static VOID -DrawClock(HDC hdc) -{ - INT iAngle; + +static VOID +DrawClock(HDC hdc, PCLOCKDATA pClockData) +{ + INT iAngle; POINT pt[3]; HBRUSH hBrushOld; HPEN hPenOld = NULL;
/* grey brush to fill the dots */ - hBrushOld = SelectObject(hdc, hGreyBrush); + hBrushOld = SelectObject(hdc, pClockData->hGreyBrush);
hPenOld = GetCurrentObject(hdc, OBJ_PEN);
- for(iAngle = 0; iAngle < 360; iAngle += 6) + for (iAngle = 0; iAngle < 360; iAngle += 6) { /* starting coords */ pt[0].x = 0; @@ -72,7 +84,7 @@ if (iAngle % 5) { pt[2].x = pt[2].y = 7; - SelectObject(hdc, hGreyPen); + SelectObject(hdc, pClockData->hGreyPen); } else { @@ -87,12 +99,12 @@ pt[1].y = pt[0].y + pt[2].y;
Ellipse(hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y); - }
SelectObject(hdc, hBrushOld); SelectObject(hdc, hPenOld); } +
static VOID DrawHands(HDC hdc, SYSTEMTIME * pst, BOOL fChange) @@ -108,12 +120,12 @@ SelectObject(hdc, GetStockObject(WHITE_BRUSH));
iAngle[0] = (pst->wHour * 30) % 360 + pst->wMinute / 2; - iAngle[1] = pst->wMinute * 6; - iAngle[2] = pst->wSecond * 6; + iAngle[1] = pst->wMinute * 6; + iAngle[2] = pst->wSecond * 6;
CopyMemory(ptTemp, pt, sizeof(pt));
- for(i = fChange ? 0 : 2; i < 3; i++) + for (i = fChange ? 0 : 2; i < 3; i++) { RotatePoint(ptTemp[i], 5, iAngle[i]);
@@ -128,62 +140,70 @@ WPARAM wParam, LPARAM lParam) { - - static INT cxClient, cyClient; - static SYSTEMTIME stPrevious; + PCLOCKDATA pClockData; HDC hdc; PAINTSTRUCT ps; - SYSTEMTIME st; + + pClockData = (PCLOCKDATA)GetWindowLongPtr(hwnd, GWLP_USERDATA);
switch (uMsg) { case WM_CREATE: - { - hGreyPen = CreatePen(PS_SOLID, 1, RGB(128, 128, 128)); - hGreyBrush = CreateSolidBrush(RGB(128, 128, 128)); + pClockData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLOCKDATA)); + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pClockData); + + pClockData->hGreyPen = CreatePen(PS_SOLID, 1, RGB(128, 128, 128)); + pClockData->hGreyBrush = CreateSolidBrush(RGB(128, 128, 128)); + SetTimer(hwnd, ID_TIMER, 1000, NULL); - GetLocalTime(&st); - stPrevious = st; - } - break; + pClockData->bTimer = TRUE; + GetLocalTime(&pClockData->stCurrent); + pClockData->stPrevious = pClockData->stCurrent; + break;
case WM_SIZE: - { - cxClient = LOWORD(lParam); - cyClient = HIWORD(lParam); - } - break; + pClockData->cxClient = LOWORD(lParam); + pClockData->cyClient = HIWORD(lParam); + break;
case WM_TIMER: - { - GetLocalTime(&st); - + GetLocalTime(&pClockData->stCurrent); InvalidateRect(hwnd, NULL, TRUE); - - stPrevious = st; - } - break; + pClockData->stPrevious = pClockData->stCurrent; + break;
case WM_PAINT: - { hdc = BeginPaint(hwnd, &ps); - - SetIsotropic(hdc, cxClient, cyClient); - - DrawClock(hdc); - DrawHands(hdc, &stPrevious, TRUE); - + SetIsotropic(hdc, pClockData); + DrawClock(hdc, pClockData); + DrawHands(hdc, &pClockData->stPrevious, TRUE); EndPaint(hwnd, &ps); - } - break; + break;
case WM_DESTROY: - { - DeleteObject(hGreyPen); - DeleteObject(hGreyBrush); - KillTimer(hwnd, ID_TIMER); - } - break; + DeleteObject(pClockData->hGreyPen); + DeleteObject(pClockData->hGreyBrush); + + if (pClockData->bTimer) + KillTimer(hwnd, ID_TIMER); + + HeapFree(GetProcessHeap(), 0, pClockData); + break; + + case CLM_SETTIME: + /* Stop the timer if it is still running */ + if (pClockData->bTimer) + { + KillTimer(hwnd, ID_TIMER); + pClockData->bTimer = FALSE; + } + + /* Set the current time */ + CopyMemory(&pClockData->stPrevious, (LPSYSTEMTIME)lParam, sizeof(SYSTEMTIME)); + + /* Redraw the clock */ + InvalidateRect(hwnd, NULL, TRUE); + break;
default: DefWindowProc(hwnd,
Modified: trunk/reactos/dll/cpl/timedate/dateandtime.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/timedate/dateandtim... ============================================================================== --- trunk/reactos/dll/cpl/timedate/dateandtime.c (original) +++ trunk/reactos/dll/cpl/timedate/dateandtime.c Sat May 12 16:37:23 2007 @@ -1,9 +1,9 @@ /* * PROJECT: ReactOS Timedate Control Panel * LICENSE: GPL - See COPYING in the top level directory - * FILE: lib/cpl/timedate/dateandtime.c + * FILE: dll/cpl/timedate/dateandtime.c * PURPOSE: Date & Time property page - * COPYRIGHT: Copyright 2004-2005 Eric Kohl + * COPYRIGHT: Copyright 2004-2007 Eric Kohl * Copyright 2006 Ged Murphy gedmurphy@gmail.com * Copyright 2006 Thomas Weidenmueller w3seek@reactos.com * @@ -361,8 +361,14 @@ { case DTN_DATETIMECHANGE: { + /* Stop the timer */ + KillTimer(hwndDlg, ID_TIMER); + + /* Tell the clock to stop ticking */ + SendDlgItemMessage(hwndDlg, IDC_CLOCKWND, CLM_SETTIME, + 0, (LPARAM)&((LPNMDATETIMECHANGE)lpnm)->st); + /* Enable the 'Apply' button */ - KillTimer(hwndDlg, ID_TIMER); PropSheet_Changed(GetParent(hwndDlg), hwndDlg); } break;
Modified: trunk/reactos/dll/cpl/timedate/timedate.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/timedate/timedate.h... ============================================================================== --- trunk/reactos/dll/cpl/timedate/timedate.h (original) +++ trunk/reactos/dll/cpl/timedate/timedate.h Sat May 12 16:37:23 2007 @@ -52,6 +52,8 @@
/* clock.c */ +#define CLM_SETTIME (WM_USER + 1) + BOOL RegisterClockControl(VOID); VOID UnregisterClockControl(VOID);