当前位置:C++技术网 > 资讯 > 四则运算器代码实现(仿Windows计算器)

四则运算器代码实现(仿Windows计算器)

更新时间:2015-06-26 19:49:22浏览次数:1+次

/* 
其实第一次听说要我发这个代码我是拒绝的,因为,你不能让我发,我就马上发表,
第一我要检查一下,因为我不愿意发表完了以后再加一些内容上去,程序“咣”一下,
很高效、很华丽,这样观众出来一定会骂我,根本没有这样的程序,
就证明那个代码不是我写的的。后来我也经过检查代码确实是完美的,
我检查了大概一天左右,感觉还不错,后来我在发表的时候也要求自己不要再修复bug,
因为我要让观众看到,我发表完之后是这个样子,你们看完之后也会是这个样子!
*/

 
//小数点未完成
debugprint.h//用于调试
//#pragma once
#include <stdio.h>
# include <windows.h>
#pragma once

static  void debugprint(TCHAR* string, ...)
{
    TCHAR buff[225];
    va_list va;
    va_start(va, string);
    vswprintf(buff, 225, string, va);
    va_end(va);
    OutputDebugString(buff);
}

//cz_4opera.h//包含处理表达式字符串的头文件
//long long cz4opera(TCHAR string [])将返回表达式的值

 //没写注释保护版权(其实是懒得写)

//cz_4opera.h

#pragma once
# include<windows.h>

void yxj(long long  buf[], char fuhao[], int shu)
{
    int i = 0;
    for(i = 0; i < shu; i++)
    {
        switch(fuhao[i])
        {
        //0-4*2/2+1
        //0-0-0-4+1
            case '*':
                buf[i + 1] = buf[i] * buf[i + 1];
                buf[i] = 0;
                if(fuhao[i - 1] == '-')
                    fuhao[i] = '-';
                else
                    fuhao[i] = '+';
                break;
            case '/':
                buf[i + 1] = buf[i] / buf[i + 1];
                buf[i] = 0;
                if(fuhao[i - 1] == '-')
                    fuhao[i] = '-';
                else
                    fuhao[i] = '+';
                break;
            default:
                break;
        }
    }
}

long long  jiema(long long buf[], char fuhao[], int shu)
{
    int i = 0;
    for(i = 0; i < shu; i++)
    {
        switch(fuhao[i])
        {//0-0-0-4+1
            case '+':
                buf[i + 1] = buf[i] + buf[i + 1];
                break;
            case '-':
                buf[i + 1] = buf[i] - buf[i + 1];
                break;
        }
    }
    return buf[i];
}

long long  f(long i, int n)
{
    for(int j = 0; j < n; j++)
    {
        i = i * 10;
    }
    return i;
}

long long fun(long long  a[], int size)
{
    int j = 0;
    for(int i = 0; i < size; i++)
    {
        a[i] = f(a[i], size - i - 1);
    }
    for(int i = size - 1; i >= 0; i--)
    {
        j = a[i] + j;
    }
    return j;
}

long long  cz4opera(TCHAR s[])
{
    int i = 0, k = 0;
    long long  buff1[10], buff2[10];
    char fuhao[10];
    int n = 0, m = 0;
    int shu = 0;
    while(s[i])
    {
        if(s[i] >= '0' && s[i] <= '9')
            buff1[k++] = s[i] - '0';
        else if(s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/' || s[i] == '.')
        {
            fuhao[shu] = s[i];
            buff2[shu] = fun(buff1, k);
            shu++;
            if(s[i + 1] == 0);
            else
                k = 0;
        }
        else
            return 0;
        i++;
    }
    buff2[shu] = fun(buff1, k);
    yxj(buff2, fuhao, shu);
    return jiema(buff2, fuhao, shu);
}

/*
char s[] = { "1+2" };
int i = 0,k=0;
int buff1[10], buff2[10];
while(s[i])
{
    if(s[i] >= 48 && s[i] <= 57)
        buff1[k++]=s[i]-48;
    if(s[i] == 42 || s[i] == 43 || s[i] == 45 || s[i] == 46 || s[i]==47)
    {
        cout << "error" << endl;
        return 0;
    }
}
*/ 

//主程序.cpp

/*代码较乱,慎入,小数点未处理,慎用*/

# include <debugprint.h> 
# include "cz_4opera.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR szCmdLine,int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("计算器");
    HWND       hwnd;
    MSG        msg;
    WNDCLASS   wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL,
        TEXT("C:\Windows\Installer\{052CFB79-9D62-42E3-8A15-DE66C2C97C3E}\\qq.ico"));
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(COLOR_BTNFACE + 1);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if(!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("计算器"),szAppName, MB_ICONERROR);
        return 0;
    }
    hwnd = CreateWindow(szAppName, TEXT("计算器"),WS_SYSMENU | WS_MINIMIZEBOX,
        760,276,226, 320, NULL, NULL, hInstance, NULL);
    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC             hdc;//设备句柄
    PAINTSTRUCT     ps;//未知
    static TCHAR    buf[100]=TEXT("\0");//要在文本框输出的字
    static TCHAR    lastbutton = 0;;//保存上一次的按钮标识
    static          RECT rect;//矩形
    static TCHAR    buttoncls[][3] = 
              {
                TEXT("1"), TEXT("2"), TEXT("3"),
                TEXT("4"), TEXT("5"), TEXT("6"),
                TEXT("7"), TEXT("8"), TEXT("9"),
                TEXT("0"), TEXT("+"), TEXT("-"),
                TEXT("*"), TEXT("/"), TEXT("="),
                TEXT("."), TEXT("⊙"), TEXT("←")
              };//保存按钮文本
   int              x = 5,i = 0,y = 100;//x控制按钮的横坐标,y控制按钮的纵坐标
   static int     k = 0;//赋予buf的焦点
   const int      n = 30;//按钮间隔
   static HWND    edit,//文本句柄
                  buttonhd[sizeof(buttoncls) / sizeof(buttoncls[0])];//按钮句柄组
   switch(message)
   {
       case  WM_CREATE://建立窗口的时候
               debugprint(TEXT("WM_CREATE\n"));
               edit = CreateWindow(TEXT("edit"), TEXT("0"), 
                  WS_CHILD | WS_VISIBLE | WS_BORDER | BS_TEXT, 1, 1, 200, 90,
                  hwnd, (HMENU)20,((LPCREATESTRUCT)lParam)->hInstance, NULL);
               for(i = 0; i <= (sizeof(buttoncls) / sizeof(buttoncls[0])); i++)
               {
                    buttonhd[i]=CreateWindow(TEXT("button"), buttoncls[i], 
                        WS_CHILD | WS_VISIBLE, 10 + x,  y, n+10, n, hwnd, (HMENU)i, 
                        ((LPCREATESTRUCT)lParam)->hInstance, NULL);
                    x += n+30;//每画一个按钮就把x往右移动n+30个坐标点
                    if(!((i + 1) % 3))//每画一行
                    {
                        y += n;//y往下移动
                        x = 5;//x恢复原位
                    }
                }
                return 0;
            case WM_SIZE://不不不窗口不可能改变大小以下代码用于调试
                /*
                // GetWindowRect(hwnd, &rect);
                // debugprint(TEXT("%d    "), rect.left);  
                   debugprint(TEXT("%d\n"), rect.top);
                //
                //
                // debugprint(TEXT("%d    "), rect.right); 
                debugprint(TEXT("%d\n\n"), rect.bottom);
                return 0;*/
            case WM_PAINT:
                hdc = BeginPaint(hwnd, &ps);
                EndPaint(hwnd, &ps);
                return 0;
                //窗口不会重绘
            case WM_DRAWITEM:
                debugprint(TEXT("WM_DRAWITEM\n"));
            case WM_COMMAND://当按下按钮以下是本程序最复杂最核心的代码
               debugprint(TEXT("WM_DRAWITEM\n"));
               debugprint(TEXT("%d\n"),k);
               for(i = 0; i <= (sizeof(buttoncls) / sizeof(buttoncls[0])); i++)
               {
                    if(LOWORD(wParam) == i)//LOWORD(wParam)可以获取按钮标识
                    {
                        if(i == 16) //清除
                        {
                            debugprint(TEXT("清除按钮\n"));
                            k = 0;//把焦点恢复到最开始处
                            buf[0] = '0';//保证文本框显示
                            buf[k+1] = '\0';//保证文本框不会输出多余的字符
                            lastbutton = TEXT('\0');//上一次什么也没按
                            SetWindowText(edit, buf);//输出文本
                            break;//结束循环,进入下一个消息循环
                        }
                        else if(i == 14)//=
                        {
                            debugprint(TEXT("=\n"));
                            long long n=cz4opera(buf);//将buf的数字进入cz四则运算符函数进行计算返回结果
                            wsprintf(buf, TEXT("%d"), n);//将数字转换为字符串
                            SetWindowText(edit, buf);//输出文本
                            k = wcslen(buf);//计算字符串的字符数用于移动焦点
                            lastbutton = TEXT('=');//记录按了=键
                            break;//退出循环进入下一次消息循环
                        }
                        else if(i==17)//←
                        {
                            debugprint(TEXT("←按钮\n"), 6);
                            if(buf[1] == TEXT('\0') )//如果只有一位数
                            {
                                k = 0;//确保k置零而已
                                buf[k] = TEXT('0');//确保在文本框显示的是
                            }
                            else
                                buf[--k] = TEXT('\0');//删除字符串末尾并且使焦点后移
                            SetWindowText(edit, buf);//输出删除后的文本
                            lastbutton = TEXT('\0');///只是为了区分上一次我有没有按下等号
                            break;
                        }
                        else//如果按下了数字键
                        {
                            debugprint(TEXT("按下数字键判断有没有按下等号\n"));
                            if(lastbutton == TEXT('='))//先看看上一次有没有按下等号如果有按下
                            {
                                debugprint(TEXT("按下数字键但上次没按下等号\n"), 8);
                                if(i >= 0 && i <= 9)//看看按下的是数字吗如果是
                                {
                                    debugprint(TEXT("%d\n"), 9);
                                    k = 0;//置零焦点
                                    buf[k++] = buttoncls[i][0];//将按下的数字放入焦点,并且移动焦点
                                    buf[k] = TEXT('\0');//
                                    lastbutton = TEXT('\0');
                                }
                                else if(i >= 10 && i <= 13)//如果不是数字而是+-*/符号
                                {
                                    debugprint(TEXT("按下符号键但上次没按下加减乘除键\n"), 10);
                                    buf[k++] = buttoncls[i][0];//不置零焦点而是在焦点加入符号
                                    buf[k] = TEXT('\0');//
                                    lastbutton = TEXT('\0');
                                }
                            }
                            else//如果没有按下等号就正常压入buf
                            {
                                debugprint(TEXT("没按下等号\n"), 11);
                                buf[k++] = buttoncls[i][0];//
                                buf[k] = TEXT('\0');//
                                lastbutton = TEXT('\0');
                            }
                            lastbutton = TEXT('\0');
                            SetWindowText(edit, buf);
                        }
                        break;
                    }
                }
                return 0;
            case WM_DESTROY:
                PostQuitMessage(0);
                return 0;
        }
    return DefWindowProc(hwnd, message, wParam, lParam);
}