zoukankan      html  css  js  c++  java
  • MFC Calculator

    使用平台:VS2010

    语言:C++

    先预览下:

     

    1. 新建工程:

    选择MFC应用程序,输入工程名称,然后确定

    1. 点击下一步后出现如下对话框,选择基于对话框,点击完成

      

    1. MS自动帮我们创建了一个基础模板,并打开界面资源编辑窗口:

      使用工具箱向界面拖控件,添加一个BUTTON控件,修改其属性:

    出现属性对话框:修改其Caption及ID,其他的属性就不罗嗦了

    类似的将其他的控件拖放到合适位置,并调整好位置,设定相应的属性。

    1. 打开类视图,有三个类关于三个类的说明就不解释了

    我们双击BUTTON按钮就会自动帮我创建点击事件处理代码:看到在XXXDlg.cpp文件中添加了如下代码:void CtestDlg::OnBnClickedButton1()

    {

        // TODO: 在此添加控件通知处理程序代码

    }

     

    在其头文件中添加了该函数的声明:afx_msg void OnBnClickedButton1();

    在XXXDlg.cpp 文件中添加了代码:

    这个称为消息映射表:我们知道windows系统可以相应很多事件,但是只是相应特定的事件,如果什么事件都响应的话,会把windows累死。那么MFC提供了 消息映射的机制,每当事件发生时就在消息映射表中查询,看有没有定义这个事件,如果有的话,就进入消息处理程序,若没有就忽略这个事件。在MFC处理消息的函数是回调函数,我们看一下回调函数:【来自MSDN】

    callback

    The [callback] attribute declares a static callback function that exists on the client side of the distributed application. Callback functions provide a way for the server to execute code on the client.

    [callback [ , function-attr-list] ] type-specifier [ptr-declarator] function-name(

            [ [attribute-list] ] type-specifier [declarator]

            , ...);

    Parameters

    function-attr-list

    Specifies zero or more attributes that apply to the function. Valid function attributes are [local]; the pointer attribute [ref], [unique], or [ptr]; and the usage attributes [string], [ignore], and [context_handle]. Separate multiple attributes with commas.

    type-specifier

    Specifies a base_type, struct, union, enum type, or type identifier. An optional storage specification can precede type-specifier.

    ptr-declarator

    Specifies zero or more pointer declarators. A pointer declarator is the same as the pointer declarator used in C; it is constructed from the * designator, modifiers such as far, and the qualifier const.

    function-name

    Specifies the name of the remote procedure.

    attribute-list

    Specifies zero or more directional attributes, field attributes, usage attributes, and pointer attributes appropriate for the specified parameter type. Separate multiple attributes with commas.

    declarator

    Specifies a standard C declarator such as identifiers, pointer declarators, and array declarators. For more information, see Array and Sized-Pointer Attributes, arrays, and Arrays and Pointers. The parameter-name identifier is optional.

    Remarks

    The [callback] function is useful when the server must obtain information from the client. If server applications were supported on Windows 3.x, the server could make a call to a remote procedure on the Windows 3.x server to obtain the needed information. The callback function accomplishes the same purpose and lets the server query the client for information in the context of the original call.

    Callbacks are special cases of remote calls that execute as part of a single thread. A callback is issued in the context of a remote call. Any remote procedure defined as part of the same interface as the static callback function can call the callback function.

    Only the connection-oriented and local-protocol sequences support the callback attribute. If an RPC interface uses a connectionless (datagram) protocol sequence, calls to procedures with the callback attribute will fail.

    Handles cannot be used as parameters in callback functions. Because callbacks always execute in the context of a call, the binding handle used by the client to make the call to the server is also used as the binding handle from the server to the client.

    Callbacks can nest to any depth.

    Example

    [callback] HRESULT DisplayString([in, string] char * p1);

    对比LabView中的事件处理机制,由于LabVIEW不依赖于windows操作系统的事件处理机制(有利于程序的移植),那么LabVIEW使用的是轮询机制,一个事件结构只能响应一个事件,若要连续响应就要放在循环中。根据我的理解,这个事件结构相当于消息映射表和事件处理代码,而循环则相当于回调函数。关于事件就说到这里。

    手动添加的话  就分别在这三个位置添加相应的代码即可

    1. 关于属性:

    类向导中可以为各个控件添加各种事件处理代码,添加变量可以将控件值和类的属性值进行绑定,UpdateData(False/true)函数可以更新界面显示值和属性值,当然也可获得该控件的指针后进行修改。

    1. 表达式的计算:使用栈结构。

    附:

    代码:

    // Expression处理

    void CCalculatorDlg::OnBnClickedButton17()//0

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+'0';

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton18()//.

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+'.';

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton22()//Ans

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+L"Ans";

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton12()//1

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();//获取属性值

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+'1';

        UpdateData(false); //更新前面板

    }

     

     

    void CCalculatorDlg::OnBnClickedButton13()//2

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+'2';

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton14()//3

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+'3';

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton7()//4

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+'4';

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton8()//5

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+'5';

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton9()//6

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+'6';

        UpdateData(false);

    }

     

     

     

    void CCalculatorDlg::OnBnClickedButton2()//7

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+'7';

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton3()//8

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+'8';

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton4()//9

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

            if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

                m_cal.Empty();

            }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+'9';

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton5()//del

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

            m_cal.Delete(m_cal.GetLength()-1);

        m_result.SetWindowTextW(NULL);

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton6()//AC

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

       

        m_cal.Empty();

        m_result.SetWindowTextW(NULL);

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton19()//(

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+'(';

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton20()//)

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+')';

        UpdateData(false);

    }

     

     

     

     

    void CCalculatorDlg::OnBnClickedButton10()//×

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        if(m_cal.GetLength()){

            m_cal=m_cal+L'×';

        }

        else MessageBox(L"输入错误!");

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton11()// ÷

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        if(m_cal.GetLength()){

            m_cal=m_cal+L'÷';

        }

        else MessageBox(L"输入错误!");

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton15()// +

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

        if(m_cal.GetLength())

        if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

            m_cal.Empty();

        }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+'+';

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton16()//-

    {

        // TODO: 在此添加控件通知处理程序代码]

        UpdateData();

        if(m_cal.GetLength()){

            if(m_cal.GetAt(m_cal.GetLength()-1)==L'='){

                m_cal.Empty();

            }

        }

        m_result.SetWindowTextW(NULL);

        m_cal=m_cal+'-';

        UpdateData(false);

    }

     

     

    void CCalculatorDlg::OnBnClickedButton21()// =

    {

        // TODO: 在此添加控件通知处理程序代码

        UpdateData();

     

        m_cal=m_cal+'=';

        UpdateData(false);

     

    // 计算表达式的值

        CString str;

        str.Format(L"%lf",GetResult(m_cal,m_store));

    // 去掉尾部的零

        if(str.Find(L'.')>=0){

            while(str.GetAt(str.GetLength()-1)==L'0'){

                str.Delete(str.GetLength()-1);

                if(str.GetAt(str.GetLength()-1)==L'.'){

                    str.Delete(str.GetLength()-1);

                    break;

                }

            }

        }

    // 显示结果

        m_result.SetWindowTextW(str);

    // 结果

        m_store.Empty();

        m_result.GetWindowTextW(m_store);

     

    }

     

     

    ///在构造函数中添加定时器:SetTimer(0,1000,0);

    ///定义响应函数

    void CCalculatorDlg::OnTimer(UINT_PTR nIDEvent)

    {

        // TODO: 在此添加消息处理程序代码和/或调用默认值

        CTime t = CTime::GetCurrentTime();

        CString Str;

        if(m_DtoT){

            Str.Format(L"%d:%.2d:%.2d",t.GetHour(),t.GetMinute(),t.GetSecond());

        }

        else

        {

            wchar_t w=L'';

            switch(t.GetDayOfWeek())

            {

            case 2:

                w=L'一';

                break;

            case 3:

                w=L'二';

                break;

            case 4:

                w=L'三';

                break;

            case 5:

                w=L'四';

                break;

            case 6:

                w=L'五';

                break;

            case 7:

                w=L'六';

                break;

            case 1:

                w=L'日';

                break;

            default:

                break;

            }

            Str.Format(L"%d/%d/%d  星期%c",t.GetYear(),t.GetMonth(),t.GetDay(),w);

        }

        m_time_date.SetWindowTextW(Str);

        CDialogEx::OnTimer(nIDEvent);

     

     

    }

     

     

    void CCalculatorDlg::OnClose()

    {

        // TODO: 在此添加消息处理程序代码和/或调用默认值

        KillTimer(0);//销毁定时器

        CDialogEx::OnClose();

    }

     

     

    void CCalculatorDlg::OnBnClickedTime()

    {

        // TODO: 在此添加控件通知处理程序代码

        m_DtoT=~ m_DtoT;

    }

    表达式计算代码:

    #include<stack>

    using std::stack;

     

     

    //计算运算符的优先级

    int pp(wchar_t c)

    {

        int k=-2;

        switch(c){

        case '*':case '/':

            k=2;

            break;

        case '+':case '-':

            k=1;

            break;

        case '(':case ')':

            k=0;

            break;

        case '=':

            k=-1;

            break;

        }

        return k;

    }

     

     

    //将字符串转换成实数

    double shishu(CString *s,int *k)

    {

        double x,y=1.0;

        int flag=1;

        x=0.0;

        wchar_t c=s->GetAt(*k);

        while(c>='0'&&c<='9'||c=='.')

        {

            *k=*k+1;

            if(c>='0'&&c<='9')

                if(flag==0)

                {

                    y*=0.1;

                    x+=(y*(c-48));

                }

                else

                    x=10*x+(c-48);

            else flag=0;

            c=s->GetAt(*k);

        }

        return x;

     

    }

     

     

    double GetResult(CString str,CString str1=NULL){

        //格式化str

       

        int i=0;

        while(0!=str.Replace(L"Ans",str1));

        while(str.GetAt(i)==L'-'){

            if(i==0)

            {

                str.Insert(str.Find(L'-'),L'0');

            }

            else if(str.GetAt(i-1)==L'(')

                        str.Insert(i,L'0');

        }

     

        i=0;

        while(str.GetAt(i)!=L'='){

            switch(str.GetAt(i))

            {

            case L'÷':

                str.Delete(i);

                str.Insert(i,'/');

                break;

            case L'×':

                str.Delete(i);

                str.Insert(i,'*');

                break;

            case L' ':

                str.Delete(i);

                break;

            }

     

            i++;

        }

    //格式化结束

     

     

        stack<double>st_data;

        stack<wchar_t>st_op;

        st_op.push('=');

       

     

        int flag=1,k;

     

        k=0;

        double x,y;

        wchar_t c=str.GetAt(k);

     

        while(flag)

        {

            if(c>=L'0'&&c<=L'9'||c==L'.')

                st_data.push(shishu(&str,&k));

            else if(c==L'('||pp(c)>pp(st_op.top()))

            {

                st_op.push(c);

                k=k+1;

            }

            else if((c==L'=')&&(st_op.top()==L'='))

                flag=0;

            else if((c==L')')&&(st_op.top()==L'('))

            {

                st_op.pop();

                k++;

            }

            else if(pp(c)<=pp(st_op.top()))

            {

                y=st_data.top();

                st_data.pop();

                x=st_data.top();

                st_data.pop();

                c=st_op.top();

                st_op.pop();

                switch(c)

                {

                case L'+':

                    x=x+y;

                    break;

                case L'-':

                    x=x-y;

                    break;

                case L'*':

                    x=x*y;

                    break;

                case L'/':

                    x=x/y;

                    break;         

                }

                st_data.push(x);

            }

            c=str.GetAt(k);

        }

        return st_data.top();

    }

  • 相关阅读:
    启动redis时报错:FATAL CONFIG FILE ERROR :Bad directive or wrong number of arguments
    转载Redis的三个框架:Jedis,Redisson,Lettuce
    转载Dubbo详解(一):Dubbo介绍和SpringBoot整合Dubbo+ZooKeeper
    Redisson如何实现类似incr的自增操作
    转载解决 com.alibaba.fastjson.JSONException: autoType is not support.
    转载springboot+mybatis实现数据库的读写分离
    转载dubbo服务被重复调用三次的原因
    js中实现函数防抖跟函数节流
    网站项目后台的目录命名为admin后,网页莫名其妙的变样了
    createreactapp不支持less的解决方式
  • 原文地址:https://www.cnblogs.com/bacazy/p/3500126.html
Copyright © 2011-2022 走看看