用GDI+旋转多边形来绘制一个时钟摸拟小程序

打印 上一主题 下一主题

主题 831|帖子 831|积分 2493

效果图

 
在头文件类中声明变量
  1. TCHAR m_dayStr[4];    // 日期
  2.     TCHAR m_weekStr[4];  // 星期
  3.     Gdiplus::Font* m_pFont;  // 字体
  4.     Gdiplus::StringFormat m_strFormat;  // 格式化字符串
  5.     Gdiplus::Pen* m_pPen;      // 画笔
  6.     Gdiplus::SolidBrush* m_pBrush;  // 画刷
  7.     Gdiplus::RectF m_dayRect;      // 日期矩形
  8.     Gdiplus::RectF m_weekRect;      // 星期矩形
  9.     Gdiplus::PointF m_orgPointF; // 圆点坐标
  10.     float m_rColok;    //圆半径<br><br>
复制代码
  Gdiplus:ointF hourPts[4];  //时针多边形数组
          Gdiplus:ointF mimPts[4];    //分针多边形数组
          Gdiplus:ointF scrPts[2];    //秒针数组
  1.  
复制代码
 
在初始化函数中初始变量的值
  1. // 获得系统时间
  2. SYSTEMTIME sysTime;
  3. GetLocalTime(&sysTime);
  4. // 格式化日期和星期字符串
  5. _stprintf_s(m_dayStr,TEXT("%02d"),sysTime.wDay);
  6. TCHAR weekStrs[7][4]={L"日",L"一",L"二",L"三",L"四",L"五",L"六"};
  7. _stprintf_s(m_weekStr,TEXT("%s"),weekStrs[sysTime.wDayOfWeek]);
  8. // 启动时间计时器
  9. SetTimer(m_hWnd,11,1000,NULL);
复制代码
在WM_SIZE中盘算圆点,半径,多边形分针,时针,秒针的极点坐标数组值
  1. float cx=LOWORD(lParam);
  2.     float cy=HIWORD(lParam);
  3.         // 计算圆点
  4.     m_orgPointF.X=cx/2;
  5.     m_orgPointF.Y=cy/2;
  6.         
  7.         // 计算半径
  8.     m_rColok=min(cx,cy)/2;
  9.     m_rColok-=10;
  10.     float r=m_rColok;
  11.    
  12.         // 秒针数组赋值
  13.     scrPts[0].X=0;
  14.     scrPts[0].Y=-r*9/10;
  15.     scrPts[1].X=0;
  16.     scrPts[1].Y=r*2/10;
  17.     // 分针多边形坐标数组
  18.     mimPts[0].X=(float)(-r*0.7 / 10);
  19.     mimPts[0].Y=0;
  20.     mimPts[1].X=0;
  21.     mimPts[1].Y=-r * 8/ 10;
  22.     mimPts[2].X=(float)(r*0.7 / 10);
  23.     mimPts[2].Y=0;
  24.     mimPts[3].X=0;
  25.     mimPts[3].Y=r * 2/ 10;
  26.     // 时针多边形数组
  27.     hourPts[0].X=-r / 10;
  28.     hourPts[0].Y=0;
  29.     hourPts[1].X=0;
  30.     hourPts[1].Y=-r * 6/ 10;
  31.     hourPts[2].X=r / 10;
  32.     hourPts[2].Y=0;
  33.     hourPts[3].X=0;
  34.     hourPts[3].Y=r * 2/ 10;
  35.         // 日期矩形
  36.     m_dayRect.X=r-16;
  37.     m_dayRect.Y=-10;
  38.     m_dayRect.Width=20;
  39.     m_dayRect.Height=20;
  40.         // 日期矩形
  41.     m_weekRect.X=r-36;
  42.     m_weekRect.Y=-10;
  43.     m_weekRect.Width=20;
  44.     m_weekRect.Height=20;   
复制代码
 
 
用旋转图片来绘制多边形,
图片旋转是以圆点为中央来旋转的,
所以要重新设置坐标系圆点为表盘中央点
自界说函数RotatePolygon来盘算多边形的旋转,和绘制
  1. // 旋转多边形,并绘制<br>// (绘制对象,多边形顶点坐标数组,顶点个数,旋转角度)<br>void RotatePolygon(Gdiplus::Graphics* graphics, Gdiplus::PointF* points, int numPoints, float angle) {
  2.     // 创建旋转矩阵
  3.     Gdiplus::Matrix matrix;
  4.     matrix.Rotate(angle);
  5.     // 旋转多边形的每个点
  6.     Gdiplus::PointF* rotatedPoints = new Gdiplus::PointF[numPoints];
  7.     for (int i = 0; i < numPoints; i++) {
  8.         Gdiplus::PointF point = points[i];
  9.         matrix.TransformPoints(&point, 1);
  10.         rotatedPoints[i] = point;
  11.     }
  12.     Gdiplus::Pen pen(Color(255,0,0,0),(numPoints==2) ? 2.0f:1.0f);
  13.     // 绘制旋转后的多边形
  14.     graphics->DrawPolygon(&pen, rotatedPoints, numPoints);<br>  <br>  <br>  // 用线性渐变画刷填充多边形
  15.     graphics->FillPolygon(&Gdiplus::LinearGradientBrush(rotatedPoints[0],rotatedPoints[2],
  16.         Color(255,0,0,255),Color(255,255,255,0)),rotatedPoints,numPoints);
  17.     delete[] rotatedPoints;
  18. }
复制代码
最后在WM_PAINT消息中绘制
  1. void MyMainWnd::OnPaint(){
  2.     PAINTSTRUCT ps;
  3.     HDC hdc=BeginPaint(m_hWnd,&ps);
  4.     // 创建内存dc,创建内存位图,并将内存位图选入内存dc中
  5.     HDC hmdc=CreateCompatibleDC(hdc);;
  6.     HBITMAP hBitmap=CreateCompatibleBitmap(hdc,ps.rcPaint.right,ps.rcPaint.bottom);
  7.     HGDIOBJ hOldMap=SelectObject(hmdc,hBitmap);
  8.     // 创建在内存dc中绘图对象
  9.     Gdiplus::Graphics g(hmdc);
  10.     g.SetSmoothingMode(SmoothingModeAntiAlias); //设置抗锯齿模式
  11.    
  12.     // 用指定颜色填充整个内存位图
  13.     m_pBrush->SetColor(Color(255,128,128,129));
  14.     g.FillRectangle(m_pBrush,0,0,ps.rcPaint.right,ps.rcPaint.bottom);
  15.     // 设置新的坐标系原点为表盘中心点
  16.     Gdiplus::Matrix transform;
  17.     transform.Translate(m_orgPointF.X, m_orgPointF.Y);
  18.     g.SetTransform(&transform);
  19.     float xBegin,yBegin;
  20.     float rClock=m_rColok; // 圆的半径
  21.     // 用指定颜色的画刷,绘制表盘上的刻度
  22.     m_pBrush->SetColor(Color(255,217,222,18));
  23.     for(int i=0;i<60;i++)
  24.     {
  25.         xBegin = (float)( rClock * sin(2 * PI*i / 60));
  26.         yBegin = (float)(rClock * cos(2 * PI*i / 60));
  27.         if (i % 5)
  28.         {
  29.             // 填充小圆点表示小刻度
  30.             g.FillEllipse(m_pBrush,xBegin-2,yBegin-2,4.0f,4.0f);
  31.         }
  32.         else
  33.         {
  34.             // 填充大圆点表示大刻度
  35.             g.FillEllipse(m_pBrush,xBegin-4,yBegin-4,8.0f,8.0f);
  36.         }
  37.     }
  38.     //获取系统时间
  39.     SYSTEMTIME x;
  40.     GetLocalTime(&x);
  41.     // 绘制显示日期和星期的矩形区域
  42.     m_pPen->SetColor(Color::Black);
  43.     m_pBrush->SetColor(Color::YellowGreen);
  44.     g.DrawRectangle(m_pPen,m_dayRect);
  45.     g.DrawRectangle(m_pPen,m_weekRect);
  46.     g.FillRectangle(m_pBrush,m_dayRect);
  47.     g.FillRectangle(m_pBrush,m_weekRect);
  48.     // 绘制日期和星期的字符串文本
  49.     m_pBrush->SetColor(Color::Black);
  50.     g.DrawString(m_dayStr,-1,m_pFont,m_dayRect,&m_strFormat,m_pBrush);
  51.     g.DrawString(m_weekStr,-1,m_pFont,PointF(m_weekRect.X+1,m_weekRect.Y+4),m_pBrush);
  52.     // 绘制时针
  53.     float tem=(float)((float)x.wMinute/60);
  54.     float fHour=x.wHour+tem;
  55.     float sita=float(fHour*30);
  56.     RotatePolygon(&g,hourPts,4,(float)sita); //计算时针旋转角度并绘制
  57.     // 绘制分针
  58.     sita=float(x.wMinute*6);
  59.     RotatePolygon(&g,mimPts,4,(float)sita);
  60.     // 绘制秒针
  61.     sita = float(x.wSecond*6);
  62.     RotatePolygon(&g,scrPts,2,sita);
  63.     // 绘制圆心
  64.     m_pBrush->SetColor(Color(255,0,0,255));
  65.     g.FillEllipse(m_pBrush,-6,-6,12,12);
  66.     // 将内存dc中绘制的图片复制到当前dc中
  67.     BitBlt(hdc,0,0,(int)ps.rcPaint.right,(int)ps.rcPaint.bottom,hmdc,0,0,SRCCOPY);
  68.     // 释放内存位图,内存dc
  69.     SelectObject(hmdc,hOldMap);
  70.     DeleteObject(hBitmap);
  71.     DeleteObject(hmdc);
  72.     EndPaint(m_hWnd,&ps);
  73. }
复制代码
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

写过一篇

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表