关键点: 窗口坐标(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;
}
} |