首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

GDI+ 绘制模拟钟表(1)

GDI+ 绘制模拟钟表(1)

关键点:  窗口坐标(X轴向右,Y轴向下); 窗口角度逆时针; 关键函数DrawClock

    #if !defined(AFX_COLOCKSTATIC_H__619C9005_4652_45A8_BC24_801ECF6ED3EA__INCLUDED_)
    #define AFX_COLOCKSTATIC_H__619C9005_4652_45A8_BC24_801ECF6ED3EA__INCLUDED_
     
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // ColockStatic.h : header file
    //
     
    #pragma warning( push, 3 )
    #undef new
    #include <GdiPlus.h>
    #pragma comment(lib, "GdiPlus.lib")
    #pragma warning( pop )
     
    using namespace Gdiplus;
     
    /////////////////////////////////////////////////////////////////////////////
    // CColockStatic window
     
    class CColockStatic : public CStatic
    {
      
      // Construction
    public:
      CColockStatic();
      
      // Attributes
    protected:
      ULONG_PTR m_GdiPlusInitToken;
      BOOL m_bTimerStarted;
      Image *m_pImage;
      
      // Operations
    public:
      BOOL DrawClock(HDC hDC, LPRECT rcRect);
      
      // Overrides
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CColockStatic)
    protected:
      virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
      //}}AFX_VIRTUAL
      
      // Implementation
    public:
      virtual ~CColockStatic();
      
      // Generated message map functions
    protected:
      //{{AFX_MSG(CColockStatic)
      // NOTE - the ClassWizard will add and remove member functions here.
      //}}AFX_MSG
      
      DECLARE_MESSAGE_MAP()
    };
     
    /////////////////////////////////////////////////////////////////////////////
     
    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
     
    #endif // !defined(AFX_COLOCKSTATIC_H__619C9005_4652_45A8_BC24_801ECF6ED3EA__INCLUDED_)



    // ColockStatic.cpp : implementation file
    //
     
    #include "stdafx.h"
    #include "CoolClock.h"
    #include "ColockStatic.h"
    #include <math.h>
     
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
     
    /////////////////////////////////////////////////////////////////////////////
    // CColockStatic
     
    CColockStatic::CColockStatic()
    {
      //初始化GDI+
      GdiplusStartupInput input;
      GdiplusStartupOutput output;
      Status status = GdiplusStartup( &m_GdiPlusInitToken, &input, &output );
      VERIFY( status == Gdiplus::Ok );
      m_bTimerStarted = FALSE;
      m_pImage = NULL;
    }
     
    CColockStatic::~CColockStatic()
    {
      GdiplusShutdown( m_GdiPlusInitToken );
      if(m_pImage)
      {
        //delete m_pImage;
        m_pImage = NULL;
      }
    }
     
     
    BEGIN_MESSAGE_MAP(CColockStatic, CStatic)
    //{{AFX_MSG_MAP(CColockStatic)
    // NOTE - the ClassWizard will add and remove mapping macros here.
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
     
    /////////////////////////////////////////////////////////////////////////////
    // CColockStatic message handlers
     
    BOOL CColockStatic:rawClock(HDC hDC, LPRECT lpRect)
    {
      CRect rcDraw = lpRect;
      
      //CRect rcClock = rcRect;
      //中心点
      CPoint ptCent = rcDraw.CenterPoint();
      
      Graphics graphics(hDC);
      //抗锯齿
      graphics.SetSmoothingMode(SmoothingModeHighQuality);
      
      //填充背景色
      {
        SolidBrush bkBrush(Color(255, 255, 255));        
        graphics.FillRectangle(&bkBrush, 0, 0, rcDraw.Width(), rcDraw.Height());
      }
      
      //背景图片
      {
        if(m_pImage == NULL)
        {
          m_pImage = Image::FromFile(L"Debug\\024.jpg");      
        }
        
        if(m_pImage != NULL)
        {
          float fWidth = (float)m_pImage->GetWidth();
          float fHight = (float)m_pImage->GetHeight();
         
          float alpha = 0.6f; //0~1 0透明1不透明
          ColorMatrix colorMartrix=
          {
            1,0,0,0,0,
            0,1,0,0,0,
            0,0,1,0,0,
            0,0,0,alpha,0,
            0,0,0,0,1
          };
          ImageAttributes imageAttr;
          imageAttr.SetColorMatrix(&colorMartrix);
         
          RectF rect((float)rcDraw.left, (float)rcDraw.top,
            (float)rcDraw.Width(), (float)rcDraw.Height());
          graphics.DrawImage(m_pImage, rect, 0, 0, fWidth, fHight, UnitPixel, &imageAttr);
         
        }
      }
      
      //取矩形区域
      int iMinSize = min(rcDraw.Width(), rcDraw.Height());
      int iMaxSize = max(rcDraw.Width(), rcDraw.Height());
      
      //atan(1) = π/4
      static double fPi = 4.0*atan(1.0);
      
      //画时表盘刻度 & 字体
      {
        int nWidth, nHeight;
        //nWidth = rcDraw.Width(), nHeight = rcDraw.Height(); //按椭圆处理
        nWidth = nHeight = iMinSize; //按圆处理
        
        int iERadioA = nWidth/2-6; //最外圆
        int iERadioB = nHeight/2-6;
        int iLHRadioA = iERadioA - 40; //长时刻度
        int iLHRadioB = iERadioB - 40;
        int iSHRadioA = iERadioA - 25; //短时刻度
        int iSHRadioB = iERadioB - 25;
        int iMRadioA  = iERadioA - 10; //分刻度
        int iMRadioB  = iERadioB - 10;
        int iTxRadioA = iLHRadioA - 20; //字体
        int iTxRadioB = iLHRadioB - 20;
        
        Pen LHPen(Color(255, 0, 0), 8.0f);
        Pen SHPen(Color(200, 0, 0), 4.0f);
        Pen SMpen(Color(0,0,0), 2.0f);
        
        double fAngle = fPi/2, fDAngle = 2.0*fPi/60.0;
        for(int i=0; i<60; i++)
        {
          BOOL bHour = i%5 == 0;
          BOOL bLHong = (i%15) == 0;
          int iIRadioA = bHour? (bLHong? iLHRadioA:iSHRadioA):iMRadioA;
          int iIRadioB = bHour? (bLHong? iLHRadioB:iSHRadioB):iMRadioB;
         
          Point s, e;
          s.X = ptCent.x + (int)(iERadioA * cos(fAngle));
          s.Y = ptCent.y - (int)(iERadioB * sin(fAngle));
          e.X = ptCent.x + (int)(iIRadioA * cos(fAngle));
          e.Y = ptCent.y - (int)(iIRadioB * sin(fAngle));
         
          Pen *plinePen = bHour? (bLHong? &LHPen:&SHPen):&SMpen;
          graphics.DrawLine(plinePen, s, e);
         
          if(bHour /*bLHong */) //写时间
          {
            Font tFont(L"Microsoft Sans Serif", 24);
            StringFormat sf;
            int iHour = 12 + (i+1)/5;
            if(iHour > 12) iHour -= 12;
            WCHAR wchBuff[16];
            swprintf_s(wchBuff, L"%d", iHour);
            
            RectF rectLayer(0,0, 1000, -1), txBound;
            graphics.MeasureString(wchBuff, -1, &tFont, rectLayer, &sf, &txBound);
            
            RectF ts = txBound;
            ts.X = (float)(ptCent.x + iTxRadioA*cos(fAngle) - txBound.Width/2);
            ts.Y = (float)(ptCent.y - iTxRadioB*sin(fAngle) - txBound.Height/2);
            
            SolidBrush txbrush(Color(0,0,0));
            graphics.DrawString(wchBuff, -1, &tFont, ts, &sf,
              &txbrush);
          }
         
          fAngle -= fDAngle;
        }
      }
返回列表