Visual_C++基于对话框的MFC应用程序【简单时钟】
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.1创建对话框的应用程序
1.使用AppWizard创建应用程序框架
首先,创建一个对话框应用程序,其工程文件名为:ch1.dsp。
具体步骤如下:
(1)启动Visual C++6.0,在File菜单中选择new菜单项;(2)在new对话框的Project页中选择MFC AppWizard(exe)选项,在Project name框中输入:ch1,并在Location框中指定希望的目录路径,编译系统生成的各种文件将会存放在该目录下,然后点击[OK]按钮
(3)MFC AppWizard-Step1中选择Dialog based选项,MFC AppWizard-Step2到MFC AppWizard-Step4中取默认选项;(4)进入VC对话框设计界面后,选中[TODO:在这里设置对话控制。
]静态框并按del键删除该框,选中[取消]按钮并按del键删除该按钮;(5)将[确认]按钮拖曳到对话框的下方中间。
生成的对话框设计窗口(如图1-1所示)。
图1-1
2.向类中添加系统消息响应函数
Windows应用程序的采用事件触发、消息驱动机制和大量的消息响应函数构成了应用程序的主体。
本示例需要用到两个消息响应函数OnCtlColor()和OnTimer(),前者响应窗口消息:WM_CTLCOLOR,后者响应窗口消息:WM_TIMER。
关于这两个函数的功能和用法暂且略过,留待后面小节再叙。
这里先介绍响应函数加载的方法。
在CCh1Dlg类中添加OnCtlColor()函数的操作方法如下:(1)打开类向导(MFC ClassWizard)窗口,选择Message Maps 页;
(2)选择工程、类和对象标识。
在Message Maps页的Project、Class name、Object Ids框中
分别选择:ch1、CCh1Dlg、CCh1Dlg;
(3)添加响应函数。
在Message Maps页的Messages框中选中并双击窗口消息:WM_CTLCOLOR,此时,消息WM_CTLCOLOR 的响应函数OnCtlColor()被添加到类向导底部Member Functions框中。
注意,添加OnTimer()函数的过程与上述过程相似,只是第(3)步选择WM_TIMER消息,而不是WM_CTLCOLOR。
添加完毕后,按[OK]按钮退出类向导。
回到项目工作区,在项目工作区窗口展开CCh1Dlg类,可以看到类中添加了OnCtlColor()和OnTimer()两个消息响应函数。
1.2静态框控件
1.静态框控件与CStatic类
静态框的功能是通过MFC类库中的CStatic类实现的。
静态框可以用来显示文本、位图或图元文件等。
示例ch1中的日历框和时钟框就是通过静态控件实现的,为此,下面将围绕示例介绍静态控件使用方法。
首先在对话框中添加一个显示内容为“当前时间”的静态框,步骤如下:
(1)添加静态框。
参考图1-1,用鼠标器单击右边控件工具栏中静态控件(Static Text)按钮,通过鼠标在对话框左边偏上的位置上拖曳出一个静态框,调整静态框到合适的大小;
(2)打开静态控件属性对话框。
右击该静态框,从弹出菜单中选择属性(Properties)菜单项,弹出属性(Text
Properties)对话框;
(3)更改静态框中文本内容。
在属性对话框中选择General 页,将Caption框的内容修改为:当前时间:
(4)单击属性对话框右上角的关闭按钮,关闭属性对话框。
接着添加一个显示内容为“00:00:00”的时钟静态框:(1)重复上面(1)、(2)两步操作,在“当前时间:”静态框下方添加一个新的静态框;
(2)更改静态控件标识符和文本内容。
在属性对话框中选择General页,将ID框的标识符
IDC_STATIC改为:IDC_STATIC1,将Caption框的内容修改为:00:00:00;
(3)设置文本对齐方式。
在属性对话框中选择Styles页,从Align text列表框中选择Center
选项、在多选框中选中Center Vertically选项;
(4)设置边框样式。
在属性对话框中选择Extended Styles 页,选中Static edge项;
(5)单击属性对话框右上角的关闭按钮,关闭属性对话框。
最后,按上述方法在对话框的右侧添加一个日历静态框,其属性参数设置如下:
(1)在属性对话框中选择General页,将ID框的标识符IDC_STATIC改为:IDC_STATIC2,
将Caption框的内容修改为:
\n2004年03月\n\n12日\n\n星期五
其中“\n”表示换行,而插入空格是为了调整日期显示的位置;
(2)在属性对话框中选择Styles页,从Align text列表框中选择Left选项;
(3)在属性对话框中选择Extended Styles页,选中Modal frame项。
对话框界面设计(如图1-2所示)。
图1-2
2.更改静态框文本内容
程序运行时,用户无法通过键盘输入更改静态框的内容。
如需要动态地变更静态框的内容,可通过编程来实现。
为此需要在CCh3_1Dlg类中添加两个分别与IDC_STATIC1、IDC_STATIC2静态控件相关成员变量,操作如下:
(1)在View菜单中选择ClassWizard菜单项,打开类向导
(MFC ClassWizard)窗口,并选择Member Variables页;(2)添加成员变量m_Static1。
在Member Variables页的Control Ids框中选择标识符IDC_STATIC1,并点击[Add Variables…]按钮,弹出添加成员变量(Add Member Variables)对话框,在成员变量名(Member variables name)框内输入:m_Static1,并在种类(Category)、变量类型(Variable type)框内依次输入或选择:Control、CStatic。
按[OK]按钮,退出添加成员变量对话框;
(3)添加成员变量m_Static2。
在Member Variables页的Control Ids框中选择标识符IDC_STATIC2,并点击[Add Variables…]按钮,弹出添加成员变量(Add Member Variables)对话框,在成员变量名(Member variables name)框内输入:m_Static2,并在种类(Category)、变量类型(Variable type)框内依次输入或选择:Control、CStatic。
按[OK]按钮,退出添加成员变量对话框;
(4)按[OK]按钮,退出类向导(MFC ClassWizard)窗口。
在项目管理区中双击CCh1Dlg类,这时程序代码窗口CCh1Dlg 类的头文件中,可以看到如下代码:
//Dialog Data
//{{AFX_DATA(CCh1Dlg)
enum{IDD=IDD_CH1_DIALOG};
CStatic m_Static2;//由类向导自动插入
CStatic m_Static1;
//}}AFX_DATA
其中插入了CStatic类型的成员变量m_Static1,该变量为静态控件对象,它通过标识符IDC_STATIC1与图1-2中所示的时钟静态框对应,而m_Static2则通过标识符IDC_STATIC2与日历框对应。
在项目管理区中展开CCh3_1Dlg类,双击OnInitDialog()函数,代码编辑窗口出现该函数
的代码,在该函数的结尾部分加上如下代码:
BOOL CCh1Dlg::OnInitDialog()
{
CDialog::OnInitDialog()
……
//TODO:Add extra initialization here
CString str=_T("10:10:10");
m_Static1.SetWindowText(str);//更改时钟框的内容return TRUE;//return TRUE unless you set the focus to a control
重新编译链接该程序,执行后时钟框显示的内容为:10:10:10。
3.如何获取当前时间
为了使该静态框能正确显示当前时间,必须要解决两个问题,首先是如何获取当前系统时间,其次是如何才能不断及时地刷新时钟框的时间。
在MFC应用程序中,不但可以调用Windows API函数,也可以使用C语言运行库函数time_t time(time_t*timer);和struct tm*localtime(const time_t*timer);要及时地刷新时钟框,需要有相应事件来触发。
为此,可以通过加载系统定时器消息WM_TIMER的响应函数OnTimer()来实现,用户可以通过SetTimer()函数设定定时值,这样当定时时间一到,函数OnTimer()就会自动响应。
我们已经在CCh1Dlg类中加载了OnTimer()函数,在项目管理工作区中展开CCh1Dlg类,双击OnTimer(),将程序代码区的光标移到该函数,加入如下代码:
void CCh1Dlg::OnTimer(UINT nIDEvent)
{
//TODO:Add your message handler code here and/or call default
time_t m_time;
tm*t;
int hour,hour1,min,sec;
int year,mon,day,week;
CString s;
CString s1[7]={"日","一","二","三","四","五","六"};
time(&m_time);//获取当前时间值存入m_time
t=localtime(&m_time);//转换为tm结构类型
hour=t->tm_hour;
min=t->tm_min;
sec=t->tm_sec;
hour1=hour%12;//24小时制转换成12小时制
year=t->tm_year+1900;
mon=t->tm_mon+1;
day=t->tm_mday;
week=t->tm_wday;
s.Format("%02d:%02d:%02d",hour,min,sec);
//将当前时钟送到IDC_STATIC1静态框显示
m_Static1.SetWindowText(s);
s.Format("\n%4d年%2d月\n\n%2d日\n\n 星期",year,mon,day);
s+=s1[week];
//将当前日历送到IDC_STATIC2静态框显示
m_Static2.SetWindowText(s);
SetTimer(0,500,NULL);//重置定时器
CDialog::OnTimer(nIDEvent);
}
为了启动系统定时器,须在CCh1Dlg类的初始化函数OnInitDialog()中加入SetTimer()函数,插入的位置如下://TODO:Add extra initialization here
CString str=_T("10:10:10");
m_Static1.SetWindowText(str);//更改时钟框的内容SetTimer(0,500,NULL);//重置定时器
return TRUE;//return TRUE unless you set the focus to a control
}
编译、运行后如下图
4.设置静态框字符和背景的颜色
静态控件框字符和背景一般使用系统默认的颜色,但也
可以改变默认设置,选择用户所需的色彩。
为了改变控件的颜色,一般需要在控件的父窗口(通常是对话框)中添加一个窗口响应函数OnCtlColor()。
当控件需要重画时,OnCtlColor()函数会被自动调用,此函数专门用于更改窗口、字符、字符背景颜色或窗口底色。
现在,通过本示例介绍该函数的使用方法。
回到项目工作区,在项目工作区窗口展开CCh1Dlg类,双击响应函数OnCtlColor()。
代码窗口的光标被移到OnCtlColor()处,为了改变静态控件IDC_STATIC1字符和背景的颜色,只需在该函数中加入如下代码即可实现:
HBRUSH CCh1Dlg::OnCtlColor(CDC*pDC,CWnd*pWnd,UINT nCtlColor)
{
HBRUSH hbr=CDialog::OnCtlColor(pDC,pWnd, nCtlColor);
//TODO:Change any attributes of the DC here
HBRUSH m_brush;//定义画刷句柄
switch(nCtlColor)
{
case CTLCOLOR_STATIC://改变静态控件字符的和背景颜色
//判断当前重画的控件是否为IDC_STATIC
if(pWnd->m_hWnd==m_Static1.m_hWnd||
pWnd->m_hWnd==m_Static2.m_hWnd)
{
pDC->SetBkMode(TRANSPARENT);//设置透明模式
pDC->SetTextColor(RGB(255,255,0));//设置字符为黄色
m_brush=CreateSolidBrush(RGB(0,0,255));//创建蓝色画刷
return m_brush;//用蓝色画刷重画控件底色}
break;
}
//TODO:Return a different brush if the default is not desired
return hbr;
}
运行程序,时钟框和日历框出现了蓝底黄字(如图1-3
所示)。
图1-3
1.3按钮控件
1.按钮控件与CButton类
按钮控件是Windows应用程序中常用的控件,用户通过单击按钮产生一个事件,从而该按钮的响应函数被激励运行,完成预定的功能。
现在我们为CCh1Dlg类添加一个按钮控件,按钮标题:更改
步骤如下:
(1)添加按钮。
用鼠标器单击右边控件工具栏中按钮控件(Button)按钮,通过鼠标在时钟框的下方拖曳出一个按钮,调整按钮到合适的大小;
(2)打开按钮控件属性对话框。
右击该按钮,从弹出菜单中选择属性(Properties)菜单项,弹出属性(Text Properties)对话框;
(3)更改按钮文本内容。
在属性对话框中选择General页,ID框的标识符IDC_BUTTON1保持不变,将Caption框的内容修改为:更改;
(4)单击属性对话框右上角的关闭按钮,关闭属性对话框;(5)右击[确认]按钮,从弹出菜单中选择属性(Properties)菜单项,弹出属性(Text Properties)对话框;
(6)在属性对话框中选择General页,ID框的标识符IDOK 保持不变,将Caption框的内容修改为:返回;
(7)单击属性对话框右上角的关闭按钮,关闭属性对话框。
最后的设计界面(如图1-4所示)。
图1-4
2.按钮响应函数
可以方便地为CCh1Dlg类添加按钮的响应函数。
操作如下:(1)参阅图1-4,双击[更改]按钮,弹出Add Member Function对话框;
(2)在Add Member Function对话框中输入成员函数名:OnButton1;
(3)按[OK]按钮,退出Add Member Function对话框。
下面将通过该按钮实现如下功能:
程序以两种方式显示当前时间,一种是24小时制,蓝底黄字;另一种是12小时制,黄底蓝字。
要求通过单击[更改]按钮能在两种显示方式之间切换。
为此,程序设计如下:(1)在CCh1Dlg类的头文件中增加一个整型的成员变量flag,当flag=0时,以第一种方式显示;当flag=1时,以
第二种方式显示。
变量flag插入位置如下所示:
class CCh1Dlg:public CDialog
{
……
//Implementation
protected:
int flag;插入的变量
HICON m_hIcon;
……
}
(2)成员变量flag为局部变量,在未赋初值之前,其值为一随机数。
因此需要在对话框初
始化函数OnInitDialog()中添加一句:flag=0;即初始化为第一种显示方式。
插入的位置如下
所示:
BOOL CCh1Dlg::OnInitDialog()
{
CDialog::OnInitDialog()
……
//TODO:Add extra initialization here
CString str=_T("10:10:10");
m_Static1.SetWindowText(str);插入的代码
flag=0;//以第一种方式显示时钟
SetTimer(0,500,NULL);
return TRUE;//return TRUE unless you set the focus to a control
}
(3)由于静态框字符和底色参数的设置由变量flag的值而决定,所以对更改颜色的响应函
数OnCtlColor()的代码要作适当修改,修改后的代码如下所示:
HBRUSH CCh1Dlg::OnCtlColor(CDC*pDC,CWnd*pWnd,UINT nCtlColor)
{
HBRUSH hbr=CDialog::OnCtlColor(pDC,pWnd, nCtlColor);
//TODO:Change any attributes of the DC here HBRUSH m_brush;
switch(nCtlColor)
{
case CTLCOLOR_STATIC:
if(pWnd->m_hWnd==m_Static1.m_hWnd
||pWnd->m_hWnd==m_Static2.m_hWnd)
{
pDC->SetBkMode(TRANSPARENT);
if(flag==0)//flag=0,设置黄字、蓝底{
pDC->SetTextColor(RGB(255,255,0));修改后的代码
m_brush=CreateSolidBrush(RGB(0,0,255));
}
else//flag!=0,设置蓝字、黄底
{
pDC->SetTextColor(RGB(0,0,255));
m_brush=CreateSolidBrush(RGB(255,255, 0));
}
return m_brush;//重画控件底色的刷子}
break;
}
//TODO:Return a different brush if the default is not desired
return hbr;
}
对OnTimer()函数也要作相应的改动,使之能根据变量flag 的值按不同的时制显示当前时间。
修改方法如下所示:
将OnTimer()函数中下列语句
s.Format("%02d:%02d:%02d",hour,min,sec);//按24小时制格式化字符串更改为:
if(flag==0)
s.Format("%02d:%02d:%02d",hour,min,sec); //按24小时制格式化字符串
else
{
s.Format("%02d:%02d:%02d",hour1,min, sec);//按12小时制格式化字符串
if(hour>=12)s+="PM";
else s+="AM";
}
(4)颜色与时制的切换通过单击按钮IDC_BUTTON1来实现,因此需在其响应函数
OnButton1()中加入切换功能的代码,这个切换是通过控制变量flag的值实现的。
添加的代码如下所示:
void CCh1Dlg::OnButton1()
{
//TODO:Add your control notification handler code here
if(flag==0)flag=1;//如果是蓝底黄字,则切换到黄字蓝底
else flag=0;//否则切换到蓝底黄字添加的代码
m_Static1.Invalidate(true);//要求重画时钟框m_Static2.Invalidate(true);//要求重画日历框}
将修改后的程序重新编译链接,启动运行,结果如图1-5、图1-6所示。
图1-5
图1-6。