c++模拟时钟实验报告.docx

上传人:b****3 文档编号:3884131 上传时间:2022-11-26 格式:DOCX 页数:27 大小:175.38KB
下载 相关 举报
c++模拟时钟实验报告.docx_第1页
第1页 / 共27页
c++模拟时钟实验报告.docx_第2页
第2页 / 共27页
c++模拟时钟实验报告.docx_第3页
第3页 / 共27页
c++模拟时钟实验报告.docx_第4页
第4页 / 共27页
c++模拟时钟实验报告.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

c++模拟时钟实验报告.docx

《c++模拟时钟实验报告.docx》由会员分享,可在线阅读,更多相关《c++模拟时钟实验报告.docx(27页珍藏版)》请在冰豆网上搜索。

c++模拟时钟实验报告.docx

c++模拟时钟实验报告

 

集中上机实习报告

 

 

指导教师:

王利

姓名:

赵蕊

学号:

2010211864

班级:

0411003

时间:

2012.5

模拟时钟程序

一.需求分析

1.题目内容:

编写一个模拟时钟程序,此程序在屏幕左方有一指针式钟面,右方有两个矩形框,上面以数字方式显示日期和时间,该时间应与指针显示的时间一致,下方的矩形框作为秒表。

用菜单选项或按钮设置时间和秒表。

时间不必与机器系统时间相同,只要可任意设置即可。

2.题目分析:

(1)模拟时钟是一种集计时器和时钟显示于一体的程序。

编写一个指针式时钟程序,此程序在屏幕左方有一个指针式钟面,右方有两个矩形框,上面以数字方式显示日期、星期和时间。

指针式的时钟表盘为圆形,并且圆周上有分布均匀的60个刻度,刻度要求显示清楚,钟面上有长度不相同的指针,即时针、分针、秒针,指针的运动要求具有规律性,且为顺时针。

数字钟显示时间的格式是年月日星期时分秒,小时为24进制,分钟和秒是60进制,指针式的时钟和数字式的时钟显示的时间同步。

按下时钟控制设置时间菜单项可弹出一对话框,用于设置当前的时间、日期和星期;按下秒表控制按钮后,秒表显示窗中显示从0开始的时间,单位为百分之一秒。

再次按下秒表控制按钮后计时停止,该窗口显示累计时间。

(2)本实验主要涉及到的知识点有:

时钟指针运动算法、屏幕重绘方法、定时器消息、鼠标消息、菜单命令、对话框、画笔/画刷、显示文字等。

指针运动算法和屏幕重绘方法是本程序主要难点所在。

3.最终效果如下图:

 

二.概要设计

1.程序系统模块划分

图1功能模块图

 

2.程序算法分析

本程序不论何种指针,每次转动均以π/30弧度(一秒的角度)为基本单位,且都以表盘中心为转动圆心。

计算指针端点(x,y)的公式如下:

x=圆心x坐标+指针长度*cos(指针方向角)

y=圆心y坐标+指针长度*sin(指针方向角)

指针长度是指自圆心至指针一个端点的长度,由于指针要跨越圆心,因此一个指针需要计算两个端点。

三个指针的运动是相关联的,秒针转一圈引起分针运动一格,分针每转12格引起时针运动一格,而因此应该使用一个定时器消息来处理指针的运动。

若用三个定时器消息分别处理时针、分针和秒针的运动,就会使问题复杂化且不易实现三个指针联动的正确规律。

采用一个定时器消息可以很容易实现指针联动算法。

由于屏幕的重绘速度快,如果采用全屏删除式重绘则闪烁十分明显,显示效果不佳。

本程序采用非删除式重绘,假定指针将要移动一格,则先采用表盘背景色(这里为浅绿色)重绘原来指针以删除原来位置的指针,再采用指针的颜色在当前位置绘制指针;如果指针没有动,则直接绘制指针。

另外,秒表需要采用单独的定时器消息控制,秒表重绘速度很快,屏幕闪烁明显,故本程序采用了双缓冲绘图。

 

3.系统流程图

三.详细设计

1.模块描述

(1)指针式时钟

指针式的时钟表盘为圆形,并且圆周上有分布均匀的12个数字刻度和48个较小的原点刻度,刻度显示清楚,用来表示小时、分钟和秒数。

钟面上有长度不相同的指针,即时针、分针、秒针,指针的运动具有规律性,为顺时针。

 

(2)数字式时钟

数字钟显示时间的格式是时分秒,小时为24进制,分钟和秒是60进制,指针式的时钟和数字式的时钟显示的时间同步,且俩时钟可以同时设置。

 

(3)秒表

按下秒表控制按钮后,秒表显示窗中显示从0开始的时间,单位为百分之一秒。

再次按下秒表控制按钮后计时停止,该窗口显示累计时间。

 

2.函数描述

(1)CPointp;

doubleangle=nvalue*PI/30;

p.x=m_Center.x+(int)(nlenth*sin(angle));

p.y=m_Center.y-(int)(nlenth*cos(angle));

returnp;

用来得到时钟刻度点和时针、分针、秒针的端点

(2)hour=hour*5;

hour=hour+minute/12;

m_OldHour[0]=m_Hour[0];

m_OldHour[1]=m_Hour[1];

m_Hour[0]=GetPoint(int(m_Radious/2),hour);

m_Hour[1]=GetPoint(7,hour+30);

m_OldMin[0]=m_Minute[0];

m_OldMin[1]=m_Minute[1];

m_Minute[0]=GetPoint(int(m_Radious*7/10),minute);

m_Minute[1]=GetPoint(10,minute+30);

m_OldSec[0]=m_Second[0];

m_OldSec[1]=m_Second[1];

m_Second[0]=GetPoint(int(m_Radious*8/10),second);

m_Second[1]=GetPoint(30,second+30);

用来得到时针、分针、秒针的当前位置和上一时刻位置并将其保存

(3)CRectrc;

CDCdcMem;

GetClientRect(&rc);

CBitmapbmp;

dcMem.CreateCompatibleDC(pDC);

bmp.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());

CBitmap*pOldBit=dcMem.SelectObject(&bmp);

dcMem.FillSolidRect(rc,RGB(255,255,255));

………….//画图代码

pDC->BitBlt(0,0,rc.Width(),rc.Height(),&dcMem,0,0,SRCCOPY);

dcMem.DeleteDC();

bmp.DeleteObject();

利用双缓冲防止屏幕画面闪烁

四.实现环境及工具

Win7环境下

VC++6.0MFC

五.程序测试

1.对时间设置测试

按下确定后测试其设置为需要设置的时间,并正常运行。

2.对秒表测试

点下启动后它正常运行;

点下停止后它停止运行并记录当前累积时间。

再次按下启动按钮时它计时清零并重新开始计时。

3.整体3部分测试

同时运行时三部分均正常运行,并且屏幕也不闪烁。

六.心得体会

通过本次实验,对c++编程有了进一步的了解和能够更加熟练的编程,还学习了MFC的一些画图处理函数,以及一些运行机理,能够基本掌握用MFC画图,且能够实现一些基本的功能。

在本次设计的初期,只实现了小部分功能,对画图及其不了解,且对窗口设置的不合理倒是画面相当丑陋,后来通过请教同学、老师、上网查资料,最终设计出比较满意的画面。

还有,本次设计的秒表设计,由于它的刷新频率太高,导致屏幕闪烁严重,画面看起来很不舒畅,后面经查资料发现双缓冲技术能够解决这一问题,也将这个问题成功解决。

觉得本次设计中的采用不同的计时器来控制不同的模块效果比较好,对每一模块进行独立的控制很短单,而且思路清晰。

总之在本次实验中我学到了很多知识,而且培养了自己的自学能力,逼着自己进行查阅大量的资料。

在本次实验中自己对程序一直修改,一直增加功能和改善画面,大大的提高了自己的动手能力。

附:

源代码及详细注释(由于使用的MFC向导形成工程只附部分核心代码)

中加

public:

intyear;

intmonth;

intday;

inthour;

intsecond;

intminute;

intwatch;

intwday;

CPenm_HouPen,m_NoHouPen,m_MinPen,m_NoMinPen,m_SecPen,m_NoSecPen,m_circle,m_RectPen;

HBRUSHm_HurkBrush,m_CircleBrush,m_RecBrush,m_RectBrush,m_RectBrush1,m_RectBrush2;

CPointm_Center;

doublem_Radious;

CPointm_Hour[2],m_OldHour[2];

CPointm_Minute[2],m_OldMin[2];

CPointm_Second[2],m_OldSec[2];

CRectm_WatchStart;

CRectm_WatchStop;

voidSetClock(inthour,intminute,intsecond);

CPointGetPoint(intnlenth,intnvalue);

 

#include"stdafx.h"

#include"Clock.h"

#definePI3.14159265

#include

#include"SetTimeDlg.h"

#include"ClockDoc.h"

#include"ClockView.h"

#include

#ifdef_DEBUG

#definenewDEBUG_NEW

#undefTHIS_FILE

staticcharTHIS_FILE[]=__FILE__;

#endif

中初始化设置变量

/////////////////////////////////////////////////////////////////////////////

//CSetTimeDlgdialog

 

CSetTimeDlg:

:

CSetTimeDlg(CWnd*pParent/*=NULL*/)

:

CDialog(CSetTimeDlg:

:

IDD,pParent)

{

//{{AFX_DATA_INIT(CSetTimeDlg)

longnow=time(NULL);

tmlocal=*localtime(&now);

m_Day=local.tm_mday;;

m_Hour=local.tm_hour;

m_Minute=local.tm_min;

m_Month=local.tm_mon+1;

m_Second=local.tm_sec;

m_Year=local.tm_year+1900;

m_Wday=local.tm_wday;

//}}AFX_DATA_INIT

}

voidCSetTimeDlg:

:

DoDataExchange(CDataExchange*pDX)

{

CDialog:

:

DoDataExchange(pDX);

//{{AFX_DATA_MAP(CSetTimeDlg)

DDX_Text(pDX,ID_DAY,m_Day);

DDV_MinMaxInt(pDX,m_Day,1,31);

DDX_Text(pDX,ID_HOUR,m_Hour);

DDV_MinMaxInt(pDX,m_Hour,0,23);

DDX_Text(pDX,ID_MINUTE,m_Minute);

DDV_MinMaxInt(pDX,m_Minute,0,59);

DDX_Text(pDX,ID_MONTH,m_Month);

DDV_MinMaxInt(pDX,m_Month,1,12);

DDX_Text(pDX,ID_SECOND,m_Second);

DDV_MinMaxInt(pDX,m_Second,0,59);

DDX_Text(pDX,ID_YEAR,m_Year);

DDV_MinMaxInt(pDX,m_Year,0,3000);

DDX_Text(pDX,ID_WDAY,m_Wday);

DDV_MinMaxInt(pDX,m_Wday,0,6);

//}}AFX_DATA_MAP

}

/////////////////////////////////////////////////////////////////////////////

//CClockView

IMPLEMENT_DYNCREATE(CClockView,CView)

BEGIN_MESSAGE_MAP(CClockView,CView)

//{{AFX_MSG_MAP(CClockView)

ON_COMMAND(ID_START,OnStart)

ON_COMMAND(ID_STOP,OnStop)

ON_COMMAND(ID_STETIME,OnStetime)

ON_WM_TIMER()

ON_WM_LBUTTONDOWN()

//}}AFX_MSG_MAP

//Standardprintingcommands

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()

/////////////////////////////////////////////////////////////////////////////

//CClockViewconstruction/destruction

CClockView:

:

CClockView()

{//初始化时间为系统时间

longnow=time(NULL);

tmlocal=*localtime(&now);

year=local.tm_year+1900;

month=local.tm_mon+1;

day=local.tm_mday;

minute=local.tm_min;

hour=local.tm_hour;

second=local.tm_sec;

wday=local.tm_wday;

//创建画笔、画刷

m_HouPen.CreatePen(PS_SOLID,5,RGB(255,50,0));

m_NoHouPen.CreatePen(PS_SOLID,5,RGB(204,255,102));

m_MinPen.CreatePen(PS_SOLID,3,RGB(0,0,255));

m_NoMinPen.CreatePen(PS_SOLID,3,RGB(204,255,102));

m_SecPen.CreatePen(PS_SOLID,1,RGB(0,0,0));

m_NoSecPen.CreatePen(PS_SOLID,1,RGB(204,255,102));

m_circle.CreatePen(PS_SOLID,2,RGB(0,0,0));

m_RectPen.CreatePen(PS_SOLID,3,RGB(204,102,0));

m_HurkBrush=CreateSolidBrush(RGB(255,0,0));

m_CircleBrush=CreateSolidBrush(RGB(204,255,102));

m_RecBrush=CreateSolidBrush(RGB(255,255,51));

m_RectBrush=CreateSolidBrush(RGB(102,51,0));

m_RectBrush1=CreateSolidBrush(RGB(255,51,0));

m_RectBrush2=CreateSolidBrush(RGB(0,102,204));

 

m_Center.x=200;

m_Center.y=200;

m_Radious=185;

SetClock(hour,minute,second);

watch=0;

m_WatchStart=CRect(480,310,560,340);

m_WatchStop=CRect(590,310,670,340);

//TODO:

addconstructioncodehere

}

CClockView:

:

~CClockView()

{

}

voidCClockView:

:

SetClock(inthour,intminute,intsecond)

{

hour=hour*5;//时针每过1小时转5*PI/3

hour=hour+minute/12;//时针每过12分钟转PI/3

//保存时钟原位置

m_OldHour[0]=m_Hour[0];

m_OldHour[1]=m_Hour[1];

//计算时针当前位置

m_Hour[0]=GetPoint(int(m_Radious/2),hour);

m_Hour[1]=GetPoint(7,hour+30);

//保存分针位置

m_OldMin[0]=m_Minute[0];

m_OldMin[1]=m_Minute[1];

//计算分针位置

m_Minute[0]=GetPoint(int(m_Radious*7/10),minute);

m_Minute[1]=GetPoint(10,minute+30);

//保存秒针位置

m_OldSec[0]=m_Second[0];

m_OldSec[1]=m_Second[1];

//计算秒针位置

m_Second[0]=GetPoint(int(m_Radious*8/10),second);

m_Second[1]=GetPoint(30,second+30);

 

}

CPointCClockView:

:

GetPoint(intnlenth,intnvalue)

{//用来计算指针的俩端点的位置和表盘上刻度的位置

CPointp;

doubleangle=nvalue*PI/30;

p.x=m_Center.x+(int)(nlenth*sin(angle));

p.y=m_Center.y-(int)(nlenth*cos(angle));

returnp;

}

BOOLCClockView:

:

PreCreateWindow(CREATESTRUCT&cs)

{

//TODO:

ModifytheWindowclassorstylesherebymodifying

//theCREATESTRUCTcs

returnCView:

:

PreCreateWindow(cs);

}

/////////////////////////////////////////////////////////////////////////////

//CClockViewdrawing

//*********画表***********//

voidCClockView:

:

OnDraw(CDC*pDC)

{

SetTimer(1,1000,NULL);

CClockDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:

adddrawcodefornativedatahere

 

CRectrc;

CDCdcMem;

GetClientRect(&rc);

CBitmapbmp;//内存中承载临时图象的位图

dcMem.CreateCompatibleDC(pDC);//依附窗口DC创建兼容内存DC

//创建兼容位图(必须用pDC创建,否则画出的图形变成黑色)

bmp.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());

CBitmap*pOldBit=dcMem.SelectObject(&bmp);//按原来背景填充客户区,不然会是黑色

dcMem.FillSolidRect(rc,RGB(255,255,255));

//画图,添加你要画图的代码,不过用dcMem画,而不是pDc

//画表盘最外面的大圆并填充颜色

dcMem.SelectObject(m_circle);

dcMem.Ellipse(m_Center.x-195,m_Center.y-195,m_Center.x+195,m_Center.y+195);

dcMem.SelectObject(m_CircleBrush);

dcMem.Ellipse(m_Center.x-195,m_Center.y-195,m_Center.x+195,m_Center.y+195);

//画60个刻度

for(inti=0;i<60;i++)

{

CPointpt=GetPoint(m_Radious,i);

dcMem.SelectObject(m_SecPen);

//画小时刻度

if(i%5==0)

{

CStringm_Number;

dcMem.SetBkMode(TRANSPARENT);//将textout背景透明

m_Number.Format("%2d",(i/5==0?

12:

i/5));

dcMem.TextOut(pt.x-7,pt.y-7,m_Number);

}//画小时之间的刻度

else

{

dcMem.SelectObject(m_HurkBrush);

dcMem.Ellipse(pt.x-2,pt.y-2,pt.x+2,pt.y+2);

}

}

//画时针

if(m_OldHour[0]!

=m_Hour[0])

{//用表盘背景色覆盖原来的时针

dcMem.SelectObject(m_NoHouPen);

dcMem.MoveTo(m_OldHour[0]);

dcMem.LineTo(m_OldHour[1]);

//时针绘制

dcMem.SelectObject(m_HouPen);

dcMem.MoveTo(m_Hour[0]);

dcMem.LineTo(m_Hour[1]);

}

else

{

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1