汇编语言程序设计——仿win7计算器(功能部分)

来源:互联网 发布:手机调试js 编辑:程序博客网 时间:2024/05/16 10:41

   

           下面代码实现的计算机基本的功能,包括加、减、乘、除、求倒、开方、百分比、记忆相关功能等,支持快捷键,显示也可以分段显示,如下图。

            界面部分源码:http://blog.csdn.net/zhangjiajie023/article/details/7728268

            整体设计参考自:http://www.cnblogs.com/kingwolfofsky/archive/2011/07/07/2100375.html

 

        不多说了,下面贴出源代码,挺多的:

;********************************************;      仿win7计算器                         *;                                           *;                CS0****                    *;                     U200915**             *;********************************************.386.model flat,stdcalloption casemap:none;********************************************include  d:\masm32\include\windows.incinclude  d:\masm32\include\shell32.incinclude  d:\masm32\include\user32.incinclude  d:\masm32\include\comctl32.incinclude  d:\masm32\include\masm32.incinclude  d:\masm32\include\kernel32.incincludelib  d:\masm32\lib\user32.libincludelib  d:\masm32\lib\comctl32.libincludelib  d:\masm32\lib\masm32.libincludelib  d:\masm32\lib\kernel32.libincludelib  d:\masm32\lib\shell32.lib;*******************************************IDB_0  EQU  100IDB_1  EQU  101IDB_2  EQU  102IDB_3  EQU  103IDB_4  EQU  104IDB_5  EQU  105IDB_6  EQU  106IDB_7  EQU  107IDB_8  EQU  108IDB_9  EQU  109;------------------------IDB_NEG    EQU  110IDB_POINT  EQU  111IDB_DIV    EQU  112IDB_MUL    EQU  113IDB_SUB    EQU  114IDB_ADD    EQU  115IDB_SQRT   EQU  116IDB_PER    EQU  117IDB_DAO    EQU  118IDB_EQU    EQU  119;------------------------IDB_MC     EQU  120IDB_MR     EQU  121IDB_MS     EQU  122IDB_MPLUS  EQU  123IDB_MSUB   EQU  124IDB_M      EQU  125IDB_BACK   EQU  126IDB_CE     EQU  127IDB_C      EQU  128;------------------------IDT_MEMORY EQU  129IDT_RESULT EQU  130;------------------------Icon          EQU  1000IDM_COPY      EQU  1001IDM_PASTE     EQU  1002IDM_STANDARD  EQU  1003IDM_SCIENCE   EQU  1004IDM_GROUP     EQU  1006IDM_HELP      EQU  1007IDM_ABOUT     EQU  1008IDM_EXIT      EQU  1009IDM_KJJ       EQU  1010IDM_NOTIFYICON  EQU  2000WM_SHELLNOTIFY  EQU  2001;**********************函数原型说明***************************WinMain  PROTO :DWORD, :DWORD, :DWORD, :DWORD     ; 窗口主程序Calculate  PROTO :DWORD, :DWORD, :DWORD, :DWORD ; 消息处理程序Init  PROTO                        ; 初始化NumBtn  PROTO :DWORD             ; 数字按键消息处理程序AddDelNeg  PROTO               ; 添加或删除‘-’号SavePreData  PROTO          ; 保存当前文本框中的数据ShowMemory  PROTO   ; 显示存储信息GetResult  PROTO   ; 双目运算MemoryFunc PROTO :DWORD      ; 记忆加或记忆减GroupNum  PROTO       ; 数字分组UnGroupNum  PROTO           ; 数字取消分组 ;****************************数据段****************************.data      CommandLine  DD  0      Output       DB  "0",0,40 DUP(0)      IsStart      DB  0      IsError      DB  0        HasPoint     DB  0      HasEqual     DB  0          ;判断是否存在等号      HasNeg1      DB  0;各数是否有‘-’号      HasNeg2      DB  0      ResultNeg    DB  0      MemoryNeg    DB  0      IsShowMem    DB  0          ;是否显示记忆      IsGroup      DB  0               Operator     DB  '.'        ;记录双目运算符      Buffer       DB  '.'        ;用于暂存字符           Memory       DQ  0.0      Temporary    DQ  0.0        ;临时数据      Operand1     DQ  0.0        ;操作数1      Operand2     DQ  0.0      Result       DQ  0.0              NumLittle    REAL8    1.0E-12      Num100       REAL8    100.0     ;实数100      NotifyIcon   NOTIFYICONDATA<>   ;通知栏图标;------------------------------------------------------------           .data?      hInstance    DD  ?      hEdit1       DD  ?        ; 下面输出文本框句柄      hEdit2       DD  ?        ; 上面输出文本框句柄      hTextM       DD  ?      hMenu        DD  ?      hIcon        DD  ?      hGlobal      HANDLE  ?      pGlobal      DB  ?;------------------------------------------------------------.const      DivError     DB  "除数不能为0",0      FuncError    DB  "输入函数无效",0      About        DB  '作者: 张**', 0ah,0dh,'时间:2010-10-10',0      ShortCuts    DB  '字母->功能:X->倒数  N->取反  S->开方  E->CE  R->C',0ah,0dh,                       '            Y->MC  U->MR  I->MS  O->M+  P->M-',0      HelpFile     DB  "help.hlp",0      ProgramName  DB  "计算器",0      DialogName   DB  "Calculator",0      MenuName     DB  "Menu",0      IconName     DB  "Icon",0      TextM        DB  'M',0;----------------------------------------------------------;***************************代码段**************************.code   start:   ;----------------------------------------------------------   invoke GetModuleHandle,NULL   mov hInstance,eax   invoke WinMain,hInstance,0,0,SW_SHOWDEFAULT   invoke ExitProcess,eax;---------------------------------------------------------   WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD        LOCAL wc:WNDCLASSEX        LOCAL msg:MSG        LOCAL hWnd:HWND                mov wc.cbSize,sizeof WNDCLASSEX        mov wc.style,CS_BYTEALIGNWINDOW or CS_BYTEALIGNWINDOW        mov wc.lpfnWndProc,OFFSET Calculate        mov wc.cbClsExtra,0        mov wc.cbWndExtra,DLGWINDOWEXTRA        mov eax,hInst        mov wc.hInstance,eax        mov wc.hbrBackground,COLOR_BTNFACE+1        mov wc.lpszMenuName,OFFSET MenuName        mov wc.lpszClassName,OFFSET DialogName        invoke LoadIcon,hInst,addr IconName        mov wc.hIcon,eax        invoke LoadCursor,NULL,IDC_ARROW        mov wc.hCursor,eax        mov wc.hIconSm,0                invoke RegisterClassEx,addr wc        invoke CreateDialogParam,hInst,addr DialogName,0,addr Calculate,0                mov hWnd,eax        invoke ShowWindow,hWnd,CmdShow        invoke UpdateWindow,hWnd             StartLoop:        invoke GetMessage,addr msg,0,0,0        cmp eax,0        je ExitLoop        invoke TranslateMessage,addr msg        invoke DispatchMessage,addr msg        jmp StartLoop     ExitLoop:        mov eax,msg.wParam        ret       WinMain endp;---------------------------------------------------------------;---------------------------------------------------------------;消息处理程序用于处理用户消息。;hWin:窗口句柄;uMsg:消息标识;param1 param2:消息所带的参数;---------------------------------------------------------------Calculate proc hWin:DWORD,uMsg:UINT,param1:DWORD,param2:DWORDLOCAL pt:POINT               ;-------------------------------------------------------      .if uMsg == WM_INITDIALOG          ;初始化窗口              invoke GetDlgItem,hWin,IDT_RESULT              mov hEdit1,eax              invoke GetDlgItem,hWin,IDT_MEMORY              mov hEdit2,eax              invoke GetDlgItem,hWin,IDB_M                 mov hTextM,eax              invoke LoadIcon,hInstance,addr IconName              mov hIcon,eax              invoke SendMessage,hWin,WM_SETICON,ICON_SMALL,eax              invoke LoadMenu,hInstance,addr MenuName              mov hMenu,eax              invoke SetMenu,hWin,eax              invoke CheckMenuRadioItem,hMenu,IDM_STANDARD,IDM_SCIENCE,IDM_STANDARD,MF_BYCOMMAND ;选中标准型              invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output        ;-----------------------------------------------------------      .elseif uMsg == WM_SIZE           .if param1==SIZE_MINIMIZED        ;最小化           mov NotifyIcon.cbSize,sizeof NOTIFYICONDATA         push hWin         pop NotifyIcon.hwnd         mov NotifyIcon.uID,IDM_NOTIFYICON         mov NotifyIcon.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP         mov NotifyIcon.uCallbackMessage,WM_SHELLNOTIFY         mov eax,hIcon         mov NotifyIcon.hIcon,eax         invoke lstrcpy,addr NotifyIcon.szTip,addr ProgramName               invoke Shell_NotifyIcon,NIM_ADD,addr NotifyIcon                 .endif                ;---------------------------------------------------------------       .elseif uMsg == WM_SHELLNOTIFY         .if param1==IDM_NOTIFYICON         .if(param2==WM_LBUTTONDOWN)           ;鼠标左键按下         invoke ShowWindow,hWin,SW_SHOW         invoke Shell_NotifyIcon,NIM_DELETE,addr NotifyIcon         .elseif(param2==WM_RBUTTONDOWN)       ;鼠标右键按下         invoke GetCursorPos,addr pt         invoke GetSubMenu,hMenu,3         invoke TrackPopupMenu,eax,TPM_LEFTALIGN,pt.x,pt.y,NULL,hWin,NULL         .endif         .endif       ;----------------------------------------------------------------       .elseif uMsg == WM_CHAR     ;热键操作         mov eax,param1                  add eax,IDB_0         sub eax,'0'                  .if (eax>=IDB_0) && (eax<=IDB_9)         invoke Calculate,hWin,WM_COMMAND,eax,0                  .elseif (eax==98)         invoke Calculate,hWin,WM_COMMAND,IDB_POINT,0                  .elseif (eax==95)                 invoke Calculate,hWin,WM_COMMAND,IDB_ADD,0                  .elseif (eax==97)         invoke Calculate,hWin,WM_COMMAND,IDB_SUB,0                  .elseif (eax==94)         invoke Calculate,hWin,WM_COMMAND,IDB_MUL,0                  .elseif (eax==97)         invoke Calculate,hWin,WM_COMMAND,IDB_DIV,0                  .elseif (eax==89)                           invoke Calculate,hWin,WM_COMMAND,IDB_PER,0                  .elseif (eax==60)           invoke Calculate,hWin,WM_COMMAND,IDB_BACK,0                  .elseif (eax==113)           invoke Calculate,hWin,WM_COMMAND,IDB_EQU,0         ;-------------------------------------------------         .elseif (eax==140 || eax==172)     ; x 倒数1/x         invoke Calculate,hWin,WM_COMMAND,IDB_DAO,0                  .elseif (eax==135 || eax==167)  ; s 开方         invoke Calculate,hWin,WM_COMMAND,IDB_SQRT,0                    .elseif (eax==130 || eax==162)  ; n 正负         invoke Calculate,hWin,WM_COMMAND,IDB_NEG,0                  .elseif (eax==121 || eax==153)  ; e 清除当前数据         invoke Calculate,hWin,WM_COMMAND,IDB_CE,0                  .elseif (eax==134 || eax==166)  ; r 初始化         invoke Calculate,hWin,WM_COMMAND,IDB_C,0         ;-------------------------------------------------           .elseif (eax==141 || eax==173)  ; y 记忆清零         invoke Calculate,hWin,WM_COMMAND,IDB_MC,0                  .elseif (eax==137 || eax==169)  ; u 显示记忆         invoke Calculate,hWin,WM_COMMAND,IDB_MR,0                  .elseif (eax==125 || eax==157)   ; i 记忆当前数据         invoke Calculate,hWin,WM_COMMAND,IDB_MS,0                    .elseif (eax==131 || eax==163)  ; o 记忆加         invoke Calculate,hWin,WM_COMMAND,IDB_MPLUS,0                    .elseif (eax==132 || eax==164)   ; p 记忆减         invoke Calculate,hWin,WM_COMMAND,IDB_MSUB,0         ;-------------------------------------------------         .elseif (eax==119 || eax==151)   ; c 复制         invoke Calculate,hWin,WM_COMMAND,IDM_COPY,0                  .elseif (eax==138 || eax==170)   ; v 粘贴         invoke Calculate,hWin,WM_COMMAND,IDM_PASTE,0                  .elseif (eax==133 || eax==165) ; q 退出         invoke Calculate,hWin,WM_COMMAND,IDM_EXIT,0                  .elseif (eax==155 || eax==123) ; g 分组        invoke Calculate,hWin,WM_COMMAND,IDM_GROUP,0         .elseif (eax==127 || eax==159) ; k 快捷键         invoke Calculate,hWin,WM_COMMAND,IDM_KJJ,0                 .elseif (eax==124 || eax==156) ; h 帮助         invoke Calculate,hWin,WM_COMMAND,IDM_HELP,0                  .elseif (eax==117 || eax==149) ; a 关于计算器         invoke Calculate,hWin,WM_COMMAND,IDM_ABOUT,0         ;-------------------------------------------------         .endif        ;---------------------------------------------------------        .elseif uMsg == WM_COMMAND          ;按钮消息处理         mov eax,param1         finit         ;---------------------------------------------         .if eax==IDB_C                      ;初始化         invoke Init         mov MemoryNeg,0         fldz         fstp Memory           ;----------------------------------------------         .elseif eax==IDB_CE;清除当前数据         .if IsError==1 || HasEqual==1         invoke Init         ret         .endif                      fldz         .if Operator=='.'         mov IsStart,0                  fst Operand1         mov HasNeg1,0         .else         fst Operand2         mov HasNeg2,0         .endif         fst Temporaryfst Resultfinit         mov HasPoint,0         mov HasEqual,0         mov IsError,0         lea esi,Output         mov BYTE PTR [esi],'0'         mov BYTE PTR [esi+1],0          invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output                   ;-----------------------------------------------         .elseif eax==IDB_BACK               ;退格         .if IsGroup==1         invoke UnGroupNum         .endif                  lea esi,Output                  .if BYTE PTR [esi+1]==0         mov BYTE PTR [esi],'0'         .if Operator=='.'         mov IsStart,0         .endif         .else         .while BYTE PTR [esi]!=0         inc esi         .endw                  mov BYTE PTR [esi-1],0         .endif         invoke StrToFloat,addr Output,addr Temporary         fld Temporary                  ;保存操作数         .if Operator=='.'         fstp Operand1         .else         fstp Operand2         .endif         .if IsGroup==1         invoke GroupNum         .endif         invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output           ;---------------------------------------------         .elseif (eax>=IDB_0) && (eax<=IDB_9)       ;数字按键                  .if HasEqual==1             fldz                  fst Operand1         fst Operand2fst Temporaryfst Resultfinitmov IsStart,0         mov HasPoint,0         mov HasEqual,0         mov HasNeg1,0         mov HasNeg2,0         mov ResultNeg,1         mov Operator,'.'         mov IsError,0         lea esi,Output         mov BYTE PTR [esi],'0'         mov BYTE PTR [esi+1],0                .endif                          invoke NumBtn,eax         ;--------------------------------------------           .elseif eax==IDB_POINT;小数点           .if HasEqual==1           invoke Init           .endif                   .if HasPoint==0         lea esi,Output         .while BYTE PTR [esi]!=0         inc esi         .endw         mov BYTE PTR [esi],'.'         mov BYTE PTR [esi+1],0         mov HasPoint,1         mov IsStart,1         invoke SavePreData         invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output         .endif         ;-------------------------------------------         .elseif eax==IDB_NEG ;取反               invoke AddDelNeg                lea esi,Output.if BYTE PTR [esi]=='0' && BYTE PTR [esi+1]==0;不加负号的情况              .elseif Operator=='.'              xor HasNeg1,1              .elseif Operator!='.'              xor HasNeg2,1              .endif invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output         ;------------------------------------------           .elseif (eax>=IDB_DIV) && (eax<=IDB_ADD)   ;加减乘除           .if Operator!='.' && HasEqual==0           invoke GetResult           .endif  .if eax==IDB_DIV   mov BYTE PTR Operator,'/'   .elseif eax==IDB_MUL  mov BYTE PTR Operator,'*'   .elseif eax==IDB_SUB  mov BYTE PTR Operator,'-'    .elseif eax==IDB_ADD  mov BYTE PTR Operator,'+'     .endif    mov HasEqual,0 mov HasPoint,0 fldz fstp Operand2 mov IsStart,1 invoke SendMessage,hTextM,WM_SETTEXT,0,NULL;------在上面文本框显示操作数1-----lea esi,Outputinvoke FloatToStr,Operand1,addr Output.while BYTE PTR [esi]!=0inc esi.endwmov bl,Operatormov [esi],blmov BYTE PTR [esi+1],0.if HasNeg1==1invoke AddDelNeg.endifinvoke SendMessage,hEdit2,WM_SETTEXT,0,addr Output;------在下面文本框显示0------lea esi,Outputmov BYTE PTR [esi],'0'mov BYTE PTR [esi+1],0invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output          ;-----------------------------------------         .elseif eax==IDB_EQU              ;等于         .if Operator!='.'         invoke GetResult         .endif                  ;------------------------------------------         .elseif eax==IDB_PER              ;百分号         finit         .if Operator=='.'         fld Num100         fld Operand1         fdiv ST(0),ST(1)         fstp Operand1         invoke FloatToStr,Operand1,addr Output         .if HasNeg1==1         invoke AddDelNeg         .endif         .if IsGroup==1         invoke GroupNum         .endif         invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output                   .else    ;功能 Op1 + Op2 % = Op1 + Op1*Op2÷100     fld Num100 fld Operand2 fdiv ST(0),ST(1)              fstp Operand2 ;Op2÷100=>Op2 ;--------保护操作数1及运算符-----           mov bl,Operator mov Buffer,bl        ;Operator=>Buffer mov Operator,'*' fld Operand1 fstp Temporary       ;Op1=>Temporary mov bh,HasNeg1       ;HasNeg1=>bh ;------------------------------------- invoke GetResult     ;Op1*Op2÷100 =>Op1 ;-------运算结果给Op2------- fld Operand1 fstp Operand2 mov bl,HasNeg1 mov HasNeg2,bl    ;-------换回Op1和运算符-----  fld Temporary fstp Operand1        mov HasNeg1,bh mov bl,Buffer mov Operator,bl       invoke GetResult     ;最后一步运算   .endif mov HasEqual,1              ;------------------------------------------         .elseif eax==IDB_DAO           ;倒数         lea esi,Output         mov bx,4000h         finit         .if Operator=='.'         ;只有一个操作数         fld Operand1                           ftst         fstsw ax                  and bx,ax                            jnz dao_error      ;Operand1==0                     fld1               ;Operand1!=0         fld Operand1         fdiv         fst Result         fstp Operand1          mov bl,HasNeg1          mov ResultNeg,bl           mov HasEqual,1              .else                          ;已经有操作数1,并且有双目操作符,算操作数2的倒数          fld Operand2          ftst          fstsw ax          and ax,bx                        jnz dao_error  ;0perand2==0                     fld1               ;0perand2!=0          fld Operand2          fdiv            ;ST(1) ÷ ST(0) => ST(1),弹出ST          fst Result          fstp Operand2                    mov bl,HasNeg2          mov ResultNeg,bl          .endif          jmp dao_show         dao_error:           mov IsError,1         invoke SendMessage,hEdit1,WM_SETTEXT,0,addr DivError          mov BYTE PTR[esi],'0'          mov BYTE PTR[esi+1],0         ret                   dao_show:           invoke FloatToStr,Result,addr Output          .if ResultNeg==1          invoke AddDelNeg          .endif          lea edi,Output          .while BYTE PTR[edi]!=0        ;判断结果是否有小数点          inc edi          .if BYTE PTR [edi]=='.'          mov HasPoint,1          .endif          .endw          .if IsGroup==1          invoke GroupNum          .endif                    invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output         ;-----------------------------------------------         .elseif eax==IDB_SQRT               ;开方         lea esi,Output         finit         .if Operator=='.'             ;只有一个操作数         .if HasNeg1==1         jmp sqrt_error         .endif         fld Operand1         fsqrt         fst Result         fst Operand1          mov HasEqual,1                         .else                       ;已经有操作数1,并且有双目操作符,算操作数2的开方         .if HasNeg2==1         jmp sqrt_error         .endif          fld Operand2           fsqrt          fst Result          fst Operand2         .endif         jmp sqrt_show         sqrt_error:            mov IsError,1          invoke SendMessage,hEdit1,WM_SETTEXT,0,addr FuncError          mov BYTE PTR[esi],'0'          mov BYTE PTR[esi+1],0          ret         sqrt_show:          invoke FloatToStr,Result,addr Output         lea edi,Output          .while BYTE PTR [edi]!=0        ;判断结果是否有小数点          inc edi          .if BYTE PTR [edi]=='.'          mov HasPoint,1          .endif          .endw         .if IsGroup==1         invoke GroupNum         .endif                  invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output                   ;------------------------------------------------         .elseif eax==IDB_MC                  ;清除记忆           fldz           fstp Memory           mov MemoryNeg,0           invoke SendMessage,hTextM,WM_SETTEXT,0,NULL           invoke SendMessage,hEdit2,WM_SETTEXT,0,NULL         ;--------------------------------------------------         .elseif eax==IDB_MR        ;显示记忆           invoke ShowMemory         ;------------------------------------------------           .elseif eax==IDB_MS         ;记忆当前数据          .if Operator=='.' || Operator!='.' && HasEqual==1          fld Operand1          mov bl,HasNeg1          .elseif Operator!='.' && HasEqual==0           fld Operand2          mov bl,HasNeg2          .endif                   fstp Memory          mov MemoryNeg,bl          mov IsShowMem,0          invoke ShowMemory         ;-----------------------------------------------         .elseif eax==IDB_MPLUS        ;记忆加           invoke MemoryFunc,eax         ;------------------------------------------------         .elseif eax==IDB_MSUB        ;记忆减                     invoke MemoryFunc,eax         ;------------------------------------------------         .elseif eax==IDM_COPY  ;复制           invoke GlobalAlloc,GMEM_MOVEABLE,35   ;配置一个内存块                    mov hGlobal ,eax                    invoke GlobalLock,hGlobal             ;锁定内存块                    mov DWORD PTR pGlobal ,eax                    lea esi,Output                    mov edi,DWORD PTR pGlobal                    mov ecx,35                    rep movsb                             ;复制字符串                    invoke GlobalUnlock,hGlobal           ;解锁内存块                    invoke OpenClipboard, NULL            ;打开剪切板                    invoke EmptyClipboard                 ;清空剪切板                    invoke SetClipboardData,CF_TEXT,hGlobal ;把内存句柄交给剪贴簿                    invoke CloseClipboard           ;------------------------------------------------         .elseif eax==IDM_PASTE                    invoke IsClipboardFormatAvailable,CF_TEXT ;确定剪贴簿是否含有CF_TEXT格式的数据                    invoke OpenClipboard,NULL  ;打开剪切板                    invoke GetClipboardData,CF_TEXT       ;得到代表文字的内存块代号                    mov hGlobal,eax                    invoke GlobalLock ,hGlobal            ;解锁内存块                    mov DWORD PTR pGlobal,eax                    mov ecx,35                    lea edi,Output                    mov esi,eax                    rep movsb                             ;复制字符串                    invoke GlobalUnlock ,hGlobal          ;解锁内存块                    invoke CloseClipboard                 ;关闭剪切板                                          invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output                    ;--------------------------------------------------           .elseif eax==IDM_GROUP                      ;分组           .if IsGroup==0           invoke CheckMenuItem,hMenu,IDM_GROUP,MF_CHECKED           invoke GroupNum           .else           invoke CheckMenuItem,hMenu,IDM_GROUP,MF_UNCHECKED           invoke UnGroupNum           .endif           xor BYTE PTR IsGroup,1           invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output         ;---------------------------------------------------         .elseif eax==IDM_KJJ                        ;快捷键帮助           invoke ShellAbout,hWin,addr ProgramName,addr ShortCuts,hIcon         ;----------------------------------------------------         .elseif eax==IDM_HELP           invoke WinHelp,hWin,addr HelpFile,HELP_CONTENTS,1         ;---------------------------------------------------         .elseif eax==IDM_ABOUT           invoke ShellAbout,hWin,addr ProgramName,addr About,hIcon         ;---------------------------------------------------.elseif eax==IDM_EXITinvoke Calculate,hWin,WM_CLOSE,param1,param2           .endif         ;-------------------------------------------------------         .elseif uMsg == WM_CLOSE         invoke Shell_NotifyIcon,NIM_DELETE,addr NotifyIcon         invoke EndDialog,hWin,NULL         invoke PostQuitMessage,0         ;--------------------------------------------------------         .else         invoke DefWindowProc,hWin,uMsg,param1,param2  ;默认消息处理         ret         .endif          ;-------------------------------------------------------          invoke SetFocus,hWin          mov eax,0          ret Calculate endp;------------------------------------------------------------;------------------------------------------------------------; 初始化所有状态变量和FPU寄存器;------------------------------------------------------------Init  procmov IsStart,0mov HasPoint,0mov HasEqual,0mov HasNeg1,0mov HasNeg2,0mov Operator,'.'mov IsError,0   fldz               fst Temporaryfst Resultfst Operand1fst Operand2     finitlea esi,Outputmov BYTE PTR [esi],'0'mov BYTE PTR [esi+1],0invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Outputinvoke SendMessage,hEdit2,WM_SETTEXT,0,NULLinvoke SendMessage,hTextM,WM_SETTEXT,0,NULLretInit endp;-----------------------------------------------------------;-----------------------------------------------------------;数字按键消息处理程序  ;把按钮发送的数值eax添加在Output后面,并调用SavePreData保存;------------------------------------------------------------                        NumBtn proc USES eax,NUM:DWORD   mov eax,NUMsub eax,IDB_0add eax,'0'lea esi,Output.if IsStart==0 mov IsStart,1mov [esi],almov BYTE PTR [esi+1],0.else.if BYTE PTR [esi]=='0' && BYTE PTR [esi+1]==0 && al=='0' ; 0 再输入0 ret;-----不添加数字的情况-------- .elseif BYTE PTR [esi]=='0' && BYTE PTR [esi+1]==0 && al>='1' && al<='9' ; 0 再输入不为0数字mov [esi],almov BYTE PTR [esi+1],0.else.while BYTE PTR [esi]!=0inc esi.endwmov [esi],almov BYTE PTR [esi+1],0.endif.endifinvoke SavePreDatainvoke SendMessage,hEdit1,WM_SETTEXT,0,addr OutputretNumBtn endp                  ;-----------------------------------------------------------;-----------------------------------------------------------;保存当前文本框中的数据;如果运算符还没变变化,则当前显示的是操作数1,否则是操作数2;-----------------------------------------------------------SavePreData proc.if IsGroup==1invoke UnGroupNum.endiflea esi,Output.if Operator=='.'       ;当前显示的是第一个操作数;------------------------------------.if HasNeg1==1invoke AddDelNeg.endifinvoke StrToFloat,addr Output,addr Operand1.if HasNeg1==1invoke AddDelNeg.endif.else;-------------------------------------.if HasNeg2==1invoke AddDelNeg.endif.if IsGroup==1invoke UnGroupNum.endifinvoke StrToFloat,addr Output,addr Operand2.if HasNeg2==1invoke AddDelNeg.endif.endif;-------------------------------------.if IsGroup==1invoke GroupNum.endifretSavePreData endp;-----------------------------------------------------------;-----------------------------------------------------------;显示存储信息;无论Memory为何值,都在上面的文本框中显示M和Memory数值;再按一次MR,取消显示;------------------------------------------------------------ShowMemory  proc        .if IsShowMem==0    ;还没有显示invoke SendMessage,hTextM,WM_SETTEXT,0,addr TextM invoke FloatToStr,Memory,addr Output  .if MemoryNeg==1         invoke AddDelNeg       .endif       invoke SendMessage,hEdit2,WM_SETTEXT,0,addr Output      mov BYTE PTR IsShowMem,1    .else     invoke SendMessage,hTextM,WM_SETTEXT,0,NULL     invoke SendMessage,hEdit2,WM_SETTEXT,0,NULL     mov BYTE PTR IsShowMem,0    .endifretShowMemory endp;-----------------------------------------------------------;-----------------------------------------------------------;在Output字符串前加上或取消‘-’号;有'-'号,则取消;没有'-'号,则添上;-----------------------------------------------------------AddDelNeg proc USES ebx ecxlea esi,Outputlea edi,Output.if BYTE PTR [esi]=='0' && BYTE PTR [esi+1]==0;----显示‘0’时不加----ret.endif;-----------没有‘-’--加上------------------.if BYTE PTR [esi]!='-'      .while BYTE PTR [esi]!=0inc esi.endw.while esi!=edimov bl,[esi]mov [esi+1],bldec esi.endwlea esi,Outputmov bl,[esi]mov [esi+1],blmov BYTE PTR [esi],'-';-----------有了‘-’--删除‘-’号------------.else               .while BYTE PTR [esi]!=0mov bl,[esi+1]mov [esi],blinc esi.endw;---------------------------------------------.endifretAddDelNeg endp;-----------------------------------------------------------;-----------------------------------------------------------;计算双目运算结果;两个操作数都是保存的正数,正负号由HasNeg1和HasNeg2保存;先进行绝对值的运算,再由两操作数的正负判定结果正负;------------------------------------------------------------GetResult  procUSES eax ebxfinit.if IsStart==1   fld Operand2fld Operand1.if Operator=='.'fst Resultjmp show;++++++++++++++++++++++++++++++++++++++++++.elseif Operator=='+'    ;-----------------------------------.if HasNeg1==0 && HasNeg2==0faddmov ResultNeg,0;-----------------------------------.elseif HasNeg1==1 && HasNeg2==0fcom ST(1)jle xiao_deng1           ;小于等于fsub ST(0),ST(1)         ;(-2 + 1)mov ResultNeg,1jmp over1xiao_deng1:                ;(-1 + 2) (-1 + 1)fsub ST(1),ST(0)fstp Resultmov ResultNeg,0  over1:;-----------------------------------.elseif HasNeg1==0 && HasNeg2==1fcom ST(1)jge da_deng2               fsub ST(1),ST(0)        ;(1 + -2)fstp Resultmov ResultNeg,0jmp over2 da_deng2:                ;大于等于fsub   ;(2 + -1) (1 + -1)mov ResultNeg,1over2:;-----------------------------------.elseif HasNeg1==1 && HasNeg2==1faddmov ResultNeg,1.endif;-----------------------------------------.elseif Operator=='-';-----------------------------------.if HasNeg1==0 && HasNeg2==0fcom ST(1)jge da_deng3  fsub ST(1),ST(0)      ;(1 - 2)fstp Resultmov ResultNeg,0da_deng3:             ;(1 - 1)(2 - 1)fsub mov ResultNeg,1 over3:;-----------------------------------.elseif HasNeg1==1 && HasNeg2==0faddmov ResultNeg,1;-----------------------------------.elseif HasNeg1==0 && HasNeg2==1faddmov ResultNeg,0;-----------------------------------.elseif HasNeg1==1 && HasNeg2==1fcom ST(1)jle xiao_deng4       fsub                 ;(-2 - -1)mov ResultNeg,1xiao_deng4:;(-1 - -1)(-1 - -2)fsub ST(1),ST(0)fstp Resultmov ResultNeg,0over4:.endif;**************************************.elseif Operator=='*'fmulmov bl,HasNeg1xor bl,HasNeg2mov ResultNeg,bl;÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷.elseif Operator=='/'mov bx,4000hfld Operand2ftst         fstsw ax                           and bx,ax                   jz NotZeromov IsError,1invoke SendMessage,hEdit1,WM_SETTEXT,0,addr DivErrorretNotZero:fstp Operand2    fdiv ST(0),ST(1)mov bl,HasNeg1xor bl,HasNeg2mov ResultNeg,bl.endif ;----------------------------------------;-----获得结果------fst Operand1fstp Resultmov bl,ResultNegmov HasNeg1,bl mov HasPoint,0 mov HasEqual,1.endif;--------------显示结果------------------------show:invoke FloatToStr,Result,addr Outputlea edi,Output.while BYTE PTR [edi]!=0inc edi.if BYTE PTR [edi]=='.'mov HasPoint,1.endif.endw.if IsGroup==1invoke GroupNum.endif.if ResultNeg==1invoke AddDelNeg.endifinvoke SendMessage,hEdit1,WM_SETTEXT,0,addr Outputinvoke SendMessage,hEdit2,WM_SETTEXT,0,NULLretGetResult endp;------------------------------------------------------------  ;------------------------------------------------------------;记忆加/记忆减;包括记忆加和记忆减;------------------------------------------------------------MemoryFunc proc USES eax ebx,param:DWORDmov eax,paramfinit;----------当前显示的是第一个操作数----------      .if Operator=='.'                          fld Memory      fld Operand1        fstp Operand2      ;Op1=>Op2         fstp Operand1      ;Memory=>Op1                  mov bl,MemoryNeg         mov HasNeg1,bl     ;Memory的符号给Op1的符号         .if eax==IDB_MPLUS         mov BYTE PTR Operator,'+'         .elseif eax==IDB_MSUB         mov BYTE PTR Operator,'-'         .endif         invoke GetResult   ;Op1+Op2=>Op1         fld Operand1         fstp Memory        ;Op1=>Memory         mov bl,HasNeg1         mov MemoryNeg,bl   ;Op1的符号给Memory         mov Operator,'.'                  mov bl,0         mov IsShowMem,bl         invoke ShowMemory                ;---------当前显示的是第二个操作数-------------         .elseif Operator!='.'              ;-----保护运算符和操作数1---------         mov bl,Operator         mov Buffer,bl      ;Operator=>Buffer          fld Operand1         fstp Temporary     ;Op1暂存Temporary         mov bh,HasNeg1     ;Op1的符号位暂存在BH         ;---------------------------------         .if eax==IDB_MPLUS         mov BYTE PTR Operator,'+'         .elseif eax==IDB_MSUB         mov BYTE PTR Operator,'-'         .endif           fld Memory         fstp Operand1      ;Memory=>Op1         mov bl,MemoryNeg         mov HasNeg1,bl     ;Memory的符号给Opd1的符号         invoke GetResult   ;Op2+Memory=>Op1         ;-----------------------------------         fld Operand1           fst Operand2       ;记忆运算的结果给Op2和Mempry         fstp Memory         mov bl,HasNeg1         mov HasNeg2,bl     ;运算结果符号位给Op2和Mempry符号位         mov MemoryNeg,bl         ;-----换回运算符和操作数1----------           fld Temporary         fstp Operand1               mov HasNeg1,bh             mov bl,Buffer               mov Operator,bl          invoke SendMessage,hTextM,WM_SETTEXT,0,NULL         invoke SendMessage,hEdit2,WM_SETTEXT,0,NULL         ;----------在上面的文本框显示操作数1----------  lea esi,Output  invoke FloatToStr,Operand1,addr Output  .while BYTE PTR [esi]!=0inc esi  .endwmov bl,Operatormov [esi],blmov BYTE PTR [esi+1],0.if HasNeg1==1invoke AddDelNeg.endifinvoke SendMessage,hEdit2,WM_SETTEXT,0,addr Output.endif        retMemoryFunc endp;------------------------------------------------------------                     ;------------------------------------------------------------;GroupNum函数将输出数据的字符串Output进行数字分组。;它首先获取小数点以前的数字位数并保存在寄存器eax中,然后将;(eax-1)÷3 => eax,即为需要添加的字符‘,’数目,;对于小数点及以后的字符都向后移动eax位,对于小数点以前的字符,;向后移动eax位并用ecx计数,当ecx计数到3时添加字符‘,’;并将ecx设为1且eax减一,重复上述步骤直到eax等于0;-------------------------------------------------------------GroupNum proc USES eax ebx ecx edxlea esi,Outputmov eax,0;----------有小数点---------------------------.if HasPoint==1.while BYTE PTR [esi]!='.'inc eaxinc esi.endw.while BYTE PTR [esi]!=0inc esi.endwdec eaxmov edx,0mov ecx,3div ecx                     ;得到需要添加‘,’的个数.while BYTE PTR [esi]!='.'  ;移动小数点之后的数据mov bx,[esi]mov [esi+eax],bxdec esi.endwmov bx,[esi]                 ;移动小数点mov [esi+eax],bx;-----------没有小数点--------------------------.elseif HasPoint==0.while BYTE PTR [esi]!=0inc esiinc eax.endwdec eaxmov edx,0mov ecx,3div ecx.endif;-----------------------------------------------dec esimov ecx,0.while eax!=0.if ecx<3mov bx,[esi]mov [esi+eax],bxinc ecx.elsemov BYTE PTR [esi+eax],','dec eaxmov ecx,1.endifdec esi.endwretGroupNum endp;-----------------------------------------------------------;-----------------------------------------------------------;UnGroupNum函数将进行数字分组输出的字符串Output解分组。;它首先获取Output地址存在esi中,然后ecx赋0,并将Output中字符;向前移动ecx个单位,遇见‘,’字符则将ecx加1,直到字符串结束;------------------------------------------------------------UnGroupNum proc USES ebx ecxlea esi,Outputmov ecx,0.while BYTE PTR [esi+ecx]!=0.if BYTE PTR [esi]==','inc ecx.endif  mov bx,[esi+ecx]       mov [esi],bx  inc esi.endwretUnGroupNum endp;-----------------------------------------------------------                end start;************************************************************            

版权所有