有关vc++ 时钟程序的学习与体会

本文记录了作者在学习VC++时钟程序过程中的理解和体会,重点讨论了映射模式如何实现时针、分针、秒针的摆动显示,以及定时器和窗口信息的保存与恢复。程序通过设置自定义映射模式MM_ISOTROPIC,利用三角函数计算针尖坐标,并通过定时器更新时钟显示。此外,还涉及了注册表存储窗口信息的方法。
摘要由CSDN通过智能技术生成

最近在学习一个时钟显示程序,觉得其中有好多值得细细体会、分析的地方。为了记住这些精妙之处,我把自己的这些理解和体会一并写在这个博客里,以备自己以后查询,也希望给正在学习这个程序的网友一个参考。

先上这个程序的运行效果图:

一、映射模式与时钟的“时针”、“分针”和“秒针”的摆动显示

时钟运行显示时间时,时、分和秒针在程序代码中摆动时,程序代码是如何绘制才符合时钟显示的运行规律的呢?这部分代码,是我学习这个程序时最让我难以理解的地方。程序中绘制时、分、秒针摆动的代码主要涉及两个函数:

1、绘制时针、分针的函数:

void CMainWindow::DrawHand (CDC* pDC, int nLength, int nScale,int nDegrees, COLORREF clrColor)

2、绘制秒针的函数:

void CMainWindow::DrawSecondHand (CDC* pDC, int nLength, int nScale,int nDegrees, COLORREF clrColor)

两个函数都需要解决以下几个问题:

1、时、分、秒针本身(外观形状)如何绘制?

2、怎样根据当时的时间(时、分、秒)把时针、分针和秒针绘制并指向对应时间点上呢?

经过仔细思考分析,我终于理解到了其中的思路:

首先,解决绘图的坐标系和绘图映射模式问题。

由于时钟显示时,钟的针是以圆心为轴,顺时针方向旋转摆动显示的。为了计算方便,有必要把坐标原点确定在时钟圆盘的中心,坐标系也要调整成x轴向右为正,y轴向上为正的模式。要实现这个目的,涉及到vc++绘图映射模式的设置。以下是代码实现:

    

	CRect rect;
	GetClientRect(&rect);
	CClientDC dc(this);
	dc.SetMapMode(MM_ISOTROPIC);
	dc.SetWindowExt(1000, 1000);
	dc.SetViewportExt(rect.Width(), -rect.Height());
	dc.SetViewportOrg(rect.Width() / 2, rect.Height() / 2);

由于使用了MM_ISOTROPIC自定义映射模式, 它使得在横、纵两个方向的缩放比例相同。就是不管窗口的水平、垂直两个方向的长度如何变化,程序总是会自动调整并按短的一边(水平和垂直短的一边)为准显示,保持横、纵比例相同。

程序中把显示的逻辑窗口设置为(1000,1000)的区域,与之对应的视窗区域却是(rect.Width(),-rect.Height())。尽管窗口的水平和垂直两个方向的长度可能不同,由于映射模式为MM_ISOTROPIC模式,所以程序会自动调整显示。由于还设置了视窗中心为新的坐标原点(dc.SetViewportOrg(rect.Width() / 2, rect.Height() / 2);),所以,(1000,1000)的逻辑区域总是会被显示到视窗区域的中心部分——一个正方形的区域,以短的一边(水平方向或垂直方向短的一边)为边长。看看下面程序运行的几种效果图即可知道了:

需要强调说明的是:SetViewportExt ()第二个参数为负值,因此逻辑坐标系在视窗显示时,相当于:原点位于视窗中心上,x轴向右为正,y轴向上为正。如下图所示:

明白这一点很重要,后面时钟的针的绘制显示才能正确理解。

 其次,解决时钟的时、分和秒针的指向摆动问题。

时针一圈分12个小时,有12个刻度,每摆动一个刻度,角度为360/12=30度;

分钟一圈分60分,有60个刻度,每摆动一个刻度,角度为360/60=6度;

秒针一圈分60秒,有60个刻度,每摆动一个刻度,角度为360/60=6度。

摆动角度的规律很明显,但如何绘制一定时间对应的时针、分针和秒针呢?这里当然要用到“三角函数”了。不过且慢,三角函数中使用的角,是以x轴正方向为起始沿逆时针或顺时针旋转而成,而在本程序中,时钟针的起点以y轴正方向为起始,沿顺时针方向而成。假设以y轴正方向为起始,沿顺时针方向旋转的角度为a,针尖所在点为A,从原点到针A点的长度为r。则A点的坐标:(r*cos(a),r*sin(a))是完全不正确的,因为它不是我们平常所用的三角函数的那种角度,起始边不一样。怎么办呢?看下图:

 由上图可知:不管角度a位于哪一个象限,都可以相当于:--a这个以x轴正方向开始的,沿顺时针方向形成的角的三角函数值,根据三角函数公式,即可推出A点坐标为(sin(a),cos(a))。(以上坐标是 r 假设为1的值,程序中r实际为450)这样,时针分针秒针的针尖点的坐标就根据角度得到了。代码实现为

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值