//模拟Windows操作系统计算器基本计算功能的简单计算器软件。@版本1.0
//本软件基于C++下的easyx图形库的实现,为2018级计算机科学与技术专业学生《面向对象程序设计实训(课程设计)》项目
//***********************************************************************************************************
//作者:南昌师范学院数学与计算机科学系 彭正文 QQ:173780842
//***********************************************************************************************************
//此软件仅为学习C++面向对象知识及easyx图形库的爱好者参考使用
//@版权所有 1.0版本
//软件说明:软件中使用easyx绘制了按钮(按钮类对象)和编辑框(编辑框类对象),另外设计了算术表达式类,该软件只实现简单加减乘除功能
//同时存在不少bug
#include <graphics.h>
#include <math.h>
#include <conio.h>
//异常类
class Except//计算过程中可能产生的异常
{char*exc_info;//异常信息
public:
Except(char *str)
{
exc_info=new char[strlen(str)+1];
strcpy(exc_info,str);
}
Except(Except&e)
{
exc_info=new char[strlen(e.exc_info)+1];
strcpy(exc_info,e.exc_info);
}
char *GetInfo()
{
return exc_info;
}
~Except()
{
delete []exc_info;
}
};
//算式类
class Formula//算术表达式类
{bool used;
double num1,num2;//两个操作数,num1 op num2
char op; //操作符
double result; //运算结果
public:
Formula()//无参构造函数
{
num1=num2=0;used=false;
}
Formula(double n1,char oper,double n2)
{
num1=n1,num2=n2;
op=oper;
}
void SetNum1(double n) //设定第一操作数
{
num1=n;
}
void SetNum2(double n)//设定第二操作数
{
num2=n;
}
void SetOP(char op)//设定操作符
{
this->op=op;
used=false;//操作符未计算过
}
void SetUsed(bool b)
{
used=b;
}
double GetResult()//计算算式的结果
{
used=true;
switch(op)
{
case '+':
result=num1+num2;
break;
case '-':
result=num1-num2;
break;
case '*':
result=num1*num2;
break;
case '/':
if(num2==0)throw Except("错误:除数不能为0!");//除数为0时抛出异常
else
result=num1/num2;
break;
case '%':
if(num2==0)throw Except("错误:除数不能为0!");//除数为0时抛出异常
else
result=(long)num1%(long)num2;
break;
case '√':
if(num1<0)throw Except("错误:复数无法求平方根!");//除数为0时抛出异常
result=sqrt(num1);
break;
case '±':
num1=-num1;
result=-num1;
break;
}
return result;
}
bool OperUsed()
{
return used;
}
};
//简单普通窗口类
class CWnd
{protected :
int length,hight;
COLORREF bkcol;
IMAGE*img;
int posx,posy;
public:
CWnd()
{}
CWnd(int l,int h,COLORREF cbk=RGB(100,100,100)):length(l),hight(h),bkcol(cbk)
{
img=new IMAGE(length,hight);
}
void Draw(int l,int r)
{posx=l;posy=r;
IMAGE *iold=GetWorkingImage();
SetWorkingImage(img);
setfillcolor(bkcol);
fillrectangle(0,0,length,hight);
SetWorkingImage(iold);
putimage(posx, posy, img);
}
~CWnd()
{if(img)delete img;}
bool mouse_in(int x,int y)
{
if((x>posx&&x<posx+length)&&(y>posy&&y<posy+hight))return true;
else return false;
}
};
//按钮类
class CButton:public CWnd
{
char *str;
public :
CButton()
{str=0;}
void SetSize(int length,int hight)
{this->length=length;this->hight=hight;
img=new IMAGE(length,hight);
}
void SetPos(int x,int y)
{posx=x;posy=y;
}
CButton(int l,int h,COLORREF c):CWnd(l,h,c)
{str=new char[20];
strcpy(str,"按钮名称");
}
void SetWnd(IMAGE*image=NULL)
{if(image){delete image;this->img=image;}
else img=GetWorkingImage();
}
void SetBnText(char* str)
{
if(this->str)
delete[]this->str;
this->str=new char[strlen(str)+1];
strcpy(this->str,str);
}
void SetBkColor(COLORREF col)
{
bkcol=col;
}
void Draw(int l,int r)
{
posx=l;posy=r;
IMAGE *iold=GetWorkingImage();
SetWorkingImage(img);
setfillcolor(bkcol);
fillrectangle(0,0,length,hight);
fillrectangle(1,1,length-1,hight-1);
fillrectangle(2,2,length-2,hight-2);
RECT rect={length/6,hight/4,length,hight};
setbkmode(TRANSPARENT);
drawtext(str,&rect,DT_CENTER);
SetWorkingImage(iold);
putimage(posx, posy, img);
}
void Click_Down()
{
IMAGE *iold=GetWorkingImage();
SetWorkingImage(img);
setfillcolor(RGB(GetRValue(bkcol)+30,GetGValue(bkcol)+30,GetBValue(bkcol)+30));
fillrectangle(0,0,length,hight);
fillrectangle(1,1,length-1,hight-1);
fillrectangle(2,2,length-2,hight-2);
RECT rect={length/6,hight/4,length,hight};
setbkmode(TRANSPARENT);
drawtext(str,&rect,DT_CENTER);
SetWorkingImage(iold);
putimage(posx, posy, img);
}
void Click_Up()
{
IMAGE *iold=GetWorkingImage();
SetWorkingImage(img);
setfillcolor(bkcol);
fillrectangle(0,0,length,hight);
fillrectangle(1,1,length-1,hight-1);
fillrectangle(2,2,length-2,hight-2);
RECT rect={length/6,hight/4,length,hight};
setbkmode(TRANSPARENT);
drawtext(str,&rect,DT_CENTER);
SetWorkingImage(iold);
putimage(posx, posy, img);
}
char*GetText()
{return str;}
~CButton()
{
if(str)delete []str;
}
};
//编辑区类
class CEdit:public CWnd
{
char*str;
public:
CEdit(int l,int h,COLORREF bkcol=RGB(100,255,255)):CWnd(l,h,bkcol)
{str=0;}
void Draw(int l,int r)
{posx=l;posy=r;
IMAGE *iold=GetWorkingImage();
SetWorkingImage(img);
setfillcolor(bkcol);
settextcolor(RGB(255,0,255));
fillrectangle(0,0,length,hight);
RECT rect={length/6,hight/4,length,hight};
setbkmode(TRANSPARENT);
drawtext(str,&rect,DT_RIGHT);
SetWorkingImage(iold);
putimage(posx, posy, img);
}
void SetPos(int x,int y)
{posx=x;posy=y;
}
void SetEditText(char* str)
{
if(this->str)
delete[]this->str;
this->str=new char[strlen(str)+1];
strcpy(this->str,str);
}
~CEdit()
{if(str)delete [] str;}
};
char* strinfo[28]={"MC","MR","MS","M+","M-",
"←","CE","C","±","√","7","8","9","/","%",
"4","5","6","*","1/x","1","2","3","-","=","0",
".","+"};
//计算器类
class calculator
{char **btinfo;//按钮上信息
CButton*pbt;//按钮
CEdit*edit;//编辑区
char*str;//按钮按下字符串
double result;
int beginx;
int beginy;
int sizex,sizey;
Formula form;
bool first;//新的数字开始,初始为true
bool b;//按数字时是否要重新开始
public:
calculator(int bx,int by,int szx,int szy, char**str=strinfo)
{btinfo=str;pbt=new CButton[28];
beginx=bx;beginy=by,sizex=szx;sizey=szy;
edit=new CEdit(sizex*5,sizey);
edit->SetPos(beginx+20,beginy-50);
this->str=new char[4];
strcpy(this->str,"0");
first=true;
b=true;
}
void Draw(IMAGE*img=NULL)
{
for(int i=0;i<28;i++)
{
pbt[i].SetBnText(strinfo[i]);
pbt[i].SetSize(sizex,sizey);
if(i==24)pbt[i].SetSize(sizex,sizey*2);
if(i==25)pbt[i].SetSize(sizex*2,sizey);
pbt[i].SetBkColor(RGB(150,100,150));
if(i>=26)pbt[i].Draw(beginx+((i+1)%5)*sizex,beginy+i/5*sizey);
else pbt[i].Draw(beginx+(i%5)*sizex,beginy+i/5*sizey);
}
edit->SetEditText(str);
edit->Draw(beginx,beginy-50);
}
bool Find(char ch)//检查某个字符是否在str中
{int i=0;
while(str[i]!=ch&&str[i])i++;
if(i<strlen(str))return 1;
else return 0;
}
char* doubleToStr(double x)//双精度数转换为字符串
{char*str=new char[50];
memset(str,0,50);//清空字符串空间
gcvt(x,17,str);
return str;
}
void Process(char*ch)//处理按钮单击,分按钮处理
{try{int x=strlen(ch);
switch(strlen(ch))//单字符按钮处理
{
case 1:
if(ch[0]=='C')
{//按钮“C”清0处理
if(str)delete[]str;
str=new char[2];
strcpy(str,"0");form.SetNum1(0);
break;
};
if(ch[0]>='0'&&ch[0]<='9')// 数字按钮“0”——“9”的处理
{ if(!form.OperUsed()){
//delete[]str;
str=new char[strlen(ch)+1];
strcpy(str,ch);
form.SetUsed(true);}
else{
if(!atoi(str)&&!Find('.')){ str=new char[strlen(ch)+1];
strcpy(str,ch);
}
else