1整体设计

创建对话框程序,并且设计对话框相关控件如图

相应的ID和对应的成员变量如图:

我的想法是这样的,只读属性的编辑框添加有CString类型的成员变量(如s_hour),在xxxDlg.h里另外定义了对应的int型成员变量(如n_hour),就是因为如果想要显示01:03:07这样的时间时,单纯的用于计时的int变量十位是不会显示“0”的。所以我通过除以10和余10把一位数的十位和个位取出来,再转化为CString类型的变量,数据交换同步到编辑框显示。

2 编辑框的显示

①初始化显示00:00:00

在初始化函数

BOOL CEbbinghausDlg::OnInitDialog()

里面,将各变量初始化为0,CString型变量可直接初始化为字符串“00”,更新数据显示。

n_hour = ;
n_minute = ;
n_second = ;
s_hour = "";
s_minute = "";
s_second = "";
UpdateData(FALSE);

②发现编辑框显示的字体很小,如图

那么就要修改字体大小。

给编辑框控件添加edit类型的变量,如第一个ID_HOUR的编辑框:添加edit类型的,CEdit,f_hour。

在头文件XXXDlg.h里定义字体变量。

CFont my_Font;

在OnInitDialog()函数里添加初始化代码

my_Font.CreatePointFont(, "Arial");
f_hour.SetFont(&my_Font);
f_minute.SetFont(&my_Font);
f_second.SetFont(&my_Font);

效果:

注:字体要是找不到用什么好,可以在word里找找,再填到函数参数表里。

my_Font.CreatePointFont(400, "Calibri");

③按下buttun control:Start开始计时

在头文件里定义这两个成员变量

BOOL b_review;
BOOL b_suspend;

b_review是用来决定定时5min是否完成的,没到就是FALSE,到了就是TRUE。b_suspend是指示当前是否暂停的,暂停即为TRUE,否则FALSE。初始化均为FALSE。

b_review = FALSE;
b_suspend = FALSE;

现在要开始设计定时器了,在cpp文件开头:

#define N_TIME_SEC 1000 //一秒时间间隔
#define N_TIME_SHOW 200 //0.2s刷新显示
#define N_TIMER_SEC 1
#define N_TIMER_SHOW 2

前两个是用于SetTimer()函数的第二个参数,即产生1s和0.2s的信号来访问WM_TIMER消息响应函数。后两个是指明定时器的序号,1s的是1,0.2s的是2,分别用于进行秒加一计数和刷新显示。

void CEbbinghausDlg::OnTimer(UINT_PTR nIDEvent)

这个函数的参数就是当前来“敲门”访问的定时器序号,那么只要在内部进行一下选择,1的时候干什么,2的时候干什么就能区别处理。用switch语句即可。

我们设想按下Start后开始计时,然后数据的变化是通过1s信号访问OnTimer函数,在函数内部调整时分秒变量实现。刷新显示是第二个定时器每0.2s就访问一次OnTimer函数。

那么Start的消息函数里要SetTimer。

void CEbbinghausDlg::OnBnClickedStart()
{
// TODO: 在此添加控件通知处理程序代码
if (b_review||b_suspend)
KillTimer(N_TIMER_SEC);
b_review = FALSE;
b_suspend = FALSE;
n_hour = ;
n_minute = ;
n_second = ;
SetTimer(N_TIMER_SEC, N_TIME_SEC, NULL);
SetTimer(N_TIMER_SHOW, N_TIME_SHOW, NULL);
}

④按下Suspend暂停计时,显示当前数值但是不要清零,因为再次按下Suspend后得继续计时。

void CEbbinghausDlg::OnBnClickedSuspend()
{
// TODO: 在此添加控件通知处理程序代码
b_suspend =!b_suspend;
if (b_suspend)
{
KillTimer(N_TIMER_SEC);
KillTimer(N_TIMER_SHOW);
int h1, h2, m1, m2, s1, s2;
h1 = n_hour / ;
h2 = n_hour % ;
m1 = n_minute / ;
m2 = n_minute % ;
s1 = n_second / ;
s2 = n_second % ;
s_hour.Format("%d%d", h1, h2);
s_minute.Format("%d%d", m1, m2);
s_second.Format("%d%d", s1, s2);
UpdateData(FALSE);
}
else
{
SetTimer(N_TIMER_SEC, N_TIME_SEC, NULL);
SetTimer(N_TIMER_SHOW, N_TIME_SHOW, NULL);
}
}

OnTimer()函数就这样设计:

void CEbbinghausDlg::OnTimer(UINT_PTR nIDEvent)
{
switch (nIDEvent)
{
case :
{
if (b_review == FALSE)
{
n_second++;
if (n_second == )
{
n_second = ;
n_minute++;
}
if (n_minute == )
{
n_minute = ;
n_hour++;
}
if (n_hour == )
n_hour = ; if (n_minute == )
b_review = TRUE;
}
else if (b_review)
{
n_hour = ;
n_minute = ;
n_second = ;
s_hour.Format("%s", "Re");
s_minute.Format("%s", "vi");
s_second.Format("%s", "ew");
}
}
case :
{
if (b_review == FALSE)
{
int h1, h2, m1, m2, s1, s2;
h1 = n_hour / ;
h2 = n_hour % ;
m1 = n_minute / ;
m2 = n_minute % ;
s1 = n_second / ;
s2 = n_second % ;
s_hour.Format("%d%d", h1, h2);
s_minute.Format("%d%d", m1, m2);
s_second.Format("%d%d", s1, s2);
}
else if (b_review)
{
n_hour = ;
n_minute = ;
n_second = ;
s_hour.Format("%s", "Re");
s_minute.Format("%s", "vi");
s_second.Format("%s", "ew");
}
UpdateData(FALSE);
}
default:
break;
}
CDialogEx::OnTimer(nIDEvent);
}

⑤想弄好看点,把文本框背景弄成图片。

先添加位图资源:

OnInitDialog()函数里继续添加:

/*    位图初始化        */
CPaintDC dc(this);
CBitmap bmpBackground;
bmpBackground.LoadBitmap(IDB_BACKGROUND); //ID是你自己的图对应的ID
BITMAP bitmap;
bmpBackground.GetBitmap(&bitmap);
SetWindowPos(NULL, , , bitmap.bmWidth, bitmap.bmHeight, SWP_NOZORDER | SWP_NOMOVE);

OnPaint()函数里的else中添加:

else
{
/* 绘制背景图片 */
//CDialogEx::OnPaint();
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
// GetWindowRect(&rect);
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
CBitmap bmpBackground;
bmpBackground.LoadBitmap(IDB_BACKGROUND); //IDB_BITMAP1是背景位图对应的ID
BITMAP bitmap;
bmpBackground.GetBitmap(&bitmap);
CBitmap *pbmpOld = dcMem.SelectObject(&bmpBackground);
dc.StretchBlt(, , rect.Width(), rect.Height(), &dcMem, , , bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);//让显示区域矩形宽高和对话框大小一致,先目的后源!
}

设计完成了,效果如下:

但是编辑框的文字还有白色的背景,没做到透明,就很难受。

【MFC】利用MFC写一个计时器小程序的更多相关文章

  1. 手把手教你写一个RN小程序!

    时间过得真快,眨眼已经快3年了! 1.我的第一个App 还记得我14年初写的第一个iOS小程序,当时是给别人写的一个单机的相册,也是我开发的第一个完整的app,虽然功能挺少,但是耐不住心中的激动啊,现 ...

  2. 微信小程序——手把手教你写一个微信小程序

    前言 微信小程序年前的跳一跳确实是火了一把,然后呢一直没有时间去实践项目,一直想搞但是工作上不需要所以,嗯嗯嗯嗯嗯emmmmm..... 需求 小程序语音识别,全景图片观看,登录授权,获取个人基本信息 ...

  3. 用Taro写一个微信小程序(一)——开始一个项目

    一.Taro简介 1.名字由来 Taro['tɑ:roʊ],泰罗·奥特曼,宇宙警备队总教官,实力最强的奥特曼. 2.taro是什么 Taro 是一个开放式跨端跨框架解决方案,支持使用 React/Vu ...

  4. 利用canvas写一个验证码小功能

    刚刚开始接触canvas,写个验证码小功能练练手,实现效果图如下: 主要代码如下: html <!DOCTYPE html> <html lang="en"> ...

  5. 写一个python小程序

    在windows环境下进行操作 window+R 输入cmd  创建一个文件夹 mkdir pytxt 创建一个py文件 py.py  用notepad或者记事本等工具进行编辑 或 首先声明pytho ...

  6. 用Taro写一个微信小程序(二)——配置目录别名

    配置别名可以方便书写代码引用路径,让代码更整洁. 官方文档可参考https://nervjs.github.io/taro/docs/config-detail#alias 一.在config/ind ...

  7. 用Taro写一个微信小程序(三)—— 配置dva

    一.关于dva dva 首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch,所以也可以理解为一个轻 ...

  8. 学了C语言,如何利用CURL写一个下载程序?—用nmake编译CURL并安装

    在这一系列的前一篇文章学了C语言,如何为下载狂人写一个磁盘剩余容量监控程序?中,我们为下载狂人写了一个程序来监视磁盘的剩余容量,防止下载的东西撑爆了硬盘.可是,这两天,他又抱怨他的下载程序不好用,让我 ...

  9. 搭建Spring开发环境并编写第一个Spring小程序

    搭建Spring开发环境并编写第一个Spring小程序 2015-05-27      0个评论    来源:茕夜   收藏    我要投稿 一.前面,我写了一篇Spring框架的基础知识文章,里面没 ...

随机推荐

  1. UltraEdit的免费激活方法

    本来前段时间用UE编辑器用的好好的,然后今天突然提示我使用到期,需要购买激活.一脸懵逼中,只好再次激活,谁知道按照原来的方法激活的时候一直提示您输入的许可证id或密码错误 请您检查注册邮件并且重试. ...

  2. yii2 checkbox 的使用实例

    使用的是Yii自带的Grid,在使用checkbox希望可以把选中行的id值传到我想要的页面. 首先需要改变key值 $dataProvider->key = 'ID'; button: Htm ...

  3. uva 6910 - Cutting Tree 并查集的删边操作,逆序

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  4. 阿里Canal框架(数据同步中间件)初步实践

    最近在工作中需要处理一些大数据量同步的场景,正好运用到了canal这款数据库中间件,因此特意花了点时间来进行该中间件的的学习和总结. 背景介绍 早期,阿里巴巴B2B公司因为存在杭州和美国双机房部署,存 ...

  5. dubbo系列--重要概念介绍

    dubbo架构图 节点角色说明 整体设计 proxyFactory:就是为了获取一个接口的代理类,例如获取一个远程接口的代理.它有2个方法,代表2个作用 getInvoker:针对server端,将服 ...

  6. Android 仿百度医生的智能分诊界面

    http://blog.csdn.net/jiang89125/article/details/49622853

  7. SQL (一)定义变量以及变量赋值

    1.定义变量:declare @name varchar(20)  用declare定义一个名字为name的字符串类型的变量,变量前面需要加@ 2.为变量赋值:set @name = '%奥迪%' , ...

  8. 自制Jquery下拉框插件

    (function ($) { $.fn.select3 = function (option) { $(this).each(function () { var _this = $(this); v ...

  9. Android接入支付宝和微信支付

    然后把下载下来的aar包,放到项目目录下面的libs目录下,通过下面的gradle依赖进来 // 支付宝 SDK AAR 包所需的配置compile(name: 'alipaySdk-15.6.0-2 ...

  10. docker 的容器入门

    Linux Namespace LXC所实现的隔离性主要是来自kernel的namespace, 其中pid, net, ipc, mnt, uts 等namespace将container的进程, ...