📄 clockview.cpp
字号:
// ClockView.cpp : implementation of the CClockView class
//
#include "stdafx.h"
#include "Clock.h"
#include "iostream.h"
// #include "string.h"
// #include "Afx.h"
#include "ClockDoc.h"
#include "ClockView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/* 颜色定义 */
#define RGB_RED RGB(255, 0, 0)
#define RGB_GREEN RGB(0, 255, 0)
#define RGB_BLUE RGB(0, 0, 255)
#define RGB_ORANGE RGB(255, 0, 255)
#define RGB_BLACK RGB(0, 0, 0)
#define BGColor 0xffff00
#define PI 3.1415926
/////////////////////////////////////////////////////////////////////////////
// CClockView
IMPLEMENT_DYNCREATE(CClockView, CView)
BEGIN_MESSAGE_MAP(CClockView, CView)
//{{AFX_MSG_MAP(CClockView)
ON_WM_CREATE()
ON_WM_TIMER()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CClockView construction/destruction
CClockView::CClockView()
{
// TODO: add construction code here
m_bTimeBitmap.LoadBitmap(IDB_BITMAP2);
}
CClockView::~CClockView()
{
}
BOOL CClockView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CClockView drawing
void CClockView::OnDraw(CDC* pDC)
{
CClientDC dc(this);
/* 获得窗体大小 */
CRect rect;
GetWindowRect(&rect);
int nWidth = rect.Width(); //1024
int nHeight= rect.Height(); //719
/* 计算钟表中心位置 */
CenterX = nWidth / 2; //512
CenterY = nHeight / 2; //359
/* 设置钟表半径为窗体宽度和高度的最小值的一半的90% */
ClockRadius = (int)(min(CenterX, CenterY) * 0.9); //323
/* 在内存中创建一个与屏幕绘图区域一致的对象 */
CDC MemDC;
CBitmap MemBitmap;
MemDC.CreateCompatibleDC(NULL);
MemBitmap.CreateCompatibleBitmap(&dc, nWidth, nHeight);
CBitmap *pOldBit = MemDC.SelectObject(&MemBitmap);
/* 创建5个画笔 */
CPen Pen_Hour, Pen_Minute, Pen_Second, Pen_Circle, Pen_Graduation;
/*指针画笔 */
Pen_Hour.CreatePen(PS_SOLID, (int)(ClockRadius * 0.06), RGB_BLUE);
Pen_Minute.CreatePen(PS_SOLID,(int)(ClockRadius * 0.04), RGB_GREEN);
Pen_Second.CreatePen(PS_SOLID,(int)(ClockRadius * 0.02), RGB_RED);
/*表盘画笔 */
Pen_Circle.CreatePen(PS_SOLID,(int)(ClockRadius * 0.05), RGB_ORANGE);
/*刻度画笔 */
Pen_Graduation.CreatePen(PS_SOLID, 1, RGB_BLACK);
/* 绘制钟表盘面 */
MemDC.SelectObject(&Pen_Circle);
MemDC.Ellipse(CenterX - ClockRadius, CenterY - ClockRadius, CenterX + ClockRadius, CenterY + ClockRadius);
/* 设置背景刷子类型。HS_DIAGCROSS:45度交叉阴影; BGColor:背景颜色*/
CBrush Bgbrush;
Bgbrush.CreateHatchBrush(HS_DIAGCROSS, BGColor);
/* 用背景刷子填充表盘背景 */
MemDC.SelectObject(&Bgbrush);
MemDC.FloodFill((int)(CenterX + ClockRadius + ClockRadius * 0.05) ,ClockRadius , RGB_ORANGE);
/* 设置整点的圆的刷子类型为实心红色 */
CBrush IntCircle;
IntCircle.CreateSolidBrush(RGB_RED);
/* 表盘上的刻度和数字绘制完成 */
for(int i = 1; i <= 60; i++)
{
if (i % 5 != 0) /* 非整点 */
{
/* 设置非整点时刻的旋转角度 */
double Radians = (double)i * 2 * PI / 60;
/* 设置非整点时刻的线段起始坐标 */
POINT StartPoint, EndPoint;
StartPoint.x = CenterX + (int)((double)ClockRadius * 0.85 * sin(Radians));
StartPoint.y = CenterY - (int)((double)ClockRadius * 0.85 * cos(Radians));
EndPoint.x = CenterX + (int)((double)ClockRadius * 0.9 * sin(Radians));
EndPoint.y = CenterY - (int)((double)ClockRadius * 0.9 * cos(Radians));
/* 绘制非整点时刻的线段 */
MemDC.SelectObject(&Pen_Graduation);
MemDC.MoveTo(StartPoint);
MemDC.LineTo(EndPoint);
}
else /* 整点 */
{
/* 格式化整点时刻对应的数字 */
CString str;
str.Format("%d", i / 5);
/* 获得整点时刻对应的数字的尺寸 */
CSize Textsize = MemDC.GetTextExtent(str,str.GetLength());
/* 设置整点时刻旋转角度 */
double Radians = (double)i / 5 * 2 * PI / 12;
/* 计算整点时刻对应的数字和红色圆点的坐标 */
POINT IntNumPoint,IntCirclePoint;
IntNumPoint.x = CenterX - (Textsize.cx / 2) + (int)((double)ClockRadius * 0.9 * sin(Radians));
IntNumPoint.y = CenterY - (Textsize.cy / 2) - (int)((double)ClockRadius * 0.9 * cos(Radians));
IntCirclePoint.x = CenterX + (int)((double)ClockRadius * 0.85 * sin(Radians));
IntCirclePoint.y = CenterY - (int)((double)ClockRadius * 0.85 * cos(Radians));
/* 计算整点时刻对应的红色圆点的半径 */
double IntCircleClockRadius;
IntCircleClockRadius = ClockRadius * 0.015;
/* 绘制整点时刻对应的数字和红色圆点 */
MemDC.SelectObject(&Pen_Graduation);
MemDC.TextOut(IntNumPoint.x, IntNumPoint.y, str);
MemDC.SelectObject(&Pen_Second);
MemDC.SelectObject(&IntCircle);
MemDC.Ellipse((int)(IntCirclePoint.x - IntCircleClockRadius),(int)(IntCirclePoint.y - IntCircleClockRadius),(int)(IntCirclePoint.x + IntCircleClockRadius),(int)(IntCirclePoint.y + IntCircleClockRadius));
}
}
/* 获得当前时间 */
CTime CurrentTime = CTime::GetCurrentTime();
/* 分离当前时间的时、分、秒 */
hour = CurrentTime.GetHour();
minute = CurrentTime.GetMinute();
second = CurrentTime.GetSecond();
/* 设置时、分、秒三个指针的旋转角度 */
double secondRadians, minuteRadians, hourRadians;
secondRadians = second * 2 * PI / 60;
minuteRadians = minute * 2 * PI / 60 + secondRadians / 60;
hourRadians = hour * 2 * PI / 12 + minuteRadians / 12 ;
/* 设置时、分、秒三个指针的起始坐标 */
POINT StartPoint, hourEndPoint, minuteEndPoint, secondEndPoint;
StartPoint.x = CenterX;
StartPoint.y = CenterY;
secondEndPoint.x = (long)(CenterX + ClockRadius * 0.9 * sin(secondRadians));
secondEndPoint.y = (long)(CenterY - ClockRadius * 0.9 * cos(secondRadians));
minuteEndPoint.x = (long)(CenterX + ClockRadius * 0.8 * sin(minuteRadians));
minuteEndPoint.y = (long)(CenterY - ClockRadius * 0.8 * cos(minuteRadians));
hourEndPoint.x = (long)(CenterX + ClockRadius * 0.7 * sin(hourRadians));
hourEndPoint.y = (long)(CenterY - ClockRadius * 0.7 * cos(hourRadians));
/* 设置指针绘制模式为复制画笔颜色 */
MemDC.SetROP2(R2_COPYPEN);
/* 绘制XUST */
CString Xust = "XUST";
CSize Textsize = MemDC.GetTextExtent(Xust, Xust.GetLength());
MemDC.TextOut((int)(CenterX - Textsize.cx / 2),(int) (CenterY + ClockRadius * 0.6), Xust);
/* 绘制时、分、秒三个指针 */
MemDC.SelectObject(&Pen_Hour);
MemDC.MoveTo(StartPoint);
MemDC.LineTo(hourEndPoint);
MemDC.SelectObject(&Pen_Minute);
MemDC.MoveTo(StartPoint);
MemDC.LineTo(minuteEndPoint);
MemDC.SelectObject(&Pen_Second);
MemDC.MoveTo(StartPoint);
MemDC.LineTo(secondEndPoint);
/* 绘制中心红色圆点 */
MemDC.SelectObject(&Pen_Second);
MemDC.SelectObject(&IntCircle);
MemDC.Ellipse((int)(CenterX - ClockRadius * 0.03),(int)(CenterY - ClockRadius * 0.03),(int)(CenterX + ClockRadius * 0.03),(int)(CenterY + ClockRadius * 0.03));
/*绘制数字时钟*/
DrawNumber((CPaintDC &) MemDC);
/* 将内存中绘制的图像复制到当前设备 */
dc.BitBlt(0, 0, nWidth, nHeight, &MemDC, 0, 0, SRCCOPY);
/* 销毁对象 */
MemBitmap.DeleteObject();
MemDC.DeleteDC();
}
/////////////////////////////////////////////////////////////////////////////
// CClockView printing
BOOL CClockView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CClockView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CClockView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CClockView diagnostics
#ifdef _DEBUG
void CClockView::AssertValid() const
{
CView::AssertValid();
}
void CClockView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CClockDoc* CClockView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CClockDoc)));
return (CClockDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CClockView message handlers
int CClockView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
/* 设置定时器为1000毫秒调用一次 */
SetTimer(1,1000 , NULL);
return 0;
}
void CClockView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
/* 刷新窗口 */
Invalidate();
//InvalidateRect(NULL,true);
// UpdateWindow();
CView::OnTimer(nIDEvent);
}
BOOL CClockView::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void CClockView::DrawNumber(CPaintDC &dc)
{
/*绘制数字时钟*/
int numX,numY;
numX = (int)(CenterX * 1.4);
numY = (int)(CenterY * 1.8);
CDC dcMemory;
dcMemory.CreateCompatibleDC(&dc);
dcMemory.SelectObject(m_bTimeBitmap);
dc.StretchBlt(numX,numY,13,23,&dcMemory,0,23*(11-hour / 10),13,23,SRCCOPY);
dc.StretchBlt(numX+13,numY,13,23,&dcMemory,0,23*(11-(hour-(hour / 10) * 10)),13,23,SRCCOPY);
dc.StretchBlt(numX+13*2,numY,13,23,&dcMemory,0,23,13,23,SRCCOPY);
dc.StretchBlt(numX+13*3,numY,13,23,&dcMemory,0,23*(11-minute / 10),13,23,SRCCOPY);
dc.StretchBlt(numX+13*4,numY,13,23,&dcMemory,0,23*(11-(minute-(minute / 10)*10)),13,23,SRCCOPY);
dc.StretchBlt(numX+13*5,numY,13,23,&dcMemory,0,13,13,23,SRCCOPY);
dc.StretchBlt(numX+13*6,numY,13,23,&dcMemory,0,23*(11-second / 10),13,23,SRCCOPY);
dc.StretchBlt(numX+13*7,numY,13,23,&dcMemory,0,23*(11-(second-(second / 10)*10)),13,23,SRCCOPY);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -