Windows API写的clock程序

/*--------------------------------------
   CLOCK.C -- Analog Clock Program
              (c) Charles Petzold, 1998
  --------------------------------------*/

#include <windows.h>
#include <math.h>

#define ID_TIMER    1
#define TWOPI       (2 * 3.14159)

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("Clock") ;
     HWND         hwnd;
     MSG          msg;
     WNDCLASS     wndclass ;
     //定义窗口类型为当窗口在水平或垂直方向上变化时将重绘窗口
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  //指定窗口的过程函数,窗口的过程函数是回调函数
     wndclass.lpfnWndProc   = WndProc ;
  //类附加内存空间
     wndclass.cbClsExtra    = 0 ;
  //窗口附加内存空间
     wndclass.cbWndExtra    = 0 ;
  //指定包含窗口过程的车工女婿的实例句柄
     wndclass.hInstance     = hInstance ;
  //指定窗口类的图标句柄
     wndclass.hIcon         = NULL ;
  //指定窗口类的光标句柄
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  //指定窗口类的背景画刷句柄
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  //指定菜单资源的名字
     wndclass.lpszMenuName  = NULL ;
  //指定窗口类的名字
     wndclass.lpszClassName = szAppName ;
     //完成窗口类(WNDCLASS)后,需要调用RegisterClass函数才能对其进行注册,注册成功后,才可以创建该类型的窗口,注册函数原型:
     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("Program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
    
     hwnd = CreateWindow (
   //指定窗口类的名称
   szAppName,
   //指定窗口的名字
   TEXT ("Analog Clock"),
   //创建窗口的样式
         WS_OVERLAPPEDWINDOW,
   //窗口的左上角(x,y)坐标
         100, 100,
   //窗口的宽度,高度
         1000, 1000,
   //指定被创建的窗口的父窗口句柄
         NULL,
   //指定窗口菜单的句柄
   NULL,
   //指定窗口所属的应用程序的实例的句柄
   hInstance,
   //WM_CREATE消息的附加参数
   NULL
   ) ;
     //显示窗口
     ShowWindow (hwnd, iCmdShow) ;
  //更新窗口
     UpdateWindow (hwnd) ;
     //消息循环
     while (GetMessage (&msg, NULL, 0, 0))
     {
   //将虚拟一键消息转换为字符消息
          TranslateMessage (&msg) ;
    //分派一个消息到窗口句柄过程,有窗口过程函数对消息进行处理。
    //DispatchMessage实际是将消息回传给操作系统,有操作系统调用窗口过程函数对消息进行处理
          DispatchMessage (&msg) ;
     }
     return msg.wParam ;
}

void SetIsotropic (HDC hdc, int cxClient, int cyClient)
{
 /*
 The mapping mode defines the unit of measure used to convert logical units to device units
 MM_ISOTROPIC--one unit along the x-axis is equal to one unit along the y-axis
 */
     SetMapMode (hdc, MM_ISOTROPIC) ;
     /*
  SetWindowExtEx
 The SetWindowExtEx function sets the horizontal and
 vertical extents of the window for a device context by using the specified values.

BOOL SetWindowExtEx(
  HDC hdc,       // handle to device context
  int nXExtent,  // new horizontal window extent
  int nYExtent,  // new vertical window extent
  LPSIZE lpSize  // original window extent
);
  */
     SetWindowExtEx (hdc, 1000, 1000, NULL) ;
  /*
  The SetViewportExtEx function sets the horizontal and vertical extents of the viewport
  for a device context by using the specified values.
  */
     SetViewportExtEx (hdc, cxClient/ 2 ,-cyClient/ 2 , NULL) ;
  /*
  The SetViewportOrgEx function specifies which device point maps to the window origin (0,0).

BOOL SetViewportOrgEx(
  HDC hdc,        // handle to device context
  int X,          // new x-coordinate of viewport origin
  int Y,          // new y-coordinate of viewport origin
  LPPOINT lpPoint // original viewport origin
);  */
     SetViewportOrgEx (hdc, cxClient / 2,  cyClient / 2, NULL) ;
}
/*
       iNum个pt点阵饶逻辑原点旋转iAngle的角度
*/
void RotatePoint (POINT pt[], int iNum, int iAngle)
{
     int   i ;
     POINT ptTemp ;
    
     for (i = 0 ; i < iNum ; i++)
     {
          ptTemp.x = (int) (pt[i].x * cos (TWOPI * iAngle / 360) +
               pt[i].y * sin (TWOPI * iAngle / 360)) ;
         
          ptTemp.y = (int) (pt[i].y * cos (TWOPI * iAngle / 360) -
               pt[i].x * sin (TWOPI * iAngle / 360)) ;
         
          pt[i] = ptTemp ;
     }
}

void DrawClock (HDC hdc)
{
     int   iAngle ;
     POINT pt[3] ;
    
     for (iAngle = 0 ; iAngle < 360 ; iAngle += 6)
     {
          pt[0].x =   0 ;
          pt[0].y = 900 ;
         
          RotatePoint (pt, 1, iAngle) ;
         
          pt[2].x = pt[2].y = iAngle % 5 ? 33 : 100 ;
         
          pt[0].x -= pt[2].x / 2 ;
          pt[0].y -= pt[2].y / 2 ;
         
          pt[1].x  = pt[0].x + pt[2].x ;
          pt[1].y  = pt[0].y + pt[2].y ;
         
          SelectObject (hdc, GetStockObject (BLACK_BRUSH)) ;
         
          Ellipse (hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y) ;
     }
}

void DrawHands (HDC hdc, SYSTEMTIME * pst, BOOL fChange)
{
     static POINT pt[3][5] = { 0, -150, 100, 0, 0, 600, -100, 0, 0, -150,
                               0, -200,  50, 0, 0, 800,  -50, 0, 0, -200,
                               0,    0,   0, 0, 0,   0,    0, 0, 0,  800 } ;
     int          i, iAngle[3] ;
     POINT        ptTemp[3][5] ;
    
     iAngle[0] = (pst->wHour * 30) % 360 + pst->wMinute / 2 ;
     iAngle[1] =  pst->wMinute  *  6 ;
     iAngle[2] =  pst->wSecond  *  6 ;
    
     memcpy (ptTemp, pt, sizeof (pt)) ;
    
     for (i = fChange ? 0 : 2 ; i < 3 ; i++)
     {
          RotatePoint (ptTemp[i], 5, iAngle[i]) ;
         
          Polyline (hdc, ptTemp[i], 5) ;
     }
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     static int        cxClient, cyClient ;
     static SYSTEMTIME stPrevious ;
     BOOL              fChange ;
     HDC               hdc ;
     PAINTSTRUCT       ps ;
     SYSTEMTIME        st ;
         
     switch (message)
     {
     case WM_CREATE :
   /*
   If lpTimerFunc is NULL, the system posts a WM_TIMER message to the application queue.
   The hwnd member of the message's MSG structure contains the value of the hWnd parameter.
   */
          SetTimer (hwnd, ID_TIMER, 1000, NULL) ;
    /*
    This function retrieves the current local date and time.
    typedef struct _SYSTEMTIME {
    WORD wYear;
    WORD wMonth;
    WORD wDayOfWeek;
    WORD wDay;
    WORD wHour;
    WORD wMinute;
    WORD wSecond;
    WORD wMilliseconds;
   } SYSTEMTIME;
    */
          GetLocalTime (&st) ;
          stPrevious = st ;
          return 0 ;
         
     case WM_SIZE :
          cxClient = LOWORD (lParam) ;
          cyClient = HIWORD (lParam) ;
          return 0 ;
         
     case WM_TIMER :
          GetLocalTime (&st) ;
                   
          fChange = st.wHour   != stPrevious.wHour ||
                    st.wMinute != stPrevious.wMinute ;
         
          hdc = GetDC (hwnd) ;
         
          SetIsotropic (hdc, cxClient, cyClient) ;
         
          SelectObject (hdc, GetStockObject (WHITE_PEN)) ;
          DrawHands (hdc, &stPrevious, fChange) ;
         
          SelectObject (hdc, GetStockObject (BLACK_PEN)) ;
          DrawHands (hdc, &st, TRUE) ;
         
          ReleaseDC (hwnd, hdc) ;
         
          stPrevious = st ;
          return 0 ;
         
     case WM_PAINT :
          hdc = BeginPaint (hwnd, &ps) ;
         
          SetIsotropic (hdc, cxClient, cyClient) ;
          DrawClock    (hdc) ;
          DrawHands    (hdc, &stPrevious, TRUE) ;
         
          EndPaint (hwnd, &ps) ;
          return 0 ;
         
     case WM_DESTROY :
          KillTimer (hwnd, ID_TIMER) ;
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值