用MFC制作一个倒计时小程序
1.思路:
1)初始步骤1:新建一个工程,选择MFC AppWizard(exe),工程名命名为CdTimer,选择基于对话框形式的应用程序,将此主对话框用于显示剩余的时间,对话框ID命名为IDD_CDTIMER_DIALOG;并在此对话框上添加三个edit控件和两个static控件,分别用于显示时钟数、分钟数、秒数以及两个间隔符“:”,在三个对话框上各关联一个Cstring型的对象;
2)初始步骤2:添加一个对话框资源,使用默认的ID号IDD_DIALOG1,打开ClassWizard,按提示添加一个新类CSetCountDownDlg,将用于设置倒计时数,同样的在此对话框上添加一个edit控件,用于显示设置的时间,如50分钟倒计时就设置为00:50:00,并在此控件上也关联一个CString型的对象;
3)想达到的功能:双击运行应用程序后,右键弹出对话框IDD_DIALOG1设置倒计时,按回车键设置完毕;左键单击主对话框,倒计时开始;左键双击主对话框,到计时暂停;右键单击主对话框,重新设置;按回车键退出。
2.具体实现:
用的的函数主要有:
a.CString 的成员函数Format、Left、Mid、Right、Find;
b.计数器相关SetTimer、KillTimer;
c.字符串转化atoi;
d.对话框或控件等窗口相关的函数DoModal、SetDlgItemText、UpdateData;
e.消息响应函数OnCreate、OnRButtonDown、OnLButtonDown、OnLButtonDblClk、OnTimer、OnOK。
主要的实现过程:
- 右键单击弹出设置倒计时对话框IDD_DIALOG1,按规定输入数据后回车,程序进入CSetCountDownDlg的重载的OnOk函数,读取输入于对话框IDD_DIALOG1的编辑框(编辑框关联的变量为m_strSetCountDownTime)相应位置的数据,并赋值给CSetCountDownDlg的int型成员变量m_settedHour、m_settedSecond、m_settedMinute,主要代码及程序运行截图如下所示:
void CSetCountDownDlg::OnOK() { UpdateData(TRUE); // 获取设置的小时数 m_settedHour = atoi(m_strSetCountDownTime.Left(m_strSetCountDownTime.Find(":"))); // 获取设置的分钟数 m_settedMinute = atoi(m_strSetCountDownTime.Mid(m_strSetCountDownTime.Find(":")+1, m_strSetCountDownTime.ReverseFind(':') - m_strSetCountDownTime.Find(':'))); // 获取设置的秒数 m_settedSecond = atoi(m_strSetCountDownTime.Right(m_strSetCountDownTime.Find(":"))); UpdateData(FALSE); CDialog::OnOK(); }
- 回车后对话框IDD_DIALOG1被销毁,程序继续执行下面代码m_setCountDownDlg.DoModal();之后的部分,使得主对话框IDD_CDTIMER_DIALOG获取到已经设置的倒计时,并按规定的格式显示。例如若设置为1:45:00则显示为01:45:00. OnRButtonDown函数代码如下:
void CCdTimerDlg::OnRButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default m_setCountDownDlg.DoModal(); m_strHours.Format("%d", m_setCountDownDlg.m_settedHour); m_strMinutes.Format("%d", m_setCountDownDlg.m_settedMinute); m_strSeconds.Format("%d", m_setCountDownDlg.m_settedSecond); // 控制显示格式,当数值 < 10,以0作为前缀 if (atoi(m_strSeconds) < 10) { m_strSeconds.Format("0%d", atoi(m_strSeconds)); } if (atoi(m_strMinutes) < 10) { m_strMinutes.Format("0%d", atoi(m_strMinutes)); } if (atoi(m_strHours) < 10) { m_strHours.Format("0%d", atoi(m_strHours)); } // 显示设置的时间 SetDlgItemText(IDC_HOURS, m_strHours); SetDlgItemText(IDC_MINUTES, m_strMinutes); SetDlgItemText(IDC_SECONDS, m_strSeconds); m_bIsBegin = FALSE; // 重新设置时间 CDialog::OnRButtonDown(nFlags, point); }
- 单击鼠标左键,响应ON_WM_LBUTTONDOWN消息,程序进入OnLButtonDown函数,代码如下:
void CCdTimerDlg::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default m_bIsBegin = TRUE; SetTimer(1, 1000, NULL); CDialog::OnLButtonDown(nFlags, point); }
- 之后进入OnTimer函数,开始计时:
void CCdTimerDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default UpdateData(TRUE); BOOL bIsDecreased = FALSE; // 防止碰到类似01:00:00的情况使得分钟被减为58而不是59 // 倒计时程序的实现部分 if (m_bIsBegin == TRUE) { if (atoi(m_strSeconds) == 0) { if (atoi(m_strMinutes) == 0) { if (atoi(m_strHours) == 0) { return; } m_strHours.Format("%d", atoi(m_strHours) - 1); m_strMinutes.Format("%d", 59); m_strSeconds.Format("%d", 59); bIsDecreased = TRUE; // 分钟已经减少为59 } if (bIsDecreased == FALSE) { m_strMinutes.Format("%d", atoi(m_strMinutes) - 1); m_strSeconds.Format("%d", 59); } } else { m_strSeconds.Format("%d", atoi(m_strSeconds) - 1); } // 控制显示格式,当数值 < 10,以0作为前缀 if (atoi(m_strSeconds) < 10) { m_strSeconds.Format("0%d", atoi(m_strSeconds)); } if (atoi(m_strMinutes) < 10) { m_strMinutes.Format("0%d", atoi(m_strMinutes)); } if (atoi(m_strHours) < 10) { m_strHours.Format("0%d", atoi(m_strHours)); } } UpdateData(FALSE); CDialog::OnTimer(nIDEvent); }
程序运行如下所示:
- 若需要暂停,双击鼠标左键,响应ON_WM_LBUTTONDBLCLK消息,程序进入OnLButtonDblClk,暂停计时:
void CCdTimerDlg::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default KillTimer(1); // 计时暂停 CDialog::OnLButtonDblClk(nFlags, point); }
- 单击左键,继续计时,回车退出。
至此,一个有简易功能倒计时小工具已经制作完成。
这个功能还很简单,后续将继续改进,关于这个程序及相关细节,希望得到大家的评论与指点!