算是学习windows编程后的第一个作品吧,想想还是把写过的东西留些在网上吧,算是另一种硬盘,电脑硬盘不靠谱(虽然从装机2年操作系统都没重装过一次...)
基本界面实现
#include <windows.h> #include "core.h" //计算器功能核心,表达树实现表达式计算,支持浮点数 #include "resource.h" BOOL CALLBACK DialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); char source [MAX_SIZE]; char dest [40]; double cal_result; HINSTANCE hInst; int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) { hInst = hInstance; DialogBoxParam (hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, DialogProc, 0); return 1; } BOOL CALLBACK DialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND hInput = GetDlgItem (hDlg, IDC_INPUT); HWND hOut = GetDlgItem (hDlg, IDC_OUT); static HBITMAP hBitmap; BITMAP bitmap; HDC hdc, hdcMem ; PAINTSTRUCT ps ; switch (message) { case WM_INITDIALOG:printf("a"); SetWindowTextA (GetDlgItem (hDlg, IDC_INPUT), "0"); hBitmap = LoadBitmap(hInst, L"BitBlt"); //GetObject (hBitmap, sizeof (bitmap), &bitmap); return true; case WM_PAINT: hdc = BeginPaint(hDlg, &ps); hdcMem = CreateCompatibleDC(hdc); SelectObject(hdcMem, hBitmap); StretchBlt (hdc, 0, 0, 550, 420, hdcMem, 0, 0, 550, 380, MERGECOPY) ; DeleteDC(hdcMem); EndPaint (hDlg, &ps); return true; case WM_COMMAND: switch (LOWORD (wParam)) { case IDM_HELP_ABOUT: if (DialogBox (hInst, TEXT ("AboutBox"), hDlg, AboutDlgProc)) InvalidateRect (hDlg, NULL, TRUE) ; return 0 ; case IDC_0: strcat (source, "0"); SetWindowTextA (hInput, source); break; case IDC_1: strcat (source, "1"); SetWindowTextA (hInput, source); break; case IDC_2: strcat (source, "2"); SetWindowTextA (hInput, source); break; case IDC_3: strcat (source, "3"); SetWindowTextA (hInput, source); break; case IDC_4: strcat (source, "4"); SetWindowTextA (hInput, source); break; case IDC_5: strcat (source, "5"); SetWindowTextA (hInput, source); break; case IDC_6: strcat (source, "6"); SetWindowTextA (hInput, source); break; case IDC_7: strcat (source, "7"); SetWindowTextA (hInput, source); break; case IDC_8: strcat (source, "8"); SetWindowTextA (hInput, source); break; case IDC_9: strcat (source, "9"); SetWindowTextA (hInput, source); break; case IDC_ADD: strcat (source, "+"); SetWindowTextA (hInput, source); break; case IDC_SUB: strcat (source, "-"); SetWindowTextA (hInput, source); break; case IDC_MUL: strcat (source, "*"); SetWindowTextA (hInput, source); break; case IDC_DIV: strcat (source, "/"); SetWindowTextA (hInput, source); break; case IDC_DOT: strcat (source, "."); SetWindowTextA (hInput, source); break; case IDC_DEL: source [strlen(source)-1] = '\0'; SetWindowTextA (hInput, source); break; case IDC_CLEAR: strcpy (source, "\0"); SetWindowTextA (hInput, "0"); SetWindowTextA (hOut, "0"); break; case IDC_LEFT_BRACKET: strcat (source, "("); SetWindowTextA (hInput, source); break; case IDC_RIGHT_BRACKET: strcat (source, ")"); SetWindowTextA (hInput, source); break; case IDC_VALUE: if (head != NULL) { destroy(head);//销毁表达式树 head = NULL; } if (!check1(source)) { MessageBox (hDlg, TEXT("括号不匹配"), TEXT("提示"), 0); break; } if (!check2(source)) { MessageBox (hDlg, TEXT("表达式错误"), TEXT("提示"), 0); break; } convert(source); postfix(source); head = Create_Tree (&head, source); cal_result = cal(head); sprintf (dest,"%.4lf",cal_result); SetWindowTextA (hOut, dest); break; case IDCANCEL: if (head != NULL) { destroy(head); head = NULL; } EndDialog(hDlg,0); return true; } return true; } return false; } BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG : return TRUE ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDOK : case IDCANCEL : EndDialog (hDlg, 0) ; return TRUE ; } break ; } return FALSE ; }
#ifndef CORE_H #define CORE_H #include <stdio.h> #include <string.h> #include <ctype.h> #define MAX_SIZE 40 #define MAX_STACK 15 #define MALLOC(p,s)\ if(!((p) = (ExpTree *) malloc (s) ) )\ {\ fprintf(stderr,"insufficient memory\n");\ exit(EXIT_FAILURE);\ } typedef enum { Oper, Date, End } flag; typedef struct v { flag tag; double value; }element;//表达式树节点结构 element ele[MAX_SIZE];//存储转换表达式树所需数组 typedef struct NODE { element date; struct NODE* left; struct NODE* right; }ExpTree; ExpTree *head; int postfix(char *str)//转换成后缀表达式 { element temp[MAX_SIZE]; //char s[MAX_SIZE];//源字符串副本 char stack[MAX_SIZE];//符号栈 int i,top=-1,j=0; memset(stack,0,sizeof(stack)); //strcpy(s,str); memcpy(temp,ele,sizeof(ele)); memset(ele,0,sizeof(ele)); //memset(str,0,sizeof(str)); for(i = 0; temp[i].tag != End ; i++) { switch(temp[i].tag) { case Oper: switch ((int)temp[i].value ) { case '*': while(top>=0&&stack[top]!='('&&stack[top]!='+'&&stack[top]!='-'&&top!=-1) { ele[j].value=stack[top--]; ele[j++].tag=Oper; } stack[++top]='*'; break; case '/': while(top>=0&&stack[top]!='('&&stack[top]!='+'&&stack[top]!='-'&&top!=-1) { ele[j].value=stack[top--]; ele[j++].tag=Oper; } stack[++top]='/'; break; case '+': while(top>=0&&stack[top]!='(') { ele[j].value=stack[top--]; ele[j++].tag=Oper; } stack[++top]='+'; break; case '-': while(top>=0&&stack[top]!='(') { ele[j].value=stack[top--]; ele[j++].tag=Oper; } stack[++top]='-'; break; case '(': stack[++top]='('; break; case ')': while(stack[top]!='(') { ele[j].value=stack[top--]; ele[j++].tag=Oper; } top--; break; } break; case Date: ele[j].tag = Date; ele[j++].value= temp[i].value; break; } } while(top>=0) { ele[j].tag = Oper; ele[j++].value=stack[top--]; } ele[j].tag = End; return TRUE; } void convert(char *str)//将表达式中的浮点字符串转换成浮点数 { char temp[MAX_SIZE/2];//临时存储浮点数的字符串用于转换成浮点数 int i,j,t; for (i = 0, j=0; str[i] != '\0'; i++) { if (str[i] == '+' || str[i] == '*' || str[i] == '/' || str[i] == '(' || str[i] == ')' || (str[i] == '-' && i!=0 && str[i-1] != '(') )//处理了负数的特殊情况 { ele[j].tag = Oper; ele[j].value = str[i]; j++; } else { t = 0; while (1) { temp[t++] = str[i]; if (str[i+1] == '+' || str[i+1] == '-' || str[i+1] == '*' || str[i+1] == '/' || str[i+1] == '(' || str[i+1] == ')' || str[i+1] == '\0') break; i++; } temp[t]='\0'; ele[j].tag = Date; ele[j].value= atof(temp); strcpy(temp,"\0"); j++; } } ele[j].tag = End; } ExpTree* Create_Tree(ExpTree **root,char *str)//生成表达式树 { ExpTree *p=NULL; ExpTree *stack[MAX_STACK]; int i,top=-1; for(i = 0; ele[i].tag != End; i++) { switch(ele[i].tag) { case Oper: MALLOC( p, sizeof(*p) ); p->date = ele[i]; p->right = stack[top--]; p->left = stack[top--]; *root = stack[++top]=p; break; case Date: MALLOC( p, sizeof(*p) ); p->date = ele[i]; p->left = p->right=NULL; stack[++top] = p; break; } } return *root; } double cal (ExpTree *root)//计算表达式树 { double result1,result2; if ( root) { result1 = cal (root->left); result2 = cal (root->right); switch (root->date.tag) { case Oper: switch ( (int)root->date.value) { case '+': return result1 + result2; case '-': return result1 - result2; case '*': return result1 * result2; case '/': return result1 / result2; } case Date: return root->date.value; } } return 0; } void destroy(ExpTree *root) { if (root) { destroy (root->left); destroy (root->right); free (root); } } int check1(char *str)//检查括号匹配 { int brac=0,i; for(i=0;str[i]!='\0';i++) { if(str[i]=='(') brac++; if(str[i]==')') brac--; if(brac < 0) return FALSE; } if(brac==0) return TRUE; return FALSE; } int check2(char *str)//检查表达式 { int oper,i; if ( !isdigit(str[0]) && str[0] != '(' && str[0] != '-' ) return FALSE; if (!isdigit(str[strlen(str)-1]) && str[strlen(str)-1] != ')' ) return FALSE; for ( i = 0,oper = 0; str[i] != '\0'; i++) if ((str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/') && (str[i+1] == '+' || str[i+1] == '-' || str[i+1] == '*' || str[i+1] == '/' ) ) //连续多个操作符 return FALSE; return TRUE; } #endif