MFC案例:利用SetTimer函数编写一个“计时器”程序

2024-06-12 07:04

本文主要是介绍MFC案例:利用SetTimer函数编写一个“计时器”程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、希望达成效果
       利用基于对话框的MFC项目,做一个一方面能够显示当前时间;另一方面在点击开始按钮时进行读秒计时,计时结果动态显示,当点击结束时读秒结束并保持最后结果。
二、编程步骤及相关代码、注释
      1、启动VS->创建新项目->MFC应用-项目名称:MFCtimer->创建->在应用程序类型中选择:基于对话框->完成。启动后,将"TODO:"、“确定”、"取消"等删去。
      2、从工具箱先拖入一些静态文本框,用于显示提示文字,选择这些控件,右键属性后更改ID、右键添加变量后添加变量。具体包括:
       属性ID: IDC_CTIME    变量名: m_CTIME      显示:当前时间("当前时间"在更改写入)
       属性ID: IDC_YEAR      变量名: m_YEAR        显示:年
       属性ID: IDC_MONTH  变量名: m_MONTH   显示:月
       属性ID: IDC_DAY        变量名:  m_DAY        显示:日
       属性ID: IDC_HOUR     变量名: m_HOUR      显示:时
       属性ID: IDC_MINUTE  变量名: m_MINUTE   显示:分
       属性ID:IDC_TITLE                                           显示:计时器
       上面IDC_TITLE以及下面介绍的一些控件,没有添加变量名,目的是为了在程序中介绍如何使用变量,以及仅使用ID调用成员函数的方法;在这个程序中,加不加变量名无所谓。
       3、从工具箱拖入文本编辑框:5个用于显示当前时间;2个用于显示读秒。使用与静态文本框相似的方法,为这些文本编辑框更改ID。
      属性ID:IDC_SHOW_YEAR  显示:年(不是“年”字,指2024,下同)
      属性ID:IDC_SHOW_MONTH 显示:月
      属性ID:IDC_SHOW_DAY  显示:日
      属性ID:IDC_SHOW_HOUR 显示:时
      属性ID:IDC_SHOW_MINUTE  显示:分
      属性ID:IDC_SHOW_TIMER1 变量名:m_showTimer1 显示:读秒  注:这里只有它加了变量名
      属性ID:IDC_SHOW_TIMER2 显示:读秒(化成"__分__秒"格式)
       4、拖入两个按钮,ID不改了,就用缺省的:IDC_BUTTON1、IDC_BUTTON2。右键这两个按钮,选择属性,ID不改了,但要把文字描述改成“开始计时”、“结束及时”。并分别给这两个按钮添加处理程序void CMFCtimerDlg::OnBnClickedButton1()、void CMFCtimerDlg :: OnBnClickedButton2(),后边要用到。
       5、至此,除了已经自动生成的代码,我们还没有写过代码。下面开始添加代码工作:

       a.在MFCtimerDlg.h中声明几个变量:

public:CFont cfont[4]; //声明静态文本框等控件需用到的字形字号time_t startTime, endTime; //声明开始时刻、结束时刻变量BOOL isStart=FALSE; //声明是否计时的逻辑变量

       b.CMFCtimerDlg::OnInitDialog()程序中,在//TODO:语句后添加代码:

//设置字体for (int i = 0; i < 4; i++){int choice;if (i == 0)choice = 40; //大标题字体使用if (i == 1)choice = 25; //年月日等提示字字体使用if (i == 2)choice = 20; //文本编辑框显示字体使用if (i == 3)choice = 80; //显示跳秒cfont[i].CreateFont(choice, // nHeight//250, // nWidth0, // nEscapement0, // nOrientationFW_BOLD, // nWeightFALSE, // bItalicFALSE, // bUnderline0, // cStrikeOutUNICODE, // nCharSetOUT_DEFAULT_PRECIS, // nOutPrecisionCLIP_DEFAULT_PRECIS, // nClipPrecisionDEFAULT_QUALITY, // nQualityDEFAULT_PITCH | FF_SWISS, // nPitchAndFamily_T("黑体")); // lpszFac}
//利用函数、控件变量等方法设置控件字体、字形GetDlgItem(IDC_TITLE)->SetFont(&cfont[0]);  //“计时器”三字m_CTIME.SetFont(&cfont[1]); //“当前时间”四字m_YEAR.SetFont(&cfont[1]);  //“年”字m_MONTH.SetFont(&cfont[1]); //“月”字m_DAY.SetFont(&cfont[1]); //“日”字m_HOUR.SetFont(&cfont[1]); //“时”字m_MINUTE.SetFont(&cfont[1]); //“分”字
//设置系统计时器(消息函数机制)SetTimer(1, 1000, NULL); //设置系统及时器(利用它实现周期性变化显示)
//设置控件焦点到"开始计时"按钮(注意:本函数的返回值要改成FALSE)GetDlgItem(IDC_BUTTON1)->SetFocus();

       c.由于我们在OnInitDialog()程序中添加了系统计时器语句,接着进行:项目->类向导->消息->选择:WM_TIMER->添加处理程序,在MFCtimerDlg.cpp可以找到下面的函数:
       Void CMFCtimerDlg::OnTimer(UINT_PTR nIDEvent),添加下列代码:

	SYSTEMTIME currentTime; //声明时间结构体GetLocalTime(&currentTime); // 获得当地时间TCHAR temp[12];//给年月日时分编辑框设置字形字号并显示当前时间wsprintf(temp,L"%d",currentTime.wYear);GetDlgItem(IDC_SHOW_YEAR)->SetFont(&cfont[2]);GetDlgItem(IDC_SHOW_YEAR)->SetWindowTextW(temp);wsprintf(temp, L"%d", currentTime.wMonth);GetDlgItem(IDC_SHOW_MONTH)->SetFont(&cfont[2]);GetDlgItem(IDC_SHOW_MONTH)->SetWindowTextW(temp);wsprintf(temp, L"%d", currentTime.wDay);GetDlgItem(IDC_SHOW_DAY)->SetFont(&cfont[2]);GetDlgItem(IDC_SHOW_DAY)->SetWindowTextW(temp);wsprintf(temp, L"%d", currentTime.wHour);GetDlgItem(IDC_SHOW_HOUR)->SetFont(&cfont[2]);GetDlgItem(IDC_SHOW_HOUR)->SetWindowTextW(temp);wsprintf(temp, L"%d", currentTime.wMinute);GetDlgItem(IDC_SHOW_MINUTE)->SetFont(&cfont[2]);GetDlgItem(IDC_SHOW_MINUTE)->SetWindowTextW(temp);GetDlgItem(IDC_BUTTON1)->SetFont(&cfont[2]);GetDlgItem(IDC_BUTTON2)->SetFont(&cfont[2]);GetDlgItem(IDC_S)->SetFont(&cfont[1]);//以两个编辑框显示读秒if (isStart == TRUE) //TRUE读秒 FALSE停止读秒{time(&endTime);TCHAR buf[128];wsprintf(buf, L"%d", int(endTime-startTime));m_showTime1.SetFont(&cfont[3]);m_showTime1.SetWindowTextW(buf);GetDlgItem(IDC_SHOWTIME2)->SetFont(&cfont[1]);int second = (endTime - startTime) % 60;int minute = (endTime - startTime) / 60;wsprintf(buf, L"   %d 分 %d 秒", minute,second);GetDlgItem(IDC_SHOWTIME2)->SetWindowTextW(buf);}Circle(); //在“当前时间”后边闪烁一个圆圈,表示屏幕非静止

       说明:由于当前时间显示到分,所以不读秒时,程序给人的感觉是静止画面,所以写一个Circle程序,在“当前时间”四字后边以深灰、浅灰不断变化闪烁,给人动感。这里先调用,后边实现程序。在写这个函数之前,先到MFCtimerDlg.h中声明一个变量:

      BOOL myBool = TRUE; //声明绘制圆圈用的逻辑变量

      d.我们直接在MFCtimerDlg.cpp内声明并实现 void CMFCtimerDlg::Circle()函数,在这个函数中写上下面代码:

	CDC* pDC=GetDC();//获取当前窗口设备上下文指针CRect rect;//这是一个关于视图窗口数据的类,这里定义一个CRect类对象GetClientRect(rect);//GetClientRect得到的是相对于窗口客户区左上角的坐标。int r = rect.Height() / 20;//设置圆半径int x = rect.Height() * 0.4, y = rect.Height() * 0.27;//设置圆心坐标CPen grayPen(PS_SOLID, 3, 0x404040);//设置深色圆线型线宽颜色CPen whitePen(PS_SOLID, 3, 0xC0C0C0);//设置浅色圆线型线宽颜色if (myBool == TRUE) //画深色圆{CPen* pOldPen = pDC->SelectObject(&grayPen);pDC->Ellipse(x, y, x + r, y + r);pDC->SelectObject(pOldPen);myBool = !myBool;}else //画浅色圆{CPen* pOldPen = pDC->SelectObject(&whitePen);pDC->Ellipse(x, y, x + r, y + r);pDC->SelectObject(pOldPen);myBool = !myBool;}ReleaseDC(pDC);

      e.在给按钮添加的程序CMFCtimerDlg::OnBnClickedButton1()中写上语句:

	isStart = TRUE; //开始计时time(&startTime);

      f.在给按钮添加的程序CMFCtimerDlg::OnBnClickedButton2()中写上语句:

	isStart = FALSE; //停止计时

      g.到这里,这个小案例基本就完成了。关于程序退出,右键对话框->类向导->点击消息->选择WM_CLOSE->添加处理程序(点击对话框右上角叉的消息)。在MFCtimerDlg.cpp中出现函数:
void CMFCtimerDlg::OnClose()  在TODO:后添加:

	KillTimer(1); //关闭系统计时器MessageBox(L"程序即将关闭 。。。");

      程序运行效果截图如下:

这篇关于MFC案例:利用SetTimer函数编写一个“计时器”程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1053518

相关文章

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

六个案例搞懂mysql间隙锁

《六个案例搞懂mysql间隙锁》MySQL中的间隙是指索引中两个索引键之间的空间,间隙锁用于防止范围查询期间的幻读,本文主要介绍了六个案例搞懂mysql间隙锁,具有一定的参考价值,感兴趣的可以了解一下... 目录概念解释间隙锁详解间隙锁触发条件间隙锁加锁规则案例演示案例一:唯一索引等值锁定存在的数据案例二:

python编写朋克风格的天气查询程序

《python编写朋克风格的天气查询程序》这篇文章主要为大家详细介绍了一个基于Python的桌面应用程序,使用了tkinter库来创建图形用户界面并通过requests库调用Open-MeteoAPI... 目录工具介绍工具使用说明python脚本内容如何运行脚本工具介绍这个天气查询工具是一个基于 Pyt

Ubuntu设置程序开机自启动的操作步骤

《Ubuntu设置程序开机自启动的操作步骤》在部署程序到边缘端时,我们总希望可以通电即启动我们写好的程序,本篇博客用以记录如何在ubuntu开机执行某条命令或者某个可执行程序,需要的朋友可以参考下... 目录1、概述2、图形界面设置3、设置为Systemd服务1、概述测试环境:Ubuntu22.04 带图

Python中bisect_left 函数实现高效插入与有序列表管理

《Python中bisect_left函数实现高效插入与有序列表管理》Python的bisect_left函数通过二分查找高效定位有序列表插入位置,与bisect_right的区别在于处理重复元素时... 目录一、bisect_left 基本介绍1.1 函数定义1.2 核心功能二、bisect_left 与

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可

Python程序打包exe,单文件和多文件方式

《Python程序打包exe,单文件和多文件方式》:本文主要介绍Python程序打包exe,单文件和多文件方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录python 脚本打成exe文件安装Pyinstaller准备一个ico图标打包方式一(适用于文件较少的程

java中BigDecimal里面的subtract函数介绍及实现方法

《java中BigDecimal里面的subtract函数介绍及实现方法》在Java中实现减法操作需要根据数据类型选择不同方法,主要分为数值型减法和字符串减法两种场景,本文给大家介绍java中BigD... 目录Java中BigDecimal里面的subtract函数的意思?一、数值型减法(高精度计算)1.

MySQL 表的内外连接案例详解

《MySQL表的内外连接案例详解》本文给大家介绍MySQL表的内外连接,结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录表的内外连接(重点)内连接外连接表的内外连接(重点)内连接内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我

C++/类与对象/默认成员函数@构造函数的用法

《C++/类与对象/默认成员函数@构造函数的用法》:本文主要介绍C++/类与对象/默认成员函数@构造函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录名词概念默认成员函数构造函数概念函数特征显示构造函数隐式构造函数总结名词概念默认构造函数:不用传参就可以