1.设计目标
了解Windows应用程序的结构与DOS程序的不同,掌握应用MFC类库编写Windows应用程序的基本模式。
2.设计内容
以简易计算器为例,通过对简单应用软件计算器的设计,编制、调试,实现简单的加,减,乘,除等运算,以学习应用MFC库类编写对话框的原理,加深对C++类的学习及应用。
3. 设计思想
基于MFC库类对对话框界面的设计,通过创建类成员函数成员变量,编辑控件创建消息映射,调用消息函数完成数据的输入输出,实现计算功能。生成简单的应用软件。
4. 设计说明
(1)包含的功能有:加、减、乘、除运算,开方、平方等功能。
(2)计算器上数字0—9为一个控件数组,加、减、乘、除为一个控件数组,其余为单一的控件。
(3)输入的原始数据、运算中间数据和结果都显示在窗口顶部的同一个标签中。
(4)计算功能基本上是用系统内部函数。
(5)程序可以能自动判断输入数据的正确性,保证不出现多于一个小数点、以0开头等不正常现象。
(6)“CE”按钮可以清除所有已输入的数据从头计算
5. 设计步骤
(1)选择FileNewlProject命令,选择MFC AppWizard(exe)创建Project名为Caa,按确定。在d出界面选择创建对话框,单击Finish按钮
(2)在生成的设计界面中加入控件,得到计算器应用界面。如图:
(3)为控件编辑框编辑ID,如图:
按钮名称 ID 用途
0 IDC_0 按键0
1 IDC_1 按键1
2 IDC_2 按键2
3 IDC_3 按键3
4 IDC_4 按键4
5 IDC_5 按键5
6 IDC_6 按键6
7 IDC_7 按键7
8 IDC_8 按键8
9 IDC_9 按键9
. IDC_dian 按键 .
+/- IDC_zhengfu 正负
+ IDC_jia 加
- IDC_jian 减
* IDC_cheng 乘
/ IDC_chu 除
CE IDC_qinglin 清零
sqrt IDC_sqrt 开方
x*x IDC_pingfang 平方
= IDC_dengyu 等于
编辑框 IDC_E1 显示数据输入输出
(4)进入ClassWizard界面选择Message Maps为控件插入消息映射,插入消息函数,实现控件命令功能。如图:
(5) 进入ClassWizard界面Message Varibles为编辑框添加成员变量m_result用以显示结果。如图:
(6)在CaaDlg.h中加入在主要成员函数和成员变量的申明在CaaDlg.cpp中加入主要成员函数实现过程和成员变量的初始化(代码片段将于后裤宴带面介绍)。
6. 主要成员函数关系图
7. 程序主要代码
//在头文件中手动添加成员函数与变量声明
// caaDlg.h : header file
//定义两个euum型结构
enum Operator { OpNone, OpAdd, OpSubtract, OpMultiply, OpDivide }
enum CalcError { ErrNone, ErrDivideByZero }
float m_operand //存储当前输入的 *** 作数
float m_accum //存储当前的计胡芦算处理结束
BOOL m_bCoff //标识当前输入是否是小数
float m_coff //小数输入时的系数
Operator m_operator //enum型变量用以标识当前运算符
CalcError m_errorState //enum型变量用以标识当前运算状态
BOOL m_bOperandAvail //标识当前输入是否是新输入数字
void UpdateDisplay() //处理显示祥滑
void Calculate() //处理计算
void OnOperandInput(int a)//处理数字输入
//在执行文件中添加成员函数实现部分与变量初始
// caaDlg.cpp : implementation file
//以下是对声明变量进行初始
CCaaDlg::CCaaDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCaaDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCaaDlg)
m_result = _T("") //默认为m_result变量初始
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME)
m_coff=0.1 //为变量进行初始
m_bCoff=0 //为变量进行初始
m_errorState = ErrNone //为变量进行初始
m_bOperandAvail=FALSE //为变量进行初始
m_operator=OpNone //为变量进行初始
}
//以下是消息处理函数,用以响应消息映射
void CCaaDlg::On0() //处理“ 0”按钮
{
// TODO: Add your control notification handler code here
OnOperandInput(0)
}
void CCaaDlg::On1() //处理“ 1”按钮
{
// TODO: Add your control notification handler code here
OnOperandInput(1)
}
void CCaaDlg::On2() //处理“ 2”按钮
{
// TODO: Add your control notification handler code here
OnOperandInput(2)
}
void CCaaDlg::On3() //处理“ 3”按钮
{
// TODO: Add your control notification handler code here
OnOperandInput(3)
}
void CCaaDlg::On4() //处理“ 4”按钮
{
// TODO: Add your control notification handler code here
OnOperandInput(4)
}
void CCaaDlg::On5() //处理“ 5”按钮
{
// TODO: Add your control notification handler code here
OnOperandInput(5)
}
void CCaaDlg::On6() //处理“ 6”按钮
{
// TODO: Add your control notification handler code here
OnOperandInput(6)
}
void CCaaDlg::On7() //处理“ 7”按钮
{
// TODO: Add your control notification handler code here
OnOperandInput(7)
}
void CCaaDlg::On8() //处理“ 8”按钮
{
// TODO: Add your control notification handler code here
OnOperandInput(8)
}
void CCaaDlg::On9() //处理“ 9”按钮
{
// TODO: Add your control notification handler code here
OnOperandInput(9)
}
void CCaaDlg::Oncheng() //处理“ *”按钮
{
// TODO: Add your control notification handler code here
Calculate()
m_operator = OpMultiply
}
void CCaaDlg::Onchu() //处理“ /”按钮
{
// TODO: Add your control notification handler code here
Calculate()
m_operator = OpDivide
}
void CCaaDlg::Ondengyu()//处理“ =”按钮
{
// TODO: Add your control notification handler code here
Calculate()
m_operator = OpNone
}
void CCaaDlg::Ondian() //处理“ .”按钮
{
// TODO: Add your control notification handler code here
m_bCoff=1
UpdateDisplay()
}
void CCaaDlg::Onjia() //处理“ +”按钮
{
// TODO: Add your control notification handler code here
Calculate()
m_operator = OpAdd
}
void CCaaDlg::Onjian() //处理“ -”按钮
{
// TODO: Add your control notification handler code here
Calculate()
m_operator = OpSubtract
}
void CCaaDlg::Onpingfang()//处理“ x*x”按钮
{
// TODO: Add your control notification handler code here
m_operand*=m_operand
UpdateDisplay()
}
void CCaaDlg::Onqinglin() //处理“ CE”按钮
{
// TODO: Add your control notification handler code here
m_operator = OpNone
m_operand = 0
m_accum = 0
m_bOperandAvail = FALSE
m_errorState = ErrNone
m_coff=0.1
m_bCoff=0
UpdateDisplay()
}
void CCaaDlg::Onsqrt() //处理“ sqrt”按钮
{
// TODO: Add your control notification handler code here
m_operand=sqrt(m_operand)
UpdateDisplay()
}
void CCaaDlg::Onzhengfu() //处理“ +/-”按钮
{
// TODO: Add your control notification handler code here
m_operand*=-1
UpdateDisplay()
}
//以下是自定义函数,用于实现计算功能
void CCaaDlg::OnOperandInput(int a) //处理0-9 数字的输入函数
{ if (m_errorState != ErrNone)//判断当前运算是否有误,若有则返回
return
if (!m_bOperandAvail) //判断是否输入新的数字,1-是 0-否
m_operand = 0
if(!m_bCoff) //判断是否是小数输入,1-是 0-否
m_operand=m_operand*10+(a)
else
{
m_operand=m_operand+(a)*m_coff
m_coff*=0.1
}
m_bOperandAvail=TRUE
UpdateDisplay() //更新显示
}
void CCaaDlg::Calculate() //处理计算函数
{
if (m_errorState != ErrNone)
return
if (m_bOperandAvail)
{
//如果没有计算符就将m_operand值赋予m_accum
if (m_operator == OpNone)
m_accum = m_operand
else if (m_operator == OpMultiply) //否则按计算符进行计算
m_accum *= m_operand
else if (m_operator == OpDivide)
{
if (m_operand == 0)
m_errorState = ErrDivideByZero
else
m_accum /= m_operand
}
else if (m_operator == OpAdd)
m_accum += m_operand
else if (m_operator == OpSubtract)
m_accum -= m_operand
}
m_bOperandAvail = FALSE
m_bCoff=0
m_coff=0.1
UpdateDisplay()
}
void CCaaDlg::UpdateDisplay() //处理显示函数
{
if (GetSafeHwnd() == NULL)
return
if (m_errorState != ErrNone)
m_result="除数不能为零"
else //如果当前计算无错误那么进行显示
{
//如果是输入计算数,那么显示输入情况,如果按下计算符,则显示结果
float lVal = (m_bOperandAvail) ? m_operand : m_accum
m_result.Format(_T("%f"), lVal)//将float型转化为CString型
int i=m_result.GetLength()
while(m_result.GetAt(i-1)=='0')
{
m_result.Delete(i-1,1)
i-=1
}
}
//用编辑控件变量m_result改变编辑控件的值,更新显示
UpdateData(FALSE)
}
8. 难点分析
在利用MFC编写计算器过程中,遇到的技术上的问题,及解决方法。
例如:
⑴.计算数输入的处理
在程序中使用m_operand来存储当前的输入。而程序只使用一个函数来处理所有数字输入,也就是说每次单击数字按钮就会调用该函数。由于计算数不仅仅是个位数,因此用户可能需要单击几个数字按钮来完成一个计算数的输入,这样在每次输入时都必须将输入的数字累加入m_operand中。而且对于小数输入和整数输入也必须采取不同的累加方式。如对整数的输入,累加方式为:
m_operand=m_operand*10+n其中n为输入的数字。而对于小数输入,累加方式为:m_operand=m_operand+n*10i
其中n为数字,i为小数位数。因此在程序中还需设立布尔型变量m_coff 的值来标识当按下按钮小数点的时候来确定调用哪个累加方式。
⑵.自定义消息处理函数、成员函数、变量
在添加自定义函数、变量时需注意函数及变量的声明在头文件中如:CaaDlg.h ;而函数的实现部分及变量的初始在执行文件中如:CaaDlg.cpp 。
值得提醒的是手动添加消息处理函数时,需声明在头文件//{{AFX_MSG(CCaaDlg) …//}}AFX_MSG中的部分。
而添加消息映射在执行文件
//{{AFX_MSG_MAP(CCaaDlg) …//}}AFX_MSG_MAP中的部分。
最后将消息处理函数添加到执行文件末即可。
很简单啦,你要关联对话框,其实就是关联对话框的类,要闷信橡把对话框的类关联到视图文件中,
比如,先把#include "C....dlg.h"//对话框类的头文件加在视图cpp文件开始处,
然后再视图文件的某个事件函数中:
C.....dlg dlg;//声明一个对象,用来 *** 作该对话框
dlg.DoModal();//要看到对话框,就要用坦芹DoModal()d出它
m_xx=dlg.m_sEdit;//m_xx为视图类中的某个变量,
这样得到对话框中的编辑框变量,这样就关联了嘛,
其实就是用dlg对象去进行蚂旁 *** 作。
用ShowScrollBar可芦誉嫌以显示滚动条。虚手SetScrollRange设置滚动陪手范围。
响应消息WM_VSCROLL和WM_HSCROLL。
可能需要移动控件的位置,再重绘。
自己处理有点麻烦,建议改用CFormView。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)