ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

clock.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:     ReactOS Timedate Control Panel
00003  * LICENSE:     GPL - See COPYING in the top level directory
00004  * FILE:        dll/cpl/timedate/clock.c
00005  * PURPOSE:     Draws the analog clock
00006  * COPYRIGHT:   Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
00007  *              Copyright 2007 Eric Kohl
00008  */
00009 
00010 /* Code based on clock.c from Programming Windows, Charles Petzold */
00011 
00012 #include <timedate.h>
00013 
00014 typedef struct _CLOCKDATA
00015 {
00016     HBRUSH hGreyBrush;
00017     HPEN hGreyPen;
00018     INT cxClient;
00019     INT cyClient;
00020     SYSTEMTIME stCurrent;
00021     SYSTEMTIME stPrevious;
00022     BOOL bTimer;
00023 } CLOCKDATA, *PCLOCKDATA;
00024 
00025 
00026 #define TWOPI (2 * 3.14159)
00027 
00028 static const WCHAR szClockWndClass[] = L"ClockWndClass";
00029 
00030 static VOID
00031 RotatePoint(POINT pt[], INT iNum, INT iAngle)
00032 {
00033      INT i;
00034      POINT ptTemp;
00035 
00036      for (i = 0 ; i < iNum ; i++)
00037      {
00038           ptTemp.x = (INT) (pt[i].x * cos (TWOPI * iAngle / 360) +
00039                pt[i].y * sin (TWOPI * iAngle / 360));
00040 
00041           ptTemp.y = (INT) (pt[i].y * cos (TWOPI * iAngle / 360) -
00042                pt[i].x * sin (TWOPI * iAngle / 360));
00043 
00044           pt[i] = ptTemp;
00045      }
00046 }
00047 
00048 
00049 static INT
00050 DrawClock(HDC hdc, PCLOCKDATA pClockData)
00051 {
00052      INT iAngle,Radius;
00053      POINT pt[3];
00054      HBRUSH hBrushOld;
00055      HPEN hPenOld = NULL;
00056 
00057      /* Grey brush to fill the dots */
00058      hBrushOld = SelectObject(hdc, pClockData->hGreyBrush);
00059 
00060      hPenOld = GetCurrentObject(hdc, OBJ_PEN);
00061 
00062      // TODO: Check if this conversion is correct resp. usable
00063      Radius = min(pClockData->cxClient,pClockData->cyClient) * 2;
00064 
00065      for (iAngle = 0; iAngle < 360; iAngle += 6)
00066      {
00067           /* Starting coords */
00068           pt[0].x = 0;
00069           pt[0].y = Radius;
00070 
00071           /* Rotate start coords */
00072           RotatePoint(pt, 1, iAngle);
00073 
00074           /* Determine whether it's a big dot or a little dot
00075            * i.e. 1-4 or 5, 6-9 or 10, 11-14 or 15 */
00076           if (iAngle % 5)
00077           {
00078                 pt[2].x = pt[2].y = 7;
00079                 SelectObject(hdc, pClockData->hGreyPen);
00080           }
00081           else
00082           {
00083               pt[2].x = pt[2].y = 16;
00084               SelectObject(hdc, GetStockObject(BLACK_PEN));
00085           }
00086 
00087           pt[0].x -= pt[2].x / 2;
00088           pt[0].y -= pt[2].y / 2;
00089 
00090           pt[1].x  = pt[0].x + pt[2].x;
00091           pt[1].y  = pt[0].y + pt[2].y;
00092 
00093           Ellipse(hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y);
00094      }
00095 
00096      SelectObject(hdc, hBrushOld);
00097      SelectObject(hdc, hPenOld);
00098      return Radius;
00099 }
00100 
00101 
00102 static VOID
00103 DrawHands(HDC hdc, SYSTEMTIME * pst, BOOL fChange, INT Radius)
00104 {
00105      POINT pt[3][5] = { {{0, (INT)-Radius/6}, {(INT)Radius/9, 0}, 
00106          {0, (INT)Radius/1.8}, {(INT)-Radius/9, 0}, {0, (INT)-Radius/6}},
00107      {{0, (INT)-Radius/4.5}, {(INT)Radius/18, 0}, {0, (INT) Radius*0.89}, 
00108          {(INT)-Radius/18, 0}, {0, (INT)-Radius/4.5}},
00109      {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, (INT) Radius*0.89}} };
00110      INT i, iAngle[3];
00111      POINT ptTemp[3][5];
00112 
00113      /* Black pen for outline, white brush for fill */
00114      SelectObject(hdc, GetStockObject(BLACK_PEN));
00115      SelectObject(hdc, GetStockObject(WHITE_BRUSH));
00116 
00117      iAngle[0] = (pst->wHour * 30) % 360 + pst->wMinute / 2;
00118      iAngle[1] = pst->wMinute * 6;
00119      iAngle[2] = pst->wSecond * 6;
00120 
00121      CopyMemory(ptTemp, pt, sizeof(pt));
00122 
00123      for (i = fChange ? 0 : 2; i < 3; i++)
00124      {
00125           RotatePoint(ptTemp[i], 5, iAngle[i]);
00126 
00127           Polygon(hdc, ptTemp[i], 5);
00128      }
00129 }
00130 
00131 
00132 static LRESULT CALLBACK
00133 ClockWndProc(HWND hwnd,
00134              UINT uMsg,
00135              WPARAM wParam,
00136              LPARAM lParam)
00137 {
00138     PCLOCKDATA pClockData;
00139     HDC hdc, hdcMem;
00140     PAINTSTRUCT ps;
00141 
00142     pClockData = (PCLOCKDATA)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
00143 
00144     switch (uMsg)
00145     {
00146         case WM_CREATE:
00147             pClockData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLOCKDATA));
00148             SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR)pClockData);
00149 
00150             pClockData->hGreyPen = CreatePen(PS_SOLID, 1, RGB(128, 128, 128));
00151             pClockData->hGreyBrush = CreateSolidBrush(RGB(128, 128, 128));
00152 
00153             SetTimer(hwnd, ID_TIMER, 1000, NULL);
00154             pClockData->bTimer = TRUE;
00155             GetLocalTime(&pClockData->stCurrent);
00156             pClockData->stPrevious = pClockData->stCurrent;
00157             break;
00158 
00159         case WM_SIZE:
00160             pClockData->cxClient = LOWORD(lParam);
00161             pClockData->cyClient = HIWORD(lParam);
00162             break;
00163 
00164         case WM_TIMER:
00165             GetLocalTime(&pClockData->stCurrent);
00166             InvalidateRect(hwnd, NULL, FALSE);
00167             pClockData->stPrevious = pClockData->stCurrent;
00168             break;
00169 
00170         case WM_PAINT:
00171             hdc = BeginPaint(hwnd, &ps);
00172 
00173             hdcMem = CreateCompatibleDC(hdc);
00174             if (hdcMem)
00175             {
00176                 HBITMAP hBmp, hBmpOld;
00177 
00178                 hBmp = CreateCompatibleBitmap(hdc,
00179                                               pClockData->cxClient,
00180                                               pClockData->cyClient);
00181                 if (hBmp)
00182                 {
00183                     HBRUSH hWinBrush, hWinBrushOld;
00184                     INT oldMap, Radius;
00185                     POINT oldOrg;
00186 
00187                     hBmpOld = SelectObject(hdcMem, hBmp);
00188 
00189                     hWinBrush = GetSysColorBrush(COLOR_BTNFACE);
00190                     hWinBrushOld = SelectObject(hdcMem, hWinBrush);
00191                     PatBlt(hdcMem,
00192                            0,
00193                            0,
00194                            pClockData->cxClient,
00195                            pClockData->cyClient,
00196                            PATCOPY);
00197 
00198                     oldMap = SetMapMode(hdcMem, MM_ISOTROPIC);
00199                     SetWindowExtEx(hdcMem, 3600, 2700, NULL);
00200                     SetViewportExtEx(hdcMem, 800, -600, NULL);
00201                     SetViewportOrgEx(hdcMem,
00202                                      pClockData->cxClient / 2,
00203                                      pClockData->cyClient / 2,
00204                                      &oldOrg);
00205 
00206                     Radius = DrawClock(hdcMem, pClockData);
00207                     DrawHands(hdcMem, &pClockData->stPrevious, TRUE, Radius);
00208 
00209                     SetMapMode(hdcMem, oldMap);
00210                     SetViewportOrgEx(hdcMem, oldOrg.x, oldOrg.y, NULL);
00211 
00212                     BitBlt(hdc,
00213                            0,
00214                            0,
00215                            pClockData->cxClient,
00216                            pClockData->cyClient,
00217                            hdcMem,
00218                            0,
00219                            0,
00220                            SRCCOPY);
00221 
00222                     SelectObject(hdcMem, hWinBrushOld);
00223                     SelectObject(hdcMem, hBmpOld);
00224                     DeleteObject(hBmp);
00225                 }
00226 
00227                 DeleteDC(hdcMem);
00228             }
00229 
00230             EndPaint(hwnd, &ps);
00231             break;
00232 
00233         case WM_DESTROY:
00234             DeleteObject(pClockData->hGreyPen);
00235             DeleteObject(pClockData->hGreyBrush);
00236 
00237             if (pClockData->bTimer)
00238                 KillTimer(hwnd, ID_TIMER);
00239 
00240             HeapFree(GetProcessHeap(), 0, pClockData);
00241             break;
00242 
00243         case CLM_STOPCLOCK:
00244             if (pClockData->bTimer)
00245             {
00246                 KillTimer(hwnd, ID_TIMER);
00247                 pClockData->bTimer = FALSE;
00248             }
00249             break;
00250 
00251         case CLM_STARTCLOCK:
00252             if (!pClockData->bTimer)
00253             {
00254                 SetTimer(hwnd, ID_TIMER, 1000, NULL);
00255                 pClockData->bTimer = TRUE;
00256             }
00257             break;
00258 
00259         default:
00260             DefWindowProcW(hwnd,
00261                            uMsg,
00262                            wParam,
00263                            lParam);
00264     }
00265 
00266     return TRUE;
00267 }
00268 
00269 
00270 BOOL
00271 RegisterClockControl(VOID)
00272 {
00273     WNDCLASSEXW wc = {0};
00274 
00275     wc.cbSize = sizeof(WNDCLASSEXW);
00276     wc.lpfnWndProc = ClockWndProc;
00277     wc.hInstance = hApplet;
00278     wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
00279     wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
00280     wc.lpszClassName = szClockWndClass;
00281 
00282     return RegisterClassExW(&wc) != (ATOM)0;
00283 }
00284 
00285 
00286 VOID
00287 UnregisterClockControl(VOID)
00288 {
00289     UnregisterClassW(szClockWndClass,
00290                      hApplet);
00291 }

Generated on Thu May 24 2012 04:21:24 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.