windows程序设计第八章计时器

模拟时钟,代码:

  1 /*--------------------------------------
  2    CLOCK.C -- Analog Clock Program
  3               (c) Charles Petzold, 1998
  4   --------------------------------------*/
  5 
  6 #include <windows.h>
  7 #include <math.h>
  8 
  9 #define ID_TIMER    1
 10 #define TWOPI       (2 * 3.14159)
 11 
 12 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
 13 
 14 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
 15                     PSTR szCmdLine, int iCmdShow)
 16 {
 17      static TCHAR szAppName[] = TEXT ("Clock") ;
 18      HWND         hwnd;
 19      MSG          msg;
 20      WNDCLASS     wndclass ;
 21      
 22      wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
 23      wndclass.lpfnWndProc   = WndProc ;
 24      wndclass.cbClsExtra    = 0 ;
 25      wndclass.cbWndExtra    = 0 ;
 26      wndclass.hInstance     = hInstance ;
 27      wndclass.hIcon         = NULL ;
 28      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
 29      wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
 30      wndclass.lpszMenuName  = NULL ;
 31      wndclass.lpszClassName = szAppName ;
 32      
 33      if (!RegisterClass (&wndclass))
 34      {
 35           MessageBox (NULL, TEXT ("Program requires Windows NT!"), 
 36                       szAppName, MB_ICONERROR) ;
 37           return 0 ;
 38      }
 39      
 40      hwnd = CreateWindow (szAppName, TEXT ("Analog Clock"),
 41                           WS_OVERLAPPEDWINDOW,
 42                           CW_USEDEFAULT, CW_USEDEFAULT,
 43                           CW_USEDEFAULT, CW_USEDEFAULT,
 44                           NULL, NULL, hInstance, NULL) ;
 45      
 46      ShowWindow (hwnd, iCmdShow) ;
 47      UpdateWindow (hwnd) ;
 48      
 49      while (GetMessage (&msg, NULL, 0, 0))
 50      {
 51           TranslateMessage (&msg) ;
 52           DispatchMessage (&msg) ;
 53      }
 54      return msg.wParam ;
 55 }
 56 
 57 void SetIsotropic (HDC hdc, int cxClient, int cyClient)
 58 {
 59      SetMapMode (hdc, MM_ISOTROPIC) ;
 60      SetWindowExtEx (hdc, 1000, 1000, NULL) ;
 61      SetViewportExtEx (hdc, cxClient / 2, -cyClient / 2, NULL) ;
 62      SetViewportOrgEx (hdc, cxClient / 2,  cyClient / 2, NULL) ;
 63 }
 64 
 65 void RotatePoint (POINT pt[], int iNum, int iAngle)
 66 {
 67      int   i ;
 68      POINT ptTemp ;
 69      
 70      for (i = 0 ; i < iNum ; i++)
 71      {
 72           ptTemp.x = (int) (pt[i].x * cos (TWOPI * iAngle / 360) +
 73                pt[i].y * sin (TWOPI * iAngle / 360)) ;
 74           
 75           ptTemp.y = (int) (pt[i].y * cos (TWOPI * iAngle / 360) -
 76                pt[i].x * sin (TWOPI * iAngle / 360)) ;
 77           
 78           pt[i] = ptTemp ;
 79      }
 80 }
 81 
 82 void DrawClock (HDC hdc)
 83 {
 84      int   iAngle ;
 85      POINT pt[3] ;
 86      
 87      for (iAngle = 0 ; iAngle < 360 ; iAngle += 6)
 88      {
 89           pt[0].x =   0 ;
 90           pt[0].y = 900 ;
 91           
 92           RotatePoint (pt, 1, iAngle) ;
 93           
 94           pt[2].x = pt[2].y = iAngle % 5 ? 33 : 100 ;
 95           
 96           pt[0].x -= pt[2].x / 2 ;
 97           pt[0].y -= pt[2].y / 2 ;
 98           
 99           pt[1].x  = pt[0].x + pt[2].x ;
100           pt[1].y  = pt[0].y + pt[2].y ;
101           
102           SelectObject (hdc, GetStockObject (BLACK_BRUSH)) ;
103           
104           Ellipse (hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y) ;
105      }
106 }
107 
108 void DrawHands (HDC hdc, SYSTEMTIME * pst, BOOL fChange)
109 {
110      static POINT pt[3][5] = { 0, -150, 100, 0, 0, 600, -100, 0, 0, -150,
111                                0, -200,  50, 0, 0, 800,  -50, 0, 0, -200,
112                                0,    0,   0, 0, 0,   0,    0, 0, 0,  800 } ;
113      int          i, iAngle[3] ;
114      POINT        ptTemp[3][5] ;
115      
116      iAngle[0] = (pst->wHour * 30) % 360 + pst->wMinute / 2 ;
117      iAngle[1] =  pst->wMinute  *  6 ;
118      iAngle[2] =  pst->wSecond  *  6 ;
119      
120      memcpy (ptTemp, pt, sizeof (pt)) ;
121      
122      for (i = fChange ? 0 : 2 ; i < 3 ; i++)
123      {
124           RotatePoint (ptTemp[i], 5, iAngle[i]) ;
125           
126           Polyline (hdc, ptTemp[i], 5) ;
127      }
128 }
129 
130 LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
131 {
132      static int        cxClient, cyClient ;
133      static SYSTEMTIME stPrevious ;
134      BOOL              fChange ;
135      HDC               hdc ;
136      PAINTSTRUCT       ps ;
137      SYSTEMTIME        st ;
138           
139      switch (message)
140      {
141      case WM_CREATE :
142           SetTimer (hwnd, ID_TIMER, 1000, NULL) ;
143           GetLocalTime (&st) ;
144           stPrevious = st ;
145           return 0 ;
146           
147      case WM_SIZE :
148           cxClient = LOWORD (lParam) ;
149           cyClient = HIWORD (lParam) ;
150           return 0 ;
151           
152      case WM_TIMER :
153           GetLocalTime (&st) ;
154                     
155           fChange = st.wHour   != stPrevious.wHour ||
156                     st.wMinute != stPrevious.wMinute ;
157           
158           hdc = GetDC (hwnd) ;
159           
160           SetIsotropic (hdc, cxClient, cyClient) ;
161           
162           SelectObject (hdc, GetStockObject (WHITE_PEN)) ;
163           DrawHands (hdc, &stPrevious, fChange) ;
164           
165           SelectObject (hdc, GetStockObject (BLACK_PEN)) ;
166           DrawHands (hdc, &st, TRUE) ;
167           
168           ReleaseDC (hwnd, hdc) ;
169           
170           stPrevious = st ;
171           return 0 ;
172           
173      case WM_PAINT :
174           hdc = BeginPaint (hwnd, &ps) ;
175           
176           SetIsotropic (hdc, cxClient, cyClient) ;
177           DrawClock    (hdc) ;
178           DrawHands    (hdc, &stPrevious, TRUE) ;
179           
180           EndPaint (hwnd, &ps) ;
181           return 0 ;
182           
183      case WM_DESTROY :
184           KillTimer (hwnd, ID_TIMER) ;
185           PostQuitMessage (0) ;
186           return 0 ;
187      }
188      return DefWindowProc (hwnd, message, wParam, lParam) ;
189 }

此时钟有一些瑕疵,比如分针、时针是每分钟动一下,看起来很突兀。

但是好多地方仍然值得学习。

比如将旋转一定角度的功能分离出来,然后应用到各个地方,使得问题顿时大为简化

现在还没学到怎么使用资源

所有的图形都要一点一点画上去

真是蛋疼……