用MFC编写一个指针型时钟程序,时钟还具有闹钟和倒计时功能,求能在mfc里执行的整个文件

用MFC编写一个指针型时钟程序,时钟还具有闹钟和倒计时功能,求能在mfc里执行的整个文件,第1张

一、程序窗口设计步骤

(1)用AppWizard生成一个名为Clock的单文档(SDI)程序框架滚察。为了简化应用程序,在第四步时去掉Docking toolbar和Initial status bar选择项(不删除也可),其他各选项均可用缺省设置。

(2)编辑项目的菜单资源,在主框架窗口的主菜单(IDR_MAINFRAME)中添加一个名为“时钟控制”的下拉菜单。在“时钟控制”菜单中添加三个菜单选项“启动时钟”、“停止时钟”和“时间设置”。并在菜单属性项中设定“启动时钟”菜单的ID标号为ID_START,“停止时钟”菜单的ID标号为ID_STOP,“时间设置”菜单的ID标号为ID_SETTIME。为了简化菜单,可删除系统原有的“文件”、“编辑”菜单项。

(3)利用ClassWizard为视图类添加菜单命令处理函数。进入ClassWizard的Message Maps选项卡,选择Class Name项为CClockView类,在Object IDs列表框中分别选择新添加的菜单选项的ID,在Messages列表框中选择COMMAND,按下Add Function按钮添加成员函数。ClassWizard会为“启动时钟”、“停止时钟”和“时间设置”菜单选项添加相应的消息响应函数OnStart ( )、OnStop ( )和OnSettime ( )。

(4)利用ClassWizard为视图类添加定时器和鼠标消息处理函数。进入ClassWizard的Message Maps选项卡,选择Class Name项为 CClockView类,在Messages列表框中分别选择定时器消息WM_TIMER和鼠标消息WM_LBUTIONDOWN,按下Add Function按钮添加成员函数。ClassWizard会添加相应的定时器和鼠标消息响应函数OnTimer和OnLButtonDown。

(5)使用Developer Studio菜单的Insert / Resource…选项调出Insert Source对话框,为项目添加新的对话框资源。在对话框属性中,修改对话框名为“时间设定”。在对话框中增加用来输入年、月、日、时、分、秒的编辑框控件。

通过控件属性,将年、月、日、时、分、秒等编辑控件的ID改为IDC_YEAR、IDC_MONTH、IDC_DAY、IDC_HOUR、IDC_MINUTE和IDC_SECOND。

(6)利用ClassWizard自动建立对话框类。进入ClassWizard后,d出一个对话框询问是否要为该对话框模板建立类。按下“OK”按钮,会d出New Class对话框,在Name栏填写对话框类的名称CSetTimeDlg后按“OK”按钮,即可为对话框创建一个对应的类。

(7) 利用大穗茄ClassWizard为对话框类添加与各控件对应的数据成员。选择MemberVariables选项卡,确保Class Name项为对话框CSetTimeDlg类,然后在选项卡下方的窗口中选择各控件的ID并按下“Add Variable…”按钮,为其添加对应成员变量。

控制ID

变量类型

变量名

变量范围

IDC_YEAR

int

m_Year

0~3000

IDC_MONTH

int

m_Month

1~12

IDC_DAY

int

m_Day

1~31

IDC_HOUR

int

m_Hour

0~23

IDC_MINUTE

int

m_Minute

0~59

IDC_SECOND

int

m_Second

0~59

最后一列为变量取值范围。

(8)编辑工程的图标资源,在Resource View选项窗口中修改Icon结点所包含的族慎主框架图标(IDR_MAINFRAME)。此步非必须。

(9)完成以上工作后,即可修改程序框架,添加必要的代码。

二、主要源代码:

按以下步骤向视图类(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) 在视图类构造函数中增加初始化语句,之前加上头文件

#include<ctime>

CClockView::CClockView()

{

// 设定时间

char time[32]

SYSTEMTIME st

GetLocalTime(&st)

day = st.wDay

hour = st.wHour

minute = st.wMinute

month = st.wMonth

second = st.wSecond

year = st.wYear

// 设定画笔/画刷

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 = 200

m_Center. y = 200

// 设定时钟半径

m_Radius = 200

// 计算指针位置

SetClock (hour, minute, second)

// 设定秒表计数器及按钮位置

watch = 0

m_WatchStart = CRect (480, 310, 560, 340)// 启动钮

m_WatchStop = CRect (590, 310, 670, 340)// 停止钮

}

编写指针位置计算函数SetClock和GetPoint。首先在ClockView. cpp文件头部添加下面两行代码,以便进行数学计算。

#include "math.h"

#define PI 3.14159265

然后添加下列代码:

//计算各个指针位置的函数

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]

// 计算时针当前位置

m_Hour[0]= GetPoint(int(m_Radius/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_Radius*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_Radius * 8/10), second)

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

}

// 计算以表心为原点的指针的端点位置

CPoint CClockView ::GetPoint (int nLenth, int nValue)

{

CPoint p

double angle = nValue* PI /30-PI/2

p.x = m_Center.x + (int) (nLenth * cos(angle))

p.y = m_Center.y + (int) (nLenth * sin(angle))

return p

}

绘制表盘上的标记、时针、分针和秒针,并显示数字时钟及秒表,在OnDraw函数中添加下面代码:

void CClockView::OnDraw(CDC* pDC)

{

CClockDoc* pDoc = GetDocument()

ASSERT_VALID(pDoc)

// 绘制表盘上的标记

pDC->SelectObject(m_MarkBrush)

int k=0

for(int i=0i<60i++)

{

CPoint pt=GetPoint(175,i)

if (i%5==0)

{

//显示表盘上的数字

CString str[12]={"12","1","2","3","4","5","6","7","8","9","10","11"}

pDC->TextOut(pt.x-5,pt.y-5,str[k])

k++

}else

{

//显示数字之间的圆圈

pDC->Ellipse(pt.x-2,pt.y-2,pt.x+2,pt.y+2)

}

}

// 画时针

pDC->SelectObject (m_HouPen)

if (m_OldHour[0]!= m_Hour[0])

{

// 用白色覆盖原位置时针

pDC->SetROP2(R2_WHITE)

pDC->MoveTo(m_OldHour [0] )

pDC->LineTo(m_OldHour [1] )

pDC->SetROP2(R2_COPYPEN)

//时针绘制

pDC->MoveTo(m_Hour[0])

pDC->LineTo(m_Hour[1])

}

else

{

// 时针绘制

pDC->MoveTo(m_Hour[0])

pDC->LineTo(m_Hour[1])

}

// 画分针

pDC->SelectObject (m_MinPen)

if (m_OldMin[0]!=m_Minute[0])

{

// 用白色覆盖原位置分针

pDC->SetROP2(R2_WHITE)

pDC->MoveTo(m_OldMin[0])

pDC->LineTo(m_OldMin[1])

pDC->SetROP2(R2_COPYPEN)

// 分针绘制

pDC->MoveTo(m_Minute[0])

pDC->LineTo(m_Minute[1])

}

else

{

// 分针绘制

pDC->MoveTo(m_Minute[0])

pDC->LineTo(m_Minute[1])

}

// 用白色覆盖原位置秒针

pDC->SelectObject(m_SecPen)

pDC->SetROP2(R2_WHITE)

pDC->MoveTo(m_OldSec[0])

pDC->LineTo(m_OldSec[1])

pDC->SetROP2(R2_COPYPEN)

// 秒针绘制

pDC->MoveTo(m_Second[0])

pDC->LineTo(m_Second[1])

// 数字时钟显示

pDC->SelectStockObject(WHITE_BRUSH)

pDC->Rectangle(450,30,700,180)

pDC->TextOut(535,20,"当前时间")

CString m_Date,m_Time

m_Date.Format ("% 4d年%4d月%4d日",year,month,day)

pDC->TextOut(510,70,m_Date)

m_Time.Format("%4d点%4d分%4d秒",hour,minute,second)

pDC->TextOut(510,100,m_Time)

// 秒表显示

pDC->Rectangle(450,220,700,370)

pDC->TextOut(545,200,"秒 表")

int minSec= watch%100

int Sec=(watch/100)%60

int Min=(watch/100)/60

m_Time.Format("% 02d: % 02d: % 02d",Min,Sec,minSec)

pDC->TextOut(535,260,m_Time)

pDC->Rectangle(&m_WatchStart)

pDC->Rectangle(&m_WatchStop)

pDC->TextOut(m_WatchStart.left + 18,m_WatchStart.top + 5,"启动")

pDC->TextOut(m_WatchStop.left + 18,m_WatchStop.top + 5,"停止")

}

请注意将表示时间的整数转换为CString字符串类型的方法以及秒表的显示方法。另外,watch计数器以1/100秒为计数单位,每达到100则秒数加1。

按照下列步骤增加时钟控制代码:

修改Onstart和OnStop函数,设置时钟运动消息。按比正常时钟快20倍的假定,50ms产生一个消息。本程序采用和正常时间同步,即1000ms产生一个消息, 其代码为:

void CClockView::OnStart()

{

SetTimer (1, 1000, NULL)

}

void CClockView::OnStop()

{

KillTimer (1)

}

修改OnTimer函数,正确计算并处理年、月、日、时、分、秒等变量的联动变化 ,其代码为:

void CClockView::OnTimer(UINT nIDEvent)

{

if (nIDEvent == 1)

{

second++// 秒增加

if (second>59)

{

second=0

minute++// 分增加

}

if (minute>59)

{

minute= 0

hour++// 小时增加

}

if (hour>23)

{

hour=0

day++// 日增加

}

switch(month)

{

case 1: // 大月

case 3:

case 5:

case 7:

case 8:

case 10:

case 12:

if (day>31)

{

day= 1

month++// 月增加

}

break

case 4: // 小月

case 6:

case 9:

case 11:

if (day>30)

{

day=1

month++// 月增加

}

break

case 2:

if (year%4 ==0 &&day>29) // 润二月

{

day=1

month++// 月增加

}

if (year%4!=0 &&day>28) // 二月

{

day=1

month++

}

break

}

if (month >12)

{

// 年增加

year++

month=1

}

SetClock (hour, minute, second)

Invalidate (false)

}

// 秒表定时器消息处理

if (nIDEvent == 2)

{

watch++

Invalidate (false)

}

CView::OnTimer(nIDEvent)

}

添加时间设置对话框代码。

首先在ClockView. cpp文件头部添加下列语句:

#include “SetTimeDlg. h”

在时间设定对话框类的构造函数中,做如下修改,将初始日期设为当前时间,之前要加上头文件

#include<ctime>

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

: CDialog(CSetTimeDlg::IDD, pParent)

{

//||AFX_DATA_INIT(CSetTimeDlg)

char time[32]

SYSTEMTIME st

GetLocalTime(&st)

m_Day = st.wDay

m_Hour = st.wHour

m_Minute = st.wMinute

m_Month = st.wMonth

m_Second = st.wSecond

m_Year = st.wYear// ||AFX_DATA_INIT

}

最后,在OnSettime函数中添加代码如下:

void CClockView::OnSettime()

{

CSetTimeDlg SetDlg

if (SetDlg.DoModal ()==IDOK)

{

year=SetDlg.m_Year

month= SetDlg.m_Month

day= SetDlg.m_Day

hour=SetDlg.m_Hour

minute=SetDlg.m_Minute

second=SetDlg.m_Second

}

// 计算各指针位置

SetClock (hour,minute,second)

Invalidate (true)

}

按以下步骤设计秒表控制程序:

在OnLButtonDown函数中增加下列内容,以便响应单击秒表启动、停止框所发出的消息:

void CClockView::OnLButtonDown(UINT nFlags, CPoint point)

{

if (m_WatchStart.PtInRect(point))

{

watch=0

SetTimer(2,10,NULL)

}

if (m_WatchStop.PtInRect(point))

{

KillTimer (2)

}

CView::OnLButtonDown(nFlags, point)

}

编译,连接,运行程序。

运行结果:

添加对话框

1)选择“插入”-“资源”菜单,选中Dialog,单击确定按钮,系

统就可以自动为当前应用程序添加一个对话框。

2)设置对话框属性。在对话框模板的空白处右击鼠标,从d出的快

捷菜单中选择属性菜单项,然后对相应的参数进行设置。

3)添加和布局控件。一旦对话框资源被打开或者是创建,就会出现

对话框编辑器,通过它我们就可以对对话框进行编辑

创建对话框类

在对话框资源模板的空白处双击鼠标,d出创建一个新类的对话框。

在Name框中输入用户定义的类名。在这里一般以“C”字母开始,单

击OK按钮,一个基于对话框资源模板的对话框类就创建好了。

在程序中使用对话框

1)在项目工作区窗口中选择ResourceView页面,双击资源Menu项

中的IDR_MAINFRAME,则就会出现菜单编辑器。在菜单的空白处添加

一个菜单项。

2)在菜模吵单的空位置处双击鼠标左键,则会出现他的属性对话框,在标

题框中输入“设置”。

3)单击“设置”菜单项下方的空位置,在属性对话框中,输入“闹

钟”在ID框中输入该菜单的资源标识:ID_TEST_DLG,然后单击属性

对话框右上角的关闭按钮。

4)用鼠标将新添加的菜单项拖到“文件”和“编辑”之间。

5)选择“查看”-“建立类向导”菜单命令,则出现MFC ClassWizard

对话框,并自动切换到Message Map页面。从Class name列表中选

择CMainFrame,在IDs列表中选择ID_TEST_DLG。然后在Message框

中选择COMMAND消息。

6)单击Add Function按钮,出现Add Member Function对话框以输

入成员函数的名称。系统的默认名称是OntestDlg。液枣该函数是对菜单

项ID_TEST_DLG的映射,也就是说,当在应用程序运行时,用户选择

“对话框”,则该函数OntestDlg别调用,执行该函数的代码。

7)单击OK按钮,在ClassWizard的Member function列表中将列出

新增加的成员函数。选择此函数,单击EditCode按钮,在此成员函

数中添加下面的代码:

void CMainFrame::OnTestDlg()

{

CFirstDlg dlg//定义对话框类对象

dlg.DoModal()//显示对话框

}

8)在OnTestDlg函数的实现文件MainFrm.cpp的前面添加CFirstDlg

类包含语句,即

#include "MainFrm.h"

#include "FirstDlg.h"

闹钟功能的实现

1)在闹钟对话框中添加三个组合框,分别是时闹码拆、分、秒。在属性中

的数据项目中添加应该显示的数据。

对话框的OK按钮响应函数,使得程序提取到闹钟的三个参数,

并且启动定时器2

void CMainFrame::OnNaozhong()

{

// TODO: Add your command handler codehere

naozhong dlg

if(dlg.DoModal()==IDOK)

{

second=dlg.second

minute=dlg.minute

hour=dlg.hour

}

SetTimer(2,500,NULL)

更新CMainFrame中的timer函数,使得每秒钟将获取的闹钟的参

数与系统当前的时间比较,如果两个数值相等,则响应d出一个对话

框,并且PlaySound函数别响应,播放声音。

void CMainFrame::OnTimer(UINT nIDEvent)

{

// TODO: Add your message handler codehere and/or call

default

if(nIDEvent==1)

Invalidate()

else if(nIDEvent==2)

{

CTime tm

int am

tm=tm.GetCurrentTime()

if(second==tm.GetSecond())

{

if(minute==tm.GetMinute())

{

if(hour==tm.GetHour())//time.GetHour()

{

KillTimer(2)

PlaySound("c:\\Users\\靳洪都\\Desktop\\自

己的程序 第三版\\shizhong\\ring.wav", NULL,SND_FILENAME |

SND_ASYNC)

MessageBox("时间到!")

}

}

}

}

}

CFrameWnd::OnTimer(nIDEvent)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12560030.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存