mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
- 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. svn path=/trunk/; revision=26720
This commit is contained in:
parent
d5d68cf53f
commit
7e499053cd
3 changed files with 84 additions and 56 deletions
|
@ -1,32 +1,43 @@
|
|||
/*
|
||||
* 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)
|
||||
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 @@ RotatePoint(POINT pt[], INT iNum, INT iAngle)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
DrawClock(HDC hdc)
|
||||
DrawClock(HDC hdc, PCLOCKDATA pClockData)
|
||||
{
|
||||
INT iAngle;
|
||||
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 @@ DrawClock(HDC hdc)
|
|||
if (iAngle % 5)
|
||||
{
|
||||
pt[2].x = pt[2].y = 7;
|
||||
SelectObject(hdc, hGreyPen);
|
||||
SelectObject(hdc, pClockData->hGreyPen);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -87,13 +99,13 @@ DrawClock(HDC hdc)
|
|||
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 @@ DrawHands(HDC hdc, SYSTEMTIME * pst, BOOL fChange)
|
|||
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 @@ ClockWndProc(HWND hwnd,
|
|||
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,
|
||||
|
|
|
@ -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 @@ DateTimePageProc(HWND hwndDlg,
|
|||
{
|
||||
case DTN_DATETIMECHANGE:
|
||||
{
|
||||
/* Enable the 'Apply' button */
|
||||
/* 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 */
|
||||
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -52,6 +52,8 @@ VOID DisplayWin32Error(DWORD dwErrorCode);
|
|||
|
||||
|
||||
/* clock.c */
|
||||
#define CLM_SETTIME (WM_USER + 1)
|
||||
|
||||
BOOL RegisterClockControl(VOID);
|
||||
VOID UnregisterClockControl(VOID);
|
||||
|
||||
|
|
Loading…
Reference in a new issue