【基于VS2010的MFC编程】多功能计算器

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/gfy571127/article/details/45722007

平台/工具:VS2010
目的:利用VS2010平台创建一个MFC工程,实现多功能计算器的程序编写和界面设计
项目分析:首先是根据功能进行界面设计:需要一个供编辑和显示的编辑框 、多种运算符按钮(“+”“-”“×”“÷”“平方”“开方”“指数”“log”)、0~9数字按钮、“=”和“.”按钮、辅助功能按钮(“关于软件”“清零”“后退”);其次是添加一些类和功能代码”

方法步骤:
Step 1: MFC工程创建部分
建立一个不使用Unicode库的MFC工程,工程命名为“多功能计算器”。

这里写图片描述
注意:Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。(百度百科)
但是使用该库时,汉字等字符需要在前面加上“_T”,比较麻烦,为了简便,不选择该库。

Step 2:主对话框设计部分
(1)建立好基于对话框的工程后,将默认主对话框上的几个控件均删除:删除“TODO: 在此放置对话框控件。” 删除“确定”“取消”按钮。


(2)添加编辑框(Edit Control)控件到主对话框顶部,用于显示用户的输入以及计算结果,拖动修改其大小;选中该编辑框->右键->添加变量->Control类别对应的变量类型为CEdit,变量名为m_edit, Value类别对应的变量类型为CString,变量名为m_str,如下两图所示:

这里写图片描述
这里写图片描述

(3)添加按钮控件到主对话框,调整按钮大小,为了保持大小一致,可以先添加一个按钮,然后复制粘贴。编辑按钮的Caption属性为适当的名字,数字按钮的ID改为IDC_NUM_0、IDC_NUM_1…… IDC_NUM_9;操作符按钮的ID改为IDC_ADD,IDC_DEC,IDC_MULTIPLY,IDC_DIVIDE (上述分别为“+”“-”“×”“÷”的ID),IDC_SQUARE,IDC_SQRT,IDC_EXP,IDC_LOG (上述为“平方”“开方”“指数”“log”的ID);“关于软件”的ID为IDC_ABOUT_BUTTON,“后退”的ID为IDC_BACK_BUTTON,“清零”的ID为IDC_CLEAR_BUTTON,“=”的ID为IDC_EQUAL,“.”的ID为IDC_DEMICAL。设计完成的主对话框如下图所示:

这里写图片描述

Step 3:代码添加部分
设计好主对话框后,开始双击按钮进入主程序中相应的位置,添加消息处理程序。
(1)首先在××Dlg.h(主程序头文件,××是你建立的工程名,如工程名为“多功能计算器”,则主程序头文件为“多功能计算器Dlg.h”)中主对话框类中的公有成员(public:)中添加代码,如下图所示,红框内为手动添加的代码:

这里写图片描述
(2)在××Dlg.cpp主程序中添加如下代码:
①在程序顶部包含cmath头文件:#include “cmath”(因为开方函数sqrt()、指数函数pow()需要该头文件)
②在初始化函数BOOL C多功能计算器Dlg::OnInitDialog()中添加m_edit.SetWindowText(“”);将编辑框初始化为空

这里写图片描述

③双击主对话框中的按钮,主程序会自动添加其消息响应函数,在函数体中添加实现代码:
A、“关于软件”按钮的代码:

void C多功能计算器Dlg::OnBnClickedAboutButton()     //“关于软件”按钮
{
    // TODO: 在此添加控件通知处理程序代码
//----添加的代码----------------- 
    CAboutDlg dlg;
    dlg.DoModal();
//此处没有做过多的编辑,直接调用MFC程序创建时系统自动生成的“关于”对话框
//--------------------------------
}


B、“后退”按钮的代码:

void C多功能计算器Dlg::OnBnClickedBackButton()   //“后退”按钮
{
    // TODO: 在此添加控件通知处理程序代码
//---------添加的代码------
    UpdateData(TRUE);
    if (!m_str.IsEmpty())      
    {
        m_str = m_str.Left(m_str.GetLength()-1);  //移除最右边一个字符
    }
    UpdateData(FALSE);
//--------------------------
}


C、“清零”按钮的代码:

void C多功能计算器Dlg::OnBnClickedClearButton()   //“清零”按钮
{
    // TODO: 在此添加控件通知处理程序代码
//------------添加的代码------------
    UpdateData(TRUE);
    m_str = "";         //将对话框设为空,即达到清零的效果
    UpdateData(FALSE);
//-----------------------------------
}


D、四则运算符(“+”“-”“×”“÷”)按钮的代码:

void C多功能计算器Dlg::OnBnClickedAdd()      //“+”按钮
{
    // TODO: 在此添加控件通知处理程序代码
//----添加的代码------------
    SaveValue1();    //执行SaveValue1()函数,保存第一个数值并在按下操作符按钮后、第二个数值输出之前使编辑框空白
    m_iSign = 0;     //“+”的标志,用于Calculator()函数中case的跳转判断
//----------------------------
}

void C多功能计算器Dlg::OnBnClickedDec()     //“-”按钮
{
    // TODO: 在此添加控件通知处理程序代码
//----添加的代码------------
    SaveValue1();
    m_iSign = 1;      //“-”的标志,用于Calculator()函数中case的跳转判断
//----------------------------
}

void C多功能计算器Dlg::OnBnClickedMultiply()  //“×”按钮
{
    // TODO: 在此添加控件通知处理程序代码
//----添加的代码------------
    SaveValue1();
    m_iSign = 2;     //“×”的标志,用于Calculator()函数中case的跳转判断
//----------------------------
}

void C多功能计算器Dlg::OnBnClickedDivide()  //“÷”按钮
{
    // TODO: 在此添加控件通知处理程序代码
//----添加的代码------------
    SaveValue1();
    m_iSign = 3;   //“÷”的标志,用于Calculator()函数中case的跳转判断
//----------------------------
}


E、“平方”“开方”“指数”“log”按钮的代码:

void C多功能计算器Dlg::OnBnClickedSquare()   //“平方”按钮
{
    // TODO: 在此添加控件通知处理程序代码
//----------添加的代码----------------
    UpdateData(TRUE);
    m_fNumber1 = atof(m_str);   //由于只有一个操作数,因此不需要等到“=”按下时才在编辑框显示结果,因此不用添加到Calculator()函数中
    double f = m_fNumber1 * m_fNumber1;
    //如果浮点数其实是个整数
    if(f - int(f) <= 1e-5)
    {
        m_str.Format("%d",(int)f);
    }
    else
    {
        m_str.Format("%f",f);
    }
    UpdateData(FALSE);
//-----------------------------
}

void C多功能计算器Dlg::OnBnClickedSqrt()    //“开方”按钮
{
    // TODO: 在此添加控件通知处理程序代码
//------------添加的代码-----------------
    UpdateData(TRUE);
    m_fNumber1 = atof(m_str);    
    double f = sqrt(m_fNumber1);
    //如果浮点数其实是个整数
    if(f - int(f) <= 1e-5)
    {
        m_str.Format("%d",(int)f);
    }
    else
    {
        m_str.Format("%f",f);
    }
    UpdateData(FALSE);
//-------------------------
}

void C多功能计算器Dlg::OnBnClickedExp()     //“指数”按钮,需要两个操作数,“指数”按钮表示实行pow计算,即结果为m_fNumber1^m_fNumber2
{
    // TODO: 在此添加控件通知处理程序代码
    SaveValue1();
    m_iSign = 6;
}

void C多功能计算器Dlg::OnBnClickedLog()   //以10为底的对数(常用对数)
{
    // TODO: 在此添加控件通知处理程序代码
    UpdateData(TRUE);
    m_fNumber1=atof(m_str);
    double f=log10(m_fNumber1);
    if(f-(int)f<=1e-5)  //如果浮点数实际上是整型数时
    {
        m_str.Format("%d",(int)f);  //将整数转换为字符
    }
    else
        m_str.Format("%f",f);  //将浮点数转换为字符
    UpdateData(FALSE);
}


F、数字按钮的代码(以数字1按钮为例,其他数字类似):

void C多功能计算器Dlg::OnBnClickedNum1()   //数字“1”按钮
{
    // TODO: 在此添加控件通知处理程序代码
//-------------添加的代码-----------------
    UpdateData(TRUE);
    m_str = m_str + "1";
    UpdateData(FALSE);
//-------------------------------------
}


G、“=”代码:

void C多功能计算器Dlg::OnBnClickedEqual()  //“=”按钮,当按下该按钮时执行之前按下的对应操作符的计算
{
    // TODO: 在此添加控件通知处理程序代码
//---------添加的代码-------------
    UpdateData(TRUE); 
//m_iSign=0~3分别对应“+”“-”“×”“÷”,m_iSign=6对应“指数”
    if(m_iSign!=0&&m_iSign!=1&&m_iSign!=2&&m_iSign!=3&&m_iSign!=6)  
    {
        m_fNumber1 = atof(m_str);  
    }
//当单击输入某一个数值而没有单击操作符按钮(“+”“-”“×”“÷”“指数”)、直接单击“=”时,界面上保持显示第一个操作数
    else
    Calculator();
    UpdateData(FALSE);
//-------------------------------
}


H、“.”按钮的代码:

void C多功能计算器Dlg::OnBnClickedDemical()  //小数点“.”按钮
{
    // TODO: 在此添加控件通知处理程序代码
//----------添加的代码-------------------
    UpdateData(TRUE);
//如果没有小数点,则加上一个小数点,如果已有小数点就忽略此次的小数点,保证最多只有1个
    if (-1 == m_str.Find('.'))
    {
        m_str = m_str + ".";
    }
    UpdateData(FALSE);
//--------------------------------------
}


I、自定义函数:

//自定义函数,用于保存并隐藏第一个操作数,使得输入第一个数,按下第二个数之前,编辑框处于空白状态
void C多功能计算器Dlg::SaveValue1()   
{
    UpdateData(TRUE);
    m_fNumber1 = atof(m_str);   //编辑框显示第一个操作数
    m_str = "";       //做完上步操作后将编辑框设置为空
    UpdateData(FALSE);
}

//计算,涉及到两个操作数,按下“=”时执行。包括“+”,“-”“×”“÷”“指数”
void C多功能计算器Dlg::Calculator()   
{
    UpdateData(TRUE);
    m_fNumber2 = atof(m_str);      //获得第二个操作数并显示在编辑框中
    double f = 0.0f;    //f必须初始化,用于保留计算结果
    switch (m_iSign)   //根据m_iSign标志跳转
    {   
    case 0:
        f = m_fNumber1 + m_fNumber2;//加
        break;
    case 1:
        f = m_fNumber1 - m_fNumber2;//减
        break;
    case 2:
        f = m_fNumber1 * m_fNumber2;//乘
        break;  
    case 3:
        if (m_fNumber2 == 0.0f)  //除法中分母不能为0,为0时需要进行如下操作
        {
            MessageBox("除数不能为0!");  //弹出提示消息框
            f = m_fNumber1;   
//除数为0时直接将第一个操作数赋给结果,表示第二个操作数不算,直接继续下一步操作
        }
        else
        {
            f = m_fNumber1 / m_fNumber2;//除
        }
        break;
    case 6:
        f =pow(m_fNumber1, m_fNumber2); //指数
        break;
    default:
        break;
    }
//计算结果处理
    //如果浮点数其实是个整数
    if(f - int(f) <= 1e-5)
    {
        m_str.Format("%d",(int)f);
    }
    else
    {
        m_str.Format("%f",f);  //double型的数据转为Cstring型
    }
    UpdateData(FALSE);
}


Step 4:“关于软件”对应的About对话框的设计部分
运行程序时,单击“关于软件”按钮,会弹出一个说明对话框,本程序中使用的是创建MFC工程时默认生成的ABOUTBOX对话框,所以不用人工再在主程序头文件中添加相关信息或者在主程序中做相应的包含头文件操作,但是该默认对话框过于简洁,为了更加详细地说明此计算器的信息,需要在该对话框上添加一些自定义控件。
主要是添加了一些按钮(Button)和静态文本框(Static Text),添加后的效果如下所示(红色框中是原有的,位置略有调整,其他为人为设计),修改Caption即可显示文字,ID不改。

这里写图片描述


Step 5:运行结果展示部分
运行程序,出现下图左侧对话框,单击“关于软件”,弹出右侧对话框

这里写图片描述

输入一些数值进行运算以验证程序的正确性,下图为当除数为0时的情况:

这里写图片描述

写在最后:这是在之前做过的简单加法计算器和四则计算器的基础上完善,重新编写的一个更接近实际的计算器,在许多大神眼中可能是个小case,但是我在编写设计的过程中不断解决遇到的问题,也算小有成长,藉此总结,与大家分享,也算是自己学习过程的一个记录吧。
THE END

展开阅读全文

没有更多推荐了,返回首页