C++实现指针式时钟Sample

前言

《指针式时钟》问题分析,功能分析

(1)正确显示系统时钟;

(2)能准确定位时钟刻度和时分秒针的位置;

(3)能随窗口大小的变化而变化。

源码下载链接,本文Sample源码下载地址:C++实现指针式时钟Sample_c++指针式时钟-C++代码类资源-CSDN下载

一、效果图

Sample制作的时钟显示效果如下图所示:

二、部分代码

关键注意查看OnDraw函数内的时钟描画过程

// ClockView.cpp : implementation of the CClockView class
//

#include "stdafx.h"
#include "Clock.h"

#include "ClockDoc.h"
#include "ClockView.h"
#include "math.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CClockView

IMPLEMENT_DYNCREATE(CClockView, CView)

BEGIN_MESSAGE_MAP(CClockView, CView)
//{{AFX_MSG_MAP(CClockView)
// NOTE - the ClassWizard will add and remove mapping macros here.
//    DO NOT EDIT what you see in these blocks of generated code!
//}}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)
ON_WM_CREATE()
ON_WM_TIMER()
END_MESSAGE_MAP()

/
// CClockView construction/destruction

CClockView::CClockView()
{
// TODO: add construction code here

}

CClockView::~CClockView()
{
}

int CClockView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO:  在此添加您专用的创建代码
SetTimer(1,1000,NULL);//设置定时器1

return 0;
}

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)
{
CClockDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here

CPen pen(PS_SOLID,5,RGB(255,255,0));
CPen *pOldPen=(CPen*)pDC -> SelectObject(&pen);
static const double pi=3.1415926535;

//得到客户区的矩形
CRect rect;
GetClientRect(&rect);

//得到表盘中央位置,即圆心
int x0 = rect.Width() / 2;
int y0 = rect.Height() / 2;

//得到半径
int r = (x0 > y0 ? y0 : x0);

r = r - 5;

pDC->Ellipse(CRect(x0-r,y0-r,x0+r,y0+r));//画最外侧的圆
CPen Pen2(PS_SOLID,3,RGB(255,0,0));
pDC -> SelectObject(Pen2);
//将要在循环中重复的计算提取出来,减少时间复杂度
//在看代码时请将下列算式代入比较容易理解
double rate = (double)(2.0 * pi / 60.0);
double halfPi=pi/2;
int zoomR=r-20;

//绘制表盘
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(255,0,0));
for(int mark=1;mark<=60;mark++)
{
int positionX = (int)(zoomR * sin(rate * mark)+ x0);
int positionY = (int)(-zoomR * sin(rate * mark + halfPi)+ y0);
if(mark % 5 ==0)
{
char number[2];
itoa(mark/5,number,10);//按照十进制转换

//绘制数值
pDC -> TextOut(positionX-5,positionY-5,number);
}
}

CTime time = CTime::GetCurrentTime();
int hour = time.GetHour();
int minute = time.GetMinute();
int second = time.GetSecond();

//绘制秒数指针
CPen secondPen(PS_SOLID,2,RGB(117,254,254));
pDC -> SelectObject(secondPen);
pDC -> MoveTo(CPoint(x0,y0));
int secondX = (int)((zoomR-25) * sin(rate * second)+ x0);
int secondY = (int)(-(zoomR-25) * sin(rate * second + halfPi)+ y0);
pDC -> LineTo(CPoint(secondX,secondY));

//绘制分钟指针
CPen minutePen(PS_SOLID,4,RGB(0,0,255));
pDC -> SelectObject(minutePen);
pDC -> MoveTo(CPoint(x0,y0));
int minuteX = (int)((zoomR-70) * sin(rate * minute)+ x0);
int minuteY = (int)(-(zoomR-70) * sin(rate * minute + halfPi)+ y0);
pDC -> LineTo(CPoint(minuteX,minuteY));

//绘制小时指针/
double hourRate=(double)(2.0*pi/12.0);
if(hour > 12)
{
hour -= 12;
}
CPen hourPen(PS_SOLID,8,RGB(0,255,0));
pDC -> SelectObject(hourPen);
pDC -> MoveTo(CPoint(x0,y0));
int hourX = (int)((zoomR-120) * sin(hourRate * hour )+ x0);
int hourY = (int)(-(zoomR-120) * sin(hourRate * hour + halfPi)+ y0);
pDC -> LineTo(CPoint(hourX,hourY));
}

/
// 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

void CClockView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if(nIDEvent==1)
Invalidate();

CView::OnTimer(nIDEvent);
}


 

程序清单 按以下步骤向视图类(CClockView)添加下列数据成员及成员函数。 (1) 添加表示年、月、日、时、分、秒的变量。 int year; int month; int day; int hour; int minute; int second; (2) 添加秒表的计数变量。 int watch; (3) 添加时钟的画笔及画刷变量。 CPen m_HouPen, m_MinPen, m_SecPen; // 各种针的画笔 CBrush m_MarkBrush; // 表盘标记的画刷 (4) 添加时钟控制变量。 CPoint m_Center; // 表的中心 double m_Radius; // 表的半径 CPoint m_Hour [2], m_OldHour [2]; // 时针当前及前一次位置 CPoint m_Minute [2], m_OldMin [2]; // 分针当前及前一次位置 CPoint m_Second [2], m_OldSec [2]; // 秒针当前及前一次位置 (5) 添加秒表的两个按钮位置变量。 CRect m_WatchStart; CRect m_WatchStop; (6) 添加两个函数,计算时钟各指针位置。 void SetClock (int hour, int minute, int second); CPoint GetPoint (int nLenth, int nValue); (7) 在视图类构造函数中增加初始化语句: CClockView::~CClockView() { //设定时间 year=2010; month=11; day=22; hour=0; minute=0; second=0; //设定画笔画刷 m_HouPen.CreatePen(PS_SOLID,5,RGB(255,0,0));//时针画笔 m_MinPen.CreatePen(PS_SOLID,3,RGB(0,0,250));//分针画笔 m_SecPen.CreatePen(PS_SOLID,1,RGB(0,0,0));//秒针画笔 m_MarkBrush.CreateSolidBrush(RGB(250,250,0)); //设定表芯位置 m_Center.x=222; m_Center.y=222; //设定时钟半径 m_Radius=222; //计算指针位置 SetClock(hour,minute,second); //设定秒表计数器及按钮位置 watch=0; m_WatchStart=CRect(480,310,560,340);//启动按钮 m_WatchStop=CRect(590,310,670,340);//停止按钮 } 编写指针位置函数SetClock和GETpOINT。 首先在ClockView.cpp文件头部下添加下面两行代码,以便进行数学计算。 #define PI 3.14159265258 #include"math.h" 然后添加下列代码: //计算个指针位置的函数 void CClockView::SetClock(int hour,int minute,int second) { hour=hour*5; hour=hour+minute/12; //保存时针原位置 m_OldHour[0]=m_Hour[0]; m_OldHour[1]=m_Hour[1];
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值