效果如下:
代码如下:
#include <graphics.h>
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
PIMAGE img;
int dh = 50;
int dw = 100;
int sw = 400;
int sh = 500;
int raw = 6;
int column = 4;
int ih = sh-dh*raw;
char dis[][10]= {"%","sqrt","(",")",
"<<",">>","^","del",
"7","8","9","/",
"4","5","6","*",
"1","2","3","-",
".","0","=","+"
};
void PaintUI() { //初始化一张绘图画板
initgraph(sw,sh);
img = newimage();
getimage(img,"D:/bk.jpg",0,0);//读取图片
putimage(0,0,img);//从绘画板左上角0,0位置开始画图
setfillcolor(EGERGB(0xff,0xff,0xff));
setfont(32,0,"ЫЮЬх");
}
void PaintPane() {//画数字键盘的方框
int x = 0,y = sh-dh*6,i,j;
setcolor(EGERGB(0x00,0x00,0x00));
for(i=0; i<raw; i++) {
for(j=0; j<column; j++) {
rectangle(x,y,x+dw,y+dh);
x+=dw;
}
x=0;
y+=dh;
}
}
void PaintDigit() {//绘制数字和运算符
putimage(0,200,img);
int x = 0,y = sh-dh*6,i,j,k=0;
PaintPane();
setbkmode(TRANSPARENT);
setfont(32,0,"ЫЮЬх");
for(i=0; i<raw; i++) {
for(j=0; j<column; j++) {
if(i==0&&j==1) {
outtextxy(x+10,y+10,dis[k++]);
} else if(i==1&&j==3) {
outtextxy(x+20,y+10,dis[k++]);
} else
outtextxy(x+40,y+10,dis[k++]);
x+=dw;
}
x=0;
y+=dh;
}
}
void Destroy() {//程序结束时调用,释放资源
getch();
delimage(img);
closegraph();
return ;
}
void getxy(int &x,int &y,int &k) {//根据鼠标的坐标,计算点击的是哪一个数字或运算符
int z = (y-ih)/dh;
y = z*dh+ih;
x = (x/dw)*dw;
k = z*column+x/dw;
}
void shadowDisplay(int x,int y) {//鼠标移动时,方格样式变化
int i=0,k=0;
getxy(x,y,k);
bar(x,y,x+dw,y+dh);
outtextxy(x+40,y+10,dis[k]);
}
void shadowDisappear() {
PaintDigit();
}
int width = 0;
char str[100];//保存从键盘或者鼠标输入的字符
char s1[100];//保存后缀表达式
int cn = 0;
int priorityValue(char c) {//返回运算符的权重值
if(c=='$') {
return 5;
} else if(c=='*'||c=='/'||c=='%') {
return 4;
} else if(c=='+'||c=='-') {
return 3;
} else if(c=='<'||c=='>'||c=='^') {
return 2;
} else
return 1;
}
void m2h() {//中缀转后缀,用来计算多项式(有兴趣的可以上网搜索学习)
int i=0,j=0,k=0;
char s2[100];
while(str[k]!='\0') {
if(str[k]>='0'&&str[k]<='9'||str[k]=='.') {
s1[i++]=str[k];
if((str[k+1]<'0'||str[k+1]>'9')&&str[k+1]!='.'){
s1[i++]='#';
}
} else {
if(str[k]=='(') {
s2[j++]='(';
} else if(str[k]==')') {
while(s2[--j]!='(') {
s1[i++]=s2[j];
}
} else {
if(j==0||priorityValue(str[k])>priorityValue(s2[j-1])) {
s2[j++]=str[k];
} else if(priorityValue(str[k])<=priorityValue(s2[j-1])) {
s1[i++]=s2[--j];
s2[j++]=str[k];
}
}
}
k++;
}
while(j>0) {
s1[i++]=s2[--j];
}
s1[i]=0;
}
void printResult(double v) {//绘制计算结果
char ss1[100],ss2[100];
int i=0,j=0;
long vv = floor(v);
while(vv) {
ss1[i++]=vv%10+'0';
vv/=10;
}
while(i>0) {
ss2[j++]=ss1[--i];
}
v = v - floor(v);
if(v>0) {
ss2[j++]='.';
}
while(v>1e-10) {
v=v*10;
int t = (int)v;
ss2[j++]=t+'0';
v=v-t;
}
ss2[j]='\0';
i=0;
while(ss2[i]!=0) {
outtextxy(width,10,ss2[i++]);
width+=15;
}
}
double calc() {//计算后缀表达式,得到计算结果
m2h();
double a[100],c,d,f=0.1,v=0;
int i=0,j=0,flag = 0;
if(s1[i]=='#')
i++;
while(s1[i]!='\0') {
if(s1[i]=='.') {
flag=1;
} else if(s1[i]>='0'&&s1[i]<='9') {
if(flag) {
v+=f*(s1[i]-'0');
f*=0.1;
} else {
v*=10;
v+=(s1[i]-'0');
}
} else if(s1[i]=='#') {
flag=0;
f=0.1;
a[j++]=v;
v=0;
} else if(s1[i]=='$') {
a[j-1]=sqrt(a[j-1]);
} else {
d = a[--j];
c = a[--j];
switch(s1[i]) {
case '%':
a[j]=(long long)c%(long long)d;
break;
case '<':
a[j]=(int)c<<(int)d;
break;
case '>':
a[j]=(int)c>>(int)d;
break;
case '+':
a[j]=c+d;
break;
case '-':
a[j]=c-d;
break;
case '*':
a[j]=c*d;
break;
case '/':
a[j]=c/d;
break;
case '^':
a[j]=(int)c^(int)d;
break;
}
j++;
}
i++;
}
printf("%lf\n",a[0]);
printResult(a[0]);
}
void Delete() {//删除重复或者多输入的字符
putimage(0,0,img);
width=0;
for(int i=0; i<cn; i++) {
if(str[i]=='$'){
outtextxy(width,10,"sqrt");
width+=65;
}
else if(str[i]=='<'){
outtextxy(width,10,"<<");
width+=30;
}
else if(str[i]=='>'){
outtextxy(width,10,">>");
width+=30;
}
else{
outtextxy(width,10,str[i]);
width+=15;
}
}
}
void reciveChar(int k) {//接受鼠标传过来的字符,保存到str数字,并绘制
if(cn==0) {
width=0;
PaintUI();
PaintPane();
PaintDigit();
delay_fps(1000);
}
outtextxy(width,10,dis[k]);
if(k==1)
width+=65;
else if(k==4||k==5)
width+=30;
else
width+=15;
if(k==22) {
str[cn]='\0';
calc();
cn=0;
} else if(k==7) {
cn--;
Delete();
} else if(k==1) {
str[cn++]='$';
} else if(k==6) {
str[cn++]='^';
} else if(k==11) {
str[cn++]='/';
} else if(k==15) {
str[cn++]='*';
} else
str[cn++]=dis[k][0];
}
void ReciveChar(char c) {//接受键盘传过来的字符,保存到str数字,并绘制
if(cn==0) {
width=0;
PaintUI();
PaintPane();
PaintDigit();
delay_fps(1000);
}
setbkmode(TRANSPARENT);
setfont(32,0,"ЫЮЬх");
outtextxy(width,10,c);
width+=15;
if(c=='=') {
printf("====");
str[cn]=0;
calc();
}
str[cn++]=c;
}
void mouseListener() {//监听鼠标事件,得到输入的字符
mouse_msg msg = {0};
int x=0,y=0,x1=0,y1=0,k=0;
if(mousemsg()) {
msg = getmouse();
if(msg.is_left()) {
x1 = msg.x;
y1 = msg.y;
if(msg.is_down()) {
getxy(x1,y1,k);
reciveChar(k);
}
}
if(msg.is_move()) {
x1 = msg.x;
y1 = msg.y;
if(y1>=ih) {
getxy(x1,y1,k);
if(x1!=x||y1!=y) {
shadowDisappear();
x = x1;
y = y1;
shadowDisplay(x,y);
}
}
}
}
}
void mykeyListener() {//监听键盘事件,得到键盘输入的字符
if(kbhit()) {
char c = getch();
if(c>='0'&&c<='9'||c=='%'||c=='*'||c=='/'||c=='='||c=='-'||c=='+'||c=='('||c==')'||c=='^'||c=='<'||c=='>')
ReciveChar(c);
}
}
int main() {
PaintUI();
PaintPane();
PaintDigit();
delay_fps(1000);
while(true) {//死循环,不断监听鼠标和键盘事件
mykeyListener();
mouseListener();
}
Destroy();
return 0;
}