C語言經典案例:計算器

提示:此程序需要用Turbo C

#include "stdio.h"    /* 標準輸入輸出庫      */
#include "string.h"   /* 字符串操作函數庫    */
#include "math.h"     /* 數學函數庫          */
#include "stdlib.h"   /* 標準函數庫          */
#include "graphics.h" /* 圖形函數庫          */
#include "bios.h"     /* 基本輸入輸出系統函數庫*/
#include "dos.h"      /* dos函數庫           */

#define NUM0       0x5230    /* 小鍵盤區上數字鍵0  */
#define NUM1       0x4f31    /* 小鍵盤區上數字鍵1  */
#define NUM2       0x5032    /* 小鍵盤區上數字鍵2  */
#define NUM3       0x5133    /* 小鍵盤區上數字鍵3  */
#define NUM4       0x4b34    /* 小鍵盤區上數字鍵4  */
#define NUM5       0x4c35    /* 小鍵盤區上數字鍵5  */
#define NUM6       0x4d36    /* 小鍵盤區上數字鍵6  */
#define NUM7       0x4737    /* 小鍵盤區上數字鍵7  */
#define NUM8       0x4838    /* 小鍵盤區上數字鍵8  */
#define NUM9       0x4939    /* 小鍵盤區上數字鍵9  */
#define NUMPNT     0x532e    /* 小鍵盤區上 . 鍵    */
#define NUMADD     0x4e2b    /* 小鍵盤區上 + 鍵    */
#define NUMSUB     0x4a2d    /* 小鍵盤區上 - 鍵    */
#define NUMMUL     0x372a    /* 小鍵盤區上 * 鍵    */
#define NUMDIV     0x352f    /* 小鍵盤區上 / 鍵    */
#define NUMEQU     0x1c0d    /* 小鍵盤區上 = 鍵    */

#define KEY0       0xb30     /* 主鍵盤區上數字鍵0  */
#define KEY1       0x231     /* 主鍵盤區上數字鍵1  */
#define KEY2       0x332     /* 主鍵盤區上數字鍵2  */
#define KEY3       0x433     /* 主鍵盤區上數字鍵3  */
#define KEY4       0x534     /* 主鍵盤區上數字鍵4  */
#define KEY5       0x635     /* 主鍵盤區上數字鍵5  */
#define KEY6       0x736     /* 主鍵盤區上數字鍵6  */
#define KEY7       0x837     /* 主鍵盤區上數字鍵7  */
#define KEY8       0x938     /* 主鍵盤區上數字鍵8  */
#define KEY9       0xa39     /* 主鍵盤區上數字鍵9  */
#define KEYPNT     0x342e    /* 主鍵盤區上 . 鍵    */
#define KEYSUB     0xc2d     /* 主鍵盤區上 - 鍵    */
#define KEYMUL     0x92a     /* 主鍵盤區上 * 鍵    */
#define KEYEQU     0xd3d     /* 主鍵盤區上 = 鍵    */

#define SQR        0x340     /* @ 鍵,求平方根 */
#define KEYR       0x1372    /* r 鍵,取倒數 */
#define PERCENT    0x625     /* % 鍵,求百分數 */
#define DEL        0x5300    /* DEL 鍵  */
#define ESC        0x11b     /* ESC 鍵  */
#define BACKSPACE  0xe08     /* 退格 鍵  */
#define F9         0x4300    /* F9 鍵,正負數變換  */
#define CTRL_L     0x260c    /* Ctrl 鍵+L鍵,清除記憶器中的數值 */
#define CTRL_R     0x1312    /* Ctrl 鍵+R鍵,讀取記憶器中的數值 */
#define CTRL_M     0x320d    /* Ctrl 鍵+M鍵,將當前數值寫入記憶器中*/
#define CTRL_P     0x1910    /* Ctrl 鍵+P鍵,將當前數值和記憶器中保存的數值相加*/
#define ALT_X      0x2d00    /* Alt 鍵+X鍵  */

#define TRUE  1     /* 爲十進制1表示爲真 true  */
#define FALSE 0     /* 爲十進制0表示爲假 false */

/*計算器界面結構體*/
struct Block
    {    int  left,top,width,height;        /* 左上座標,寬,高          */
         char caption[50];                  /* 標題                    */
         int  fontcolor,fontsize,status;    /* 字體顏色,字體大小,狀態  */
    };

void Form(struct Block form);      /* 構造和顯示主窗口*/
void TextBox(struct Block txtbox); /* 構造和顯示文本輸入框*/
void Label(struct Block label);    /* 構造和顯示標籤,若記憶功能開啓,標籤標記爲:M*/

void CommandButton(struct Block cmdbutton); /*顯示cmdbutton[i]命令按鈕*/
void CommandButton_KeyboardDown(int i); /*定義按下編號爲i的鍵所進行的操作,如按鈕的狀態的改變*/
void CommandButton_KeyboardUp(int i);   /*定義鬆開編號爲i的按鍵所進行的操作,如按鈕的狀態*/


void InitApp(); /*初始化程序*/
void Showme();  /*顯示計算器界面*/
void Load();    /*初始化默認值*/

void CommandButton_Click(int key);  /*按鍵盤時所做的操作*/
void DoubleRun(); /*四則運算:加減乘除*/
void SingleRun(int operatoror); /*單運算*/
void Resetbuf(); /*重置緩衝區*/
void StoreSet(int key); /*定義記憶存儲操作*/
void Unload(); /*退出系統時的一些恢復操作*/


struct Block frmmain,txtscreen,lblstore,cmdbutton[28]; /*定義主窗口,文本輸入框,記憶標籤,28[0-27]個按鈕*/
int clickflag;  /*clickflag:按鍵標誌,*/
int top,pointflag,digitkeyhit; /*top:保存緩衝區中的當前位數,pointflag:小數點標記,digitkeyhit:數字鍵按鍵標記*/
int operatoror,runflag,ctnflag; /*operatoror:操作符,runflag:運算標記,ctnflag:運算符標記*/
int errorflag; /*錯誤標記*/
double num1,num2,store; /*num1:操作數1,num2:操作數2,store:記憶變量*/
char strbuf[33];  /*字符緩衝區,用於保存一個操作數*/


void main()
    {

         int key;  /*保存此計算器上定義的按鍵編號*/
         InitApp();/*初始化程序,進入圖形模式*/
         Showme(); /*顯示計算器窗口*/
         Load();   /*初始化默認值*/
         while(1)
             {
                    if(bioskey(1)==0) continue; /*直到有鍵按下時,才返回非0值,否則返回0值*/
                    key=bioskey(0); /*返回上條語句的按鍵值*/
                    switch(key)    /*捕獲相應的鍵盤按鍵並匹配到計算器按鍵上*/
                        {    case NUM0:case KEY0:          key=10;break;
                             case NUM1:case KEY1:          key=1;break;
                             case NUM2:case KEY2:          key=2;break;
                             case NUM3:case KEY3:          key=3;break;
                             case NUM4:case KEY4:          key=4;break;
                             case NUM5:case KEY5:          key=5;break;
                             case NUM6:case KEY6:          key=6;break;
                             case NUM7:case KEY7:          key=7;break;
                             case NUM8:case KEY8:          key=8;break;
                             case NUM9:case KEY9:          key=9;break;
                             case F9:                      key=11;break;
                             case NUMPNT:case KEYPNT:      key=12;break;
                             case NUMADD:                  key=13;break;
                             case NUMSUB:case KEYSUB:      key=14;break;
                             case NUMMUL:case KEYMUL:      key=15;break;
                             case NUMDIV:                  key=16;break;
                             case SQR:                     key=17;break;
                             case PERCENT:                 key=18;break;
                             case KEYR:                    key=19;break;
                             case NUMEQU:case KEYEQU:      key=20;break;
                             case CTRL_L:                  key=21;break;
                             case CTRL_R:                  key=22;break;
                             case CTRL_M:                  key=23;break;
                             case CTRL_P:                  key=24;break;
                             case BACKSPACE:               key=25;break;
                             case DEL:                     key=26;break;
                             case ESC:                     key=27;break;
                             case ALT_X:                   key=0; break;
                             default:                      key=-1;break;
                     }
             if(key<0) continue; /*若對應的按鍵返回負數,則返回到while(1)處執行*/
             CommandButton_KeyboardDown(key);/*爲了在計算器上顯示按鍵效果,在此函數中改變一些按鈕的狀態值*/
             CommandButton_Click(key); /*根據key的值,進行相關操作*/
             delay(300000);    /*爲了突出按鍵效果,此處延時300000毫秒*/
             CommandButton_KeyboardUp(key); /*在處理完此按鍵後,要恢復按鈕的狀態值*/
        }
    }

void InitApp()   /*初始化程序*/
    {
         int driver=DETECT,mode; /* 顯示設備驅動爲自動檢測顯示器模式 */
         initgraph(&driver,&mode,"");   /* 初始化圖形顯示系統  */
         if(driver!=VGA&&driver!=EGA)  /* 如果不能初始化  */
             {  printf("\n\nERROR!Can't initialize the graphics system!"); /* 顯示錯誤信息"不能初始化圖形系統"  */
                    closegraph();   /* 關閉圖形接口*/
                    exit(0);       /* 直接退出系統 */
             }
         setbkcolor(9);     /* 設置背景顏色爲青色  */


         /*主窗口的屬性設置*/
         frmmain.left=200; frmmain.top=100; frmmain.width=230;  frmmain.height=235; frmmain.fontcolor=BLACK; frmmain.fontsize=1;   strcpy(frmmain.caption,"   << Calculator >>");frmmain.status=1;
         /*文本框的屬性設置*/
         txtscreen.left=10;txtscreen.top=25;txtscreen.width=210;txtscreen.height=30;txtscreen.fontcolor=BLACK;txtscreen.fontsize=1;strcpy(txtscreen.caption,"0.");           txtscreen.status=1;
         /*標籤的屬性設置*/
         lblstore.left=190; lblstore.top=62; lblstore.width=30;  lblstore.height=25; lblstore.fontcolor=YELLOW; lblstore.fontsize=1;strcpy(lblstore.caption,"");              lblstore.status=1;
         /*命令按鈕的屬性設置*/
         cmdbutton[1].left=50-35;cmdbutton[1].top=165;cmdbutton[1].width=30;cmdbutton[1].height=25;cmdbutton[1].fontcolor=BLUE;cmdbutton[1].fontsize=1;strcpy(cmdbutton[1].caption,"1");cmdbutton[1].status=1;
         cmdbutton[2].left=85-35;cmdbutton[2].top=165;cmdbutton[2].width=30;cmdbutton[2].height=25;cmdbutton[2].fontcolor=BLUE;cmdbutton[2].fontsize=1;strcpy(cmdbutton[2].caption,"2");cmdbutton[2].status=1;
         cmdbutton[3].left=120-35;cmdbutton[3].top=165;cmdbutton[3].width=30;cmdbutton[3].height=25;cmdbutton[3].fontcolor=BLUE;cmdbutton[3].fontsize=1;strcpy(cmdbutton[3].caption,"3");cmdbutton[3].status=1;
         cmdbutton[4].left=50-35;cmdbutton[4].top=130;cmdbutton[4].width=30;cmdbutton[4].height=25;cmdbutton[4].fontcolor=BLUE;cmdbutton[4].fontsize=1;strcpy(cmdbutton[4].caption,"4");cmdbutton[4].status=1;
         cmdbutton[5].left=85-35;cmdbutton[5].top=130;cmdbutton[5].width=30;cmdbutton[5].height=25;cmdbutton[5].fontcolor=BLUE;cmdbutton[5].fontsize=1;strcpy(cmdbutton[5].caption,"5");cmdbutton[5].status=1;
         cmdbutton[6].left=120-35;cmdbutton[6].top=130;cmdbutton[6].width=30;cmdbutton[6].height=25;cmdbutton[6].fontcolor=BLUE;cmdbutton[6].fontsize=1;strcpy(cmdbutton[6].caption,"6");cmdbutton[6].status=1;
         cmdbutton[7].left=50-35;cmdbutton[7].top=95;cmdbutton[7].width=30;cmdbutton[7].height=25;cmdbutton[7].fontcolor=BLUE;cmdbutton[7].fontsize=1;strcpy(cmdbutton[7].caption,"7");cmdbutton[7].status=1;
         cmdbutton[8].left=85-35;cmdbutton[8].top=95;cmdbutton[8].width=30;cmdbutton[8].height=25;cmdbutton[8].fontcolor=BLUE;cmdbutton[8].fontsize=1;strcpy(cmdbutton[8].caption,"8");cmdbutton[8].status=1;
         cmdbutton[9].left=120-35;cmdbutton[9].top=95;cmdbutton[9].width=30;cmdbutton[9].height=25;cmdbutton[9].fontcolor=BLUE;cmdbutton[9].fontsize=1;strcpy(cmdbutton[9].caption,"9");cmdbutton[9].status=1;
         cmdbutton[10].left=50-35;cmdbutton[10].top=200;cmdbutton[10].width=30;cmdbutton[10].height=25;cmdbutton[10].fontcolor=BLUE;cmdbutton[10].fontsize=1;strcpy(cmdbutton[10].caption,"0");cmdbutton[10].status=1;
         cmdbutton[11].left=85-35;cmdbutton[11].top=200;cmdbutton[11].width=30;cmdbutton[11].height=25;cmdbutton[11].fontcolor=BLUE;cmdbutton[11].fontsize=1;strcpy(cmdbutton[11].caption,"+/-");cmdbutton[11].status=1;
         cmdbutton[12].left=120-35;cmdbutton[12].top=200;cmdbutton[12].width=30;cmdbutton[12].height=25;cmdbutton[12].fontcolor=BLUE;cmdbutton[12].fontsize=1;strcpy(cmdbutton[12].caption,".");cmdbutton[12].status=1;
         cmdbutton[13].left=155-35;cmdbutton[13].top=95;cmdbutton[13].width=30;cmdbutton[13].height=25;cmdbutton[13].fontcolor=RED;cmdbutton[13].fontsize=1;strcpy(cmdbutton[13].caption,"+");cmdbutton[13].status=1;
         cmdbutton[14].left=155-35;cmdbutton[14].top=130;cmdbutton[14].width=30;cmdbutton[14].height=25;cmdbutton[14].fontcolor=RED;cmdbutton[14].fontsize=1;strcpy(cmdbutton[14].caption,"-");cmdbutton[14].status=1;
         cmdbutton[15].left=155-35;cmdbutton[15].top=165;cmdbutton[15].width=30;cmdbutton[15].height=25;cmdbutton[15].fontcolor=RED;cmdbutton[15].fontsize=1;strcpy(cmdbutton[15].caption,"*");cmdbutton[15].status=1;
         cmdbutton[16].left=155-35;cmdbutton[16].top=200;cmdbutton[16].width=30;cmdbutton[16].height=25;cmdbutton[16].fontcolor=RED;cmdbutton[16].fontsize=1;strcpy(cmdbutton[16].caption,"/");cmdbutton[16].status=1;
         cmdbutton[17].left=190-35;cmdbutton[17].top=95;cmdbutton[17].width=30;cmdbutton[17].height=25;cmdbutton[17].fontcolor=BLUE;cmdbutton[17].fontsize=1;strcpy(cmdbutton[17].caption,"sqr");cmdbutton[17].status=1;
         cmdbutton[18].left=190-35;cmdbutton[18].top=130;cmdbutton[18].width=30;cmdbutton[18].height=25;cmdbutton[18].fontcolor=BLUE;cmdbutton[18].fontsize=1;strcpy(cmdbutton[18].caption,"%");cmdbutton[18].status=1;
         cmdbutton[19].left=190-35;cmdbutton[19].top=165;cmdbutton[19].width=30;cmdbutton[19].height=25;cmdbutton[19].fontcolor=BLUE;cmdbutton[19].fontsize=1;strcpy(cmdbutton[19].caption,"1/x");cmdbutton[19].status=1;
         cmdbutton[20].left=190-35;cmdbutton[20].top=200;cmdbutton[20].width=30;cmdbutton[20].height=25;cmdbutton[20].fontcolor=RED;cmdbutton[20].fontsize=1;strcpy(cmdbutton[20].caption,"=");cmdbutton[20].status=1;
         cmdbutton[21].left=190;cmdbutton[21].top=95;cmdbutton[21].width=30;cmdbutton[21].height=25;cmdbutton[21].fontcolor=RED;cmdbutton[21].fontsize=1;strcpy(cmdbutton[21].caption,"MC");cmdbutton[21].status=1;
         cmdbutton[22].left=190;cmdbutton[22].top=130;cmdbutton[22].width=30;cmdbutton[22].height=25;cmdbutton[22].fontcolor=RED;cmdbutton[22].fontsize=1;strcpy(cmdbutton[22].caption,"MR");cmdbutton[22].status=1;
         cmdbutton[23].left=190;cmdbutton[23].top=165;cmdbutton[23].width=30;cmdbutton[23].height=25;cmdbutton[23].fontcolor=RED;cmdbutton[23].fontsize=1;strcpy(cmdbutton[23].caption,"MS");cmdbutton[23].status=1;
         cmdbutton[24].left=190;cmdbutton[24].top=200;cmdbutton[24].width=30;cmdbutton[24].height=25;cmdbutton[24].fontcolor=RED;cmdbutton[24].fontsize=1;strcpy(cmdbutton[24].caption,"M+");cmdbutton[24].status=1;
         cmdbutton[25].left=50-35;cmdbutton[25].top=60;cmdbutton[25].width=53;cmdbutton[25].height=25;cmdbutton[25].fontcolor=RED;cmdbutton[25].fontsize=1;strcpy(cmdbutton[25].caption,"<-");cmdbutton[25].status=1;
         cmdbutton[26].left=108-35;cmdbutton[26].top=60;cmdbutton[26].width=53;cmdbutton[26].height=25;cmdbutton[26].fontcolor=RED;cmdbutton[26].fontsize=1;strcpy(cmdbutton[26].caption,"Del");cmdbutton[26].status=1;
         cmdbutton[27].left=166-35;cmdbutton[27].top=60;cmdbutton[27].width=53;cmdbutton[27].height=25;cmdbutton[27].fontcolor=RED;cmdbutton[27].fontsize=1;strcpy(cmdbutton[27].caption,"Esc");cmdbutton[27].status=1;
         /* 設置計算器界面 */
    }

void Showme()   /*顯示計算器界面*/
    {    int i;
         Form(frmmain); /*顯示主窗口,frmmain爲主窗口的結構變量名*/
         TextBox(txtscreen); /*顯示文本框*/
         Label(lblstore); /*顯示記憶器的狀態標籤*/
         for(i=1;i<28;i++) /*顯示27個按鈕在計算器主窗口中*/
             CommandButton(cmdbutton[i]);
    }

void Load() /*初始化默認值*/
    {    num1=num2=0;
         Resetbuf();
         ctnflag=FALSE;
         operatoror=0;
         runflag=FALSE;
         errorflag=FALSE;
         store=0;
         clickflag=FALSE;

         strcpy(txtscreen.caption,"0.");
         TextBox(txtscreen);/*文本框中初始顯示爲0.的字符*/

         strcpy(lblstore.caption,"");
         Label(lblstore);
    }

void Unload() /*退出系統*/
    {
         cleardevice(); /*清除圖形屏幕*/
         closegraph();  /*關閉圖形系統*/
         exit(0);
    }

void Resetbuf()
    {    strbuf[0]=' ';
         strbuf[1]=0;
         top=1;
         digitkeyhit=FALSE;
         pointflag=FALSE;
    }


void Form(struct Block form)   /* 構造和顯示主窗口*/
    {    int x1=form.left; /*窗口左上角的橫座標值*/
         int y1=form.top;  /*窗口左上角的縱座標值*/
         int x2=form.width+x1-1;/*窗口右下角的橫座標值*/
         int y2=form.height+y1-1; /*窗口右下角的縱座標值*/

         setfillstyle(SOLID_FILL,LIGHTGRAY); /*設置填充模式和顏色  */
                bar(x1+1,y1+1,x2-1,y2-1);    /*畫一個淡灰色的填充窗口,作爲主窗口,但此函數不畫出邊框*/
         setcolor(WHITE);                    /*設置當前畫線顏色*/
                line(x1,y1,x2,y1);
                line(x1,y1,x1,y2);    /*用白線畫邊框左邊和上邊的線,美化主窗口*/
         setcolor(DARKGRAY);          /*設置填充模式和顏色  */
                line(x2,y1,x2,y2);
                line(x1,y2,x2,y2);    /*用深灰色畫邊框右邊和下邊的線,美化主窗口*/
         setfillstyle(SOLID_FILL,RED);
                bar(x1+2,y1+2,x2-2,y1+15);    /*設置標題欄顏色爲紅色*/
         settextjustify(LEFT_TEXT,CENTER_TEXT); /*設置文本的對齊方式爲左中對齊*/
         settextstyle(DEFAULT_FONT,0,form.fontsize); /*設置文本顯示字體爲默認字體,大小爲主窗體字體大小*/
         setcolor(form.fontcolor);
                outtextxy(x1+3,y1+10,form.caption);  /*用主窗體的顏色顯示標題在標題欄*/

         if(form.status&1)     /*判斷窗口是否可用,未使用ALT+X鍵,右上角的X按鈕*/
             {      cmdbutton[0].left=form.width-15;
                    cmdbutton[0].top=3;
                    cmdbutton[0].width=12;
                    cmdbutton[0].height=12;
                    cmdbutton[0].status=1;
                    cmdbutton[0].caption[0]=0;
                    CommandButton(cmdbutton[0]);
                    x1=cmdbutton[0].left+form.left;
                    y1=cmdbutton[0].top+form.top;
                    x2=cmdbutton[0].width+x1-1;
                    y2=cmdbutton[0].height+y1-1;
                    setfillstyle(SOLID_FILL,LIGHTGRAY);
                         bar(x1+1,y1+1,x2-1,y2-1);
                    setcolor(DARKGRAY);
                         line(x1+2,y1+2,x2-2,y2-2);
                         line(x2-2,y1+2,x1+2,y2-2);
             }

    }

void TextBox(struct Block txtbox)     /* 設置和顯示輸入框*/
    {    /*(x1,y1),(x2,y2)爲主窗口中的相對座標*/
         int x1=txtbox.left+frmmain.left;
         int y1=txtbox.top+frmmain.top;
         int x2=txtbox.width+x1-1;
         int y2=txtbox.height+y1-1;

         setfillstyle(SOLID_FILL,WHITE);
                bar(x1+1,y1+1,x2-1,y2-1);
         /*因bar()不畫出邊框,所以接下來畫這個方本框的邊框線*/
         setcolor(LIGHTGRAY);
                rectangle(x1+1,y1+1,x2-1,y2-1);
         setcolor(DARKGRAY);
                line(x1,y1,x2,y1);
                line(x1,y1,x1,y2);
                setcolor(WHITE);
                line(x2,y1,x2,y2);
                line(x1,y2,x2,y2);
         settextjustify(RIGHT_TEXT,CENTER_TEXT); /*爲圖形函數設置文本的對齊方式,第一參數爲水平對齊方式,第二參數爲垂直對齊方式*/
         settextstyle(DEFAULT_FONT,0,txtbox.fontsize); /*爲圖形輸出設置當前的文本屬性:字體,方向,大小*/
         setcolor(txtbox.fontcolor); /*設置方本框的字體顏色*/
         outtextxy(x2-10,(y1+y2)/2,txtbox.caption);  /*在指定位置顯示txtbox.caption的字符串值*/

    }

void Label(struct Block label) /*設置和顯示計算器記憶功能的使用狀態,默認爲空*/
    {    int x1=label.left+frmmain.left;
         int y1=label.top+frmmain.top;
         int x2=label.width+x1-1;
         int y2=label.height+y1-1;

         setfillstyle(SOLID_FILL,LIGHTGRAY);
                bar(x1+1,y1+1,x2-1,y2-1);
         setcolor(DARKGRAY);
                line(x1,y1,x2,y1);
                line(x1,y1,x1,y2);
         setcolor(WHITE);
                line(x2,y1,x2,y2);
                line(x1,y2,x2,y2);
         settextjustify(CENTER_TEXT,CENTER_TEXT);
         settextstyle(DEFAULT_FONT,0,label.fontsize);
         setcolor(label.fontcolor);
                outtextxy((x1+x2)/2,(y1+y2)/2,label.caption);

    }

void CommandButton(struct Block cmdbutton)  /*設置和顯示單個按鈕*/
    {     /*(x1,y1),(x2,y2)爲主窗口中的相對座標*/
         int x1=cmdbutton.left+frmmain.left;
         int y1=cmdbutton.top+frmmain.top;
         int x2=cmdbutton.width+x1-1;
         int y2=cmdbutton.height+y1-1;
         int c1,c2;
         /*按鈕的初始狀態爲1,若有鍵按下後,其狀態變爲0,處理完按鍵操作後,又恢復爲狀態1*/
         if(cmdbutton.status) /*根據按鈕的當前狀態值來,分別用不同的顏色邊框來重繪此按鈕*/
             {      c1=WHITE;  /*白色*/
                    c2=DARKGRAY; /*深灰色*/
             }
         else /*若剛有鍵按下*/
             {      c1=DARKGRAY;
                    c2=WHITE;
             }

         setcolor(c1);
                line(x1,y1,x2,y1);
                line(x1,y1,x1,y2);
         setcolor(c2);
                line(x2,y1,x2,y2);
                line(x1,y2,x2,y2);
         settextjustify(CENTER_TEXT,CENTER_TEXT);
         settextstyle(DEFAULT_FONT,0,cmdbutton.fontsize);
         outtextxy((x1+x2)/2,(y1+y2)/2,cmdbutton.caption);

    }

void CommandButton_KeyboardDown(int i) /*按下某鍵時所做的操作*/
    {    clickflag=TRUE;      /*鍵盤點擊標誌*/
         cmdbutton[i].status=0;
         CommandButton(cmdbutton[i]); /*用與初始時不同的邊框顏色色,重繪此命令按鈕*/
    }



void CommandButton_KeyboardUp(int key) /*當按鍵處理完後,恢復按鈕狀態,重繪此命令按鈕*/
    {  clickflag=FALSE;
         cmdbutton[key].status=1;
         CommandButton(cmdbutton[key]);
    }



void CommandButton_Click(int key)      /*處理相應按鍵操作*/
    {
        if(errorflag==TRUE)  return;
         switch(key)
             {  case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:   /*1-9*/
                        if(top<15) /*單個操作數小於15位*/
                            {    strbuf[top++]='0'+key; /*'0'+key表示是字符1,若沒有'0'+則存儲的是Ascll碼爲key爲字符*/
                                 strbuf[top]=0; /*存儲的是ASCLL碼爲0的表示的字符Ctrl+@*/
                                 digitkeyhit=TRUE; /*表示已有數字鍵按下*/
                                 strcpy(txtscreen.caption,strbuf); /*在文本框中顯示當前的*/
                            }
                        runflag=FALSE; /*運算標記爲假*/
                        if(ctnflag==FALSE) operatoror=0;
                        break;
                    case 10:     /* 0輸入*/
                        if(top<15&&top!=1)
                            {    strbuf[top++]='0';
                                 strbuf[top]=0;
                                 strcpy(txtscreen.caption,strbuf);
                            }
                        digitkeyhit=TRUE;
                        runflag=FALSE;
                        if(ctnflag==FALSE) operatoror=0;
                        break;
                    case 11:    /*正負互換*/
                        if(digitkeyhit==TRUE)
                            {    strbuf[0]=strbuf[0]==' '?'-':' ';
                                 strcpy(txtscreen.caption,strbuf);
                            }
                        else if(runflag==TRUE) /*表示沒有新的輸入,就是在之前的計算結果上正負轉換*/
                            {    num1=-num2;
                                 sprintf(txtscreen.caption,"%G",num1);
                            }
                        else   /*原數的正負互換*/
                            {    num1=-num1;
                                 sprintf(txtscreen.caption,"%G",num1);
                            }
                        runflag=FALSE;
                        if(ctnflag==FALSE) operatoror=0;
                        break;
                    case 12:   /*輸入一個小數點*/
                        if(top==1) /*表示還沒有輸入數,保持0.狀態*/
                            {  strbuf[top++]='0';
                                 strbuf[top++]='.';
                                 strbuf[top]=0;
                                 strcpy(txtscreen.caption,strbuf);
                                 digitkeyhit=TRUE;
                                 runflag=FALSE;
                                 pointflag=TRUE;
                                 if(ctnflag==FALSE) operatoror=0;
                            }
                        else if(top<15&&pointflag==FALSE)
                            {  strbuf[top++]='.';
                                 strbuf[top]=0;
                                 strcpy(txtscreen.caption,strbuf);
                                 digitkeyhit=TRUE;
                                 runflag=FALSE;
                                 pointflag=TRUE;
                                 if(ctnflag==FALSE) operatoror=0;
                            }
                        break;
                    case 13:case 14:case 15:case 16:   /* 四則運算加減乘除運算符 */
                        if(digitkeyhit) /*若此運算符之前已經輸入了一個數*/
                            num1=atof(strbuf);
                        if(ctnflag) /*之前的輸入中,已有運算符的輸入*/
                            if(digitkeyhit==TRUE) /*如1+2+的情況*/
                                 DoubleRun(); /*先計算出1+2*/
                            else
                                 ;
                        else /*之前的輸入中,沒有運算符的輸入,如:1+的情況*/
                            if(operatoror==0)
                                 num2=num1;
                            else
                                 ;
                        Resetbuf();
                        operatoror=key;
                        ctnflag=TRUE;
                        runflag=TRUE;
                        break;
                    case 17:case 18:case 19:   /*單運算 開方,百分比,倒數*/
                        if(digitkeyhit)
                            num1=atof(strbuf); /*num1保存當前操作數*/

                        SingleRun(key);
                        Resetbuf();
                        ctnflag=FALSE;
                        operatoror=0;
                        runflag=FALSE;
                        break;
                    case 20:    /*獲取運算結果及等於操作*/
                        if(digitkeyhit) num1=atof(strbuf);
                        if(operatoror)
                            DoubleRun(); /*第一個操作數,保存在num2中*/
                        else
                            num2=num1;
                        Resetbuf();
                        ctnflag=FALSE;
                        runflag=TRUE;
                        break;
                    case 21:case 22:case 23:case 24: /*值的保存的一些操作*/
                        if(digitkeyhit) num1=atof(strbuf);
                        StoreSet(key);
                        Resetbuf();
                        break;
                    case 25:    /*刪除數字的整數部分的最後一位數(BackSpace鍵)*/
                        if(top>1)
                            if(strbuf[--top]=='.')
                                {  if(strbuf[1]=='0'&&strbuf[2]=='.')
                                         strbuf[--top]=0;
                                     else
                                         strbuf[top]=0;
                                     pointflag=FALSE;
                                }
                            else
                                strbuf[top]=0;
                        operatoror=0;
                        ctnflag=FALSE;
                        runflag=FALSE;
                        strcpy(txtscreen.caption,strbuf);
                        break;
                    case 26:   /*清除當前顯示的值(Del鍵)*/
                        Resetbuf();
                        num1=0;
                        strcpy(txtscreen.caption,strbuf);
                        TextBox(txtscreen);
                        break;
                    case 27:   /*清除所有的值,包括存儲的,已經運算了的(ESC鍵)*/
                        Resetbuf();
                        num1=num2=0;
                        ctnflag=FALSE;
                        operatoror=0;
                        runflag=FALSE;
                        errorflag=FALSE;

                        strcpy(txtscreen.caption,"0.");
                        TextBox(txtscreen);

                        break;
                    case 0:
                        Unload();
                        break;
             }
         if(errorflag==FALSE)
             {  if(atof(txtscreen.caption)==0)
                        strcpy(txtscreen.caption,"0");
                    if(strchr(txtscreen.caption,'.')==NULL)
                        strcat(txtscreen.caption,".");
             }
         TextBox(txtscreen); /*顯示txtscreen結構變量的值*/
    }

void DoubleRun() /*四則運算*/
    {  switch(operatoror)
             {      case 13: num2+=num1;break;  /*加*/
                    case 14: num2-=num1;break; /*減*/
                    case 15: num2*=num1;break; /*乘*/
                    case 16: if(num1==0)     /*除*/
                                         errorflag=TRUE;
                                     else
                                         num2/=num1;
                                     break;
             }
         if(errorflag)
             strcpy(txtscreen.caption,"Can't divide by zero!");
         else
             sprintf(txtscreen.caption,"%G",num2);
    }

void SingleRun(int key) /*單運算*/
    {  switch(key)
             {  case 17:  /*求開方*/
                        if(num1<0)
                             errorflag=TRUE;
                        else
                             num1=sqrt(num1);
                        break;
                    case 18:  /*求百分比*/
                             num1/=100;
                        break;
                    case 19: /*求倒數*/
                        if(num1==0)
                             errorflag=TRUE;
                        else
                             num1=1/num1;
                        break;
                }
         if(errorflag==TRUE)
             if(num1<0)
                 strcpy(txtscreen.caption,"Can't blower than zero!");
             else
                 strcpy(txtscreen.caption,"Can't equal to zero!");
         else
             sprintf(txtscreen.caption,"%G",num1);
    }

void StoreSet(int key)  /*記憶存儲操作*/
   {  switch(key)
             {  case 21:   /*保存清除*/
                        store=0;
                        lblstore.caption[0]=0;
                        break;
                case 22:  /*取出保存的值*/
                        num1=store;
                        sprintf(txtscreen.caption,"%G",store);
                        runflag=FALSE;
                        if(ctnflag==FALSE) operatoror=0;
                        break;
                case 23:  /*保存當前數字*/
                        store=num1;
                        strcpy(lblstore.caption,"M");
                        break;
               case 24:  /*保存值與當前數字相加*/
                        store+=num1;
                        strcpy(lblstore.caption,"M");
                        break;
            }
         Label(lblstore);
    }



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章