; #########################################################################
.386
.model flat, stdcall
option casemap :none ; case sensitive
; #########################################################################
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\masm32.lib
; include macro.asm
; #########################################################################
szText MACRO Name, Text:VARARG
LOCAL lbl
jmp lbl
Name db Text,0
lbl:
ENDM
m2m MACRO M1, M2
push M2
pop M1
ENDM
return MACRO arg
mov eax, arg
ret
ENDM
CTXT MACRO quoted_text:VARARG
comment *
这些宏定义在这里没什么实际意义,但是如果把这些写好放在一个文件里,这样如果经常使用直接
包含这个文件就方便了很多,O(∩_∩)O哈哈~,书上看到的,虽然对我这个小程序不实用,但是好习惯要学习。
*
EXITM <offset literal(quoted_text)>
ENDM
literal MACRO quoted_text:VARARG
LOCAL local_text
.data
local_text db quoted_text,0
.code
EXITM <local_text>
ENDM
RadioID01 equ 2001
RadioID02 equ 2002
RadioID03 equ 2003
RadioID04 equ 2004
RadioID05 equ 2005
RadioID06 equ 2006
EditID01 equ 700
EditID02 equ 701
ButtonID equ 500
ID_Timer equ 1
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
TopXY PROTO :DWORD,:DWORD
Paint_Proc PROTO :DWORD,:DWORD
NcPaint_Proc PROTO :DWORD,:DWORD
FrameCtrl PROTO :DWORD,:DWORD,:DWORD,:DWORD
FrameWindow PROTO :DWORD,:DWORD,:DWORD,:DWORD
EditSl PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
Static PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
PushButton PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
DecToBin PROTO
BinToDec PROTO
DecToOct PROTO
OctToDec PROTO
DecToHex PROTO
HexToDec PROTO
.data
szDisplayName db "Number System Converter(Binary Octal Decimal Hexadecimal)",0
szText1 db "请输入正确的二进制数(0、1)",0
szCaption1 db "二进制与十进制间的转换",0
szText2 db "请输入正确的八进制数(0-8)",0
szCaption2 db "八进制与十进制间的转换",0
szText3 db "请输入正确的十六进制数(0-9,a-f或A-F)",0
szCaption3 db "十六进制与十进制间的转换",0
CommandLine dd 0
hWnd dd 0
hInstance dd 0
hEdit1 dd 0
hEdit2 dd 0
hButn1 dd 0
hFont dd 0 ;字体
szChange01 db "十进制到二进制",0
szChange02 db "二进制到十进制",0
szChange03 db "十进制到八进制",0
szChange04 db "八进制到十进制",0
szChange05 db "十进制到十六进制",0
szChange06 db "十六进制到十进制",0
szFmtDecToHex db '%x',0
szFmtHexToDec db '%u',0
.DATA?
hRadio01 dd ?
hRadio02 dd ?
hRadio03 dd ?
hRadio04 dd ?
szBuf db 128 dup(?)
dwLen dd ? ;标题长度 字节数
dwNum dd ? ;走过的长度 字节数
.code
start:
invoke GetModuleHandle,NULL
mov hInstance, eax
invoke GetCommandLine
mov CommandLine, eax
invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke ExitProcess,eax
; #########################################################################
WinMain proc hInst :DWORD,
hPrevInst :DWORD,
CmdLine :DWORD,
CmdShow :DWORD
LOCAL wc :WNDCLASSEX
LOCAL msg :MSG
LOCAL Wwd :DWORD
LOCAL Wht :DWORD
LOCAL Wtx :DWORD
LOCAL Wty :DWORD
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW \
or CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc, offset WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
m2m wc.hInstance, hInst ;<< NOTE: macro not mnemonic
mov wc.hbrBackground, COLOR_WINDOW+9
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, offset szClassName
invoke LoadIcon,hInst,500 ; icon ID
mov wc.hIcon, eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor, eax
mov wc.hIconSm, 0
invoke RegisterClassEx, ADDR wc
mov Wwd, 400 ;窗口的宽度
mov Wht, 300 ;窗口的高度
invoke GetSystemMetrics,SM_CXSCREEN
invoke TopXY,Wwd,eax
mov Wtx, eax
invoke GetSystemMetrics,SM_CYSCREEN
invoke TopXY,Wht,eax
mov Wty, eax
szText szClassName,"Template_Class"
invoke CreateWindowEx, WS_EX_CLIENTEDGE,
ADDR szClassName,
ADDR szDisplayName,
WS_POPUP or WS_CAPTION,
Wtx,Wty,Wwd,Wht,
NULL,NULL,
hInst,NULL
mov hWnd,eax
INVOKE CreateWindowEx, WS_EX_DLGMODALFRAME, CTXT("button"), addr szChange01,\
WS_CHILD or WS_VISIBLE or WS_TABSTOP or BS_AUTORADIOBUTTON,\
00,90,200,30, hWnd, RadioID01, hInst, NULL
mov hRadio01, eax
INVOKE CreateWindowEx, WS_EX_DLGMODALFRAME, CTXT("button"), addr szChange02,\
WS_CHILD or WS_VISIBLE or WS_TABSTOP or BS_AUTORADIOBUTTON,\
200,90,200,30, hWnd, RadioID02, hInst, NULL
mov hRadio02, eax
INVOKE CreateWindowEx, WS_EX_DLGMODALFRAME, CTXT("button"), addr szChange03,\
WS_CHILD or WS_VISIBLE or WS_TABSTOP or BS_AUTORADIOBUTTON,\
00,120,200,30, hWnd, RadioID03, hInst, NULL
mov hRadio01, eax
INVOKE CreateWindowEx, WS_EX_DLGMODALFRAME, CTXT("button"), addr szChange04,\
WS_CHILD or WS_VISIBLE or WS_TABSTOP or BS_AUTORADIOBUTTON,\
200,120,200,30, hWnd, RadioID04, hInst, NULL
mov hRadio02, eax
INVOKE CreateWindowEx, WS_EX_DLGMODALFRAME, CTXT("button"), addr szChange05,\
WS_CHILD or WS_VISIBLE or WS_TABSTOP or BS_AUTORADIOBUTTON,\
00,150,200,30, hWnd, RadioID05, hInst, NULL
mov hRadio01, eax
INVOKE CreateWindowEx, WS_EX_DLGMODALFRAME, CTXT("button"), addr szChange06,\
WS_CHILD or WS_VISIBLE or WS_TABSTOP or BS_AUTORADIOBUTTON,\
200,150,200,30, hWnd, RadioID06, hInst, NULL
mov hRadio02, eax
invoke ShowWindow,hWnd,SW_SHOWNORMAL
invoke UpdateWindow,hWnd
StartLoop:
invoke GetMessage,ADDR msg,NULL,0,0
cmp eax, 0
je ExitLoop
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp StartLoop
ExitLoop:
return msg.wParam
WinMain endp
; #########################################################################
WndProc proc hWin :DWORD,
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD
LOCAL hDC :DWORD
LOCAL Ps :PAINTSTRUCT
.if uMsg == WM_COMMAND
mov eax,wParam
.IF ax==RadioID01 ;响应按键的动作
shr eax,16
.IF ax==BN_CLICKED
invoke DecToBin
.ENDIF
.ENDIF
.IF ax==RadioID02
shr eax,16
.IF ax==BN_CLICKED
INVOKE BinToDec
.ENDIF
.ENDIF
.IF ax==RadioID03
shr eax,16
.IF ax==BN_CLICKED
invoke DecToOct
.ENDIF
.ENDIF
.IF ax==RadioID04
shr eax,16
.IF ax==BN_CLICKED
invoke OctToDec
.ENDIF
.ENDIF
.IF ax==RadioID05
shr eax,16
.IF ax==BN_CLICKED
INVOKE DecToHex
.ENDIF
.ENDIF
.IF ax==RadioID06
shr eax,16
.IF ax==BN_CLICKED
INVOKE HexToDec
.ENDIF
.ENDIF
.if wParam == 500 ;按退出时的响应
invoke SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL
.endif
;***************************************************************************************************
.elseif uMsg == WM_CREATE
szText font1,"黑体"
invoke CreateFont,20,8,0,0,600,0,0,0, \ ;设置字体
DEFAULT_CHARSET,0,0,0,\
DEFAULT_PITCH,ADDR font1
mov hFont, eax ;hFont里存的是字体的句柄
szText adrTxt,0
szText lbl3," 数制转换器(二进制 八进制 十进制 十六进制)"
invoke Static,ADDR lbl3,hWin,00,00,400,30,0
szText lbl1," ****转换前的数(请输入至多十位正数)****"
invoke Static,ADDR lbl1,hWin,00,30,400,30,0
szText lbl2," ****转换后的数(请输入至多十位正数)****"
invoke Static,ADDR lbl2,hWin,00,180,400,30,0
invoke EditSl,ADDR adrTxt,00,60,500,23,hWin,700
mov hEdit1, eax
invoke EditSl,ADDR adrTxt,00,210,400,23,hWin,701
mov hEdit2, eax
szText ButnTxt,"退出"
invoke PushButton,ADDR ButnTxt,hWin,0,240,400,25,500
mov hButn1, eax
invoke SetTimer,hWin,ID_Timer,500,0 ;定时器 0.5s触发一次
xor eax,eax
mov dwNum,eax
invoke lstrlen,offset szDisplayName
mov dwLen,eax
.elseif uMsg == WM_TIMER
mov eax,dwNum
inc eax ;每次加1
mov dwNum,eax
lea eax,szDisplayName
add eax,dwNum
invoke lstrcpy,offset szBuf,eax ;先将后面的复制过去
invoke lstrlen,offset szBuf
lea ecx,szBuf
add ecx,eax ;指向刚才复制的字符串的末尾
sub eax,dwLen
neg eax ;求出剩下的长度
invoke lstrcpyn,ecx,offset szDisplayName,eax
mov eax,dwNum
.if eax >= dwLen ;若当前位置大于长度则重新开始
xor eax,eax
mov dwNum,eax
.endif
invoke SetWindowText,hWin,offset szBuf
;******************************************************************************************************
.elseif uMsg == WM_PAINT
invoke BeginPaint,hWin,ADDR Ps
mov hDC, eax
invoke Paint_Proc,hWin,hDC
invoke EndPaint,hWin,ADDR Ps
return 0
.elseif uMsg == WM_NCPAINT ;窗口重绘消息
szText scrn,"DISPLAY"
invoke CreateDC,ADDR scrn,NULL,NULL,NULL
mov hDC, eax
invoke NcPaint_Proc,hWin,hDC
invoke DeleteDC,hDC
return 0
.elseif uMsg == WM_CLOSE
.elseif uMsg == WM_DESTROY
invoke PostQuitMessage,NULL
return 0
.endif
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
WndProc endp
;**************************************************************************
;二进制与十进制之间的转换
;**************************************************************************
DecToBin proc
local @szBuffer1[256]:BYTE
local @szBuffer2[256]:BYTE
invoke GetDlgItemInt,hWnd,EditID01,NULL,FALSE
.if eax
mov ebx,2
lea esi,@szBuffer1
xor ecx,ecx
.while eax!=0
xor edx,edx
div ebx
add edx,'0'
mov [esi],edx
inc esi
inc ecx
.endw ;除2取余
lea edi,@szBuffer2
.repeat
mov edx, [esi-1]
mov [edi],edx ;把存在@szBuffer1中的余数反过来存在@szBuffer2 中
inc edi
dec esi
.untilcxz
mov BYTE ptr [edi],0
invoke SetDlgItemText, hWnd ,EditID02,addr @szBuffer2
.else
invoke SetDlgItemInt, hWnd ,EditID02,eax,TRUE
.endif
ret
DecToBin endp
BinToDec proc
local @szBuffer [512]:byte
invoke GetDlgItemText, hWnd ,EditID01,addr @szBuffer,sizeof @szBuffer
lea esi,@szBuffer
cld
xor eax,eax
mov ebx,2
.while TRUE
movzx ecx,BYTE ptr [esi]
inc esi
.break .if !ecx
.if (ecx>='0')&&(ecx<='1')
sub ecx,'0'
.else
invoke MessageBox,hWnd,addr szText1,addr szCaption1, MB_ICONWARNING
.break
.endif
mul ebx
add eax,ecx
.endw
invoke SetDlgItemInt, hWnd ,EditID02,eax,TRUE
ret
BinToDec endp
;****************************************************************************************
;八进制与十进制之间的转换
;****************************************************************************************
DecToOct proc
local @szBuffer1[256]:BYTE
local @szBuffer2[256]:BYTE
invoke GetDlgItemInt,hWnd,EditID01,NULL,FALSE
.if eax
mov ebx,8
lea esi,@szBuffer1
xor ecx,ecx
.while eax!=0
xor edx,edx
div ebx
add edx,'0'
mov [esi],edx
inc esi
inc ecx
.endw ;除8取余
lea edi,@szBuffer2
.repeat
mov edx, [esi-1]
mov [edi],edx ;把存在@szBuffer1中的余数反过来存在@szBuffer2 中
inc edi
dec esi
.untilcxz
mov BYTE ptr [edi],0
invoke SetDlgItemText, hWnd ,EditID02,addr @szBuffer2
.else
invoke SetDlgItemInt, hWnd ,EditID02,eax,TRUE
.endif
ret
DecToOct endp
OctToDec proc
local @szBuffer [512]:byte
invoke GetDlgItemText, hWnd ,EditID01,addr @szBuffer,sizeof @szBuffer
lea esi,@szBuffer
cld
xor eax,eax
mov ebx,8
.while TRUE
movzx ecx,BYTE ptr [esi]
inc esi
.break .if !ecx
.if (ecx>='0')&&(ecx<='8')
sub ecx,'0'
.else
invoke MessageBox,hWnd,addr szText2,addr szCaption2, MB_ICONWARNING
.break
.endif
mul ebx
add eax,ecx
.endw
lop: invoke SetDlgItemInt, hWnd ,EditID02,eax,TRUE
ret
OctToDec endp
;********************************************************************************
;十六进制与十进制之间的转换
;********************************************************************************
DecToHex proc
local @szBuffer [512]:byte
invoke GetDlgItemInt, hWnd ,EditID01,NULL,FALSE
invoke wsprintf ,addr @szBuffer,addr szFmtDecToHex,eax
invoke SetDlgItemText,hWnd,EditID02,addr @szBuffer
ret
DecToHex endp
HexToDec proc
local @szBuffer [512]:byte
invoke GetDlgItemText, hWnd ,EditID01,addr @szBuffer,sizeof @szBuffer
lea esi,@szBuffer
cld
xor eax,eax
mov ebx,16
.while TRUE
movzx ecx,BYTE ptr [esi]
inc esi
.break .if !ecx
.if (ecx>='a')&&(ecx<='f')
sub ecx,'a'-0ah
.elseif(ecx>='A')&&(ecx<='F')
sub ecx,'A'-0Ah
.elseif (ecx>='0')&&(ecx<='9')
sub ecx,'0'
.elseif
invoke MessageBox,hWnd,addr szText3,addr szCaption3, MB_ICONWARNING
.break
.endif
mul ebx
add eax,ecx
.endw
invoke wsprintf,addr @szBuffer,addr szFmtHexToDec,eax
invoke SetDlgItemText, hWnd ,EditID02,addr @szBuffer
ret
HexToDec endp
; ########################################################################
TopXY proc wDim:DWORD, sDim:DWORD
shr sDim, 1 ; divide screen dimension by 2
shr wDim, 1 ; divide window dimension by 2
mov eax, wDim ; copy window dimension into eax
sub sDim, eax ; sub half win dimension from half screen dimension
return sDim
TopXY endp
EditSl proc szMsg:DWORD,a:DWORD,b:DWORD,
wd:DWORD,ht:DWORD,hParent:DWORD,ID:DWORD
LOCAL hndle:DWORD
szText slEdit,"EDIT"
invoke CreateWindowEx, WS_EX_CONTROLPARENT,ADDR slEdit,szMsg,
WS_VISIBLE or WS_CHILDWINDOW or \
ES_AUTOHSCROLL or ES_NOHIDESEL,
a,b,wd,ht,hParent,ID,hInstance,NULL
mov hndle, eax
invoke SendMessage,hndle,WM_SETFONT,hFont,1
mov eax, hndle
ret
EditSl endp
Static proc lpText:DWORD,hParent:DWORD,
a:DWORD,b:DWORD,wd:DWORD,ht:DWORD,ID:DWORD
LOCAL hndle:DWORD
szText statClass,"STATIC"
invoke CreateWindowEx,WS_EX_DLGMODALFRAME,
ADDR statClass,lpText,
WS_CHILD or WS_VISIBLE or SS_LEFT,
a,b,wd,ht,hParent,ID,
hInstance,NULL
mov hndle, eax
invoke SendMessage,hndle,WM_SETFONT,hFont, 0
mov eax, hndle
ret
Static endp
PushButton proc lpText:DWORD,hParent:DWORD,
a:DWORD,b:DWORD,wd:DWORD,ht:DWORD,ID:DWORD
LOCAL hndle:DWORD
szText btnClass,"BUTTON"
invoke CreateWindowEx,0,
ADDR btnClass,lpText,
WS_CHILD or WS_VISIBLE,
a,b,wd,ht,hParent,ID,
hInstance,NULL
mov hndle, eax
invoke SendMessage,hndle,WM_SETFONT,hFont, 0
mov eax, hndle
ret
PushButton endp
; ########################################################################
NcPaint_Proc proc hWin:DWORD,hDC:DWORD
LOCAL btn_hi :DWORD
LOCAL btn_lo :DWORD
LOCAL Rct :RECT
invoke GetSysColor,COLOR_BTNHIGHLIGHT ;按钮的3D加亮区
mov btn_hi, eax
invoke GetSysColor,COLOR_BTNSHADOW ;按钮的3D阴影
mov btn_lo, eax
invoke GetWindowRect,hWin,ADDR Rct
;该函数返回指定窗口的边框矩形的尺寸,该尺寸以相对于屏幕坐标左上角的屏幕坐标给出
add Rct.left, 2
add Rct.top, 2
sub Rct.right, 2
sub Rct.bottom, 2
invoke Frame3D,hDC,btn_hi,btn_lo,
Rct.left,Rct.top,
Rct.right,Rct.bottom,2
add Rct.left, 1
add Rct.top, 1
sub Rct.right, 1
sub Rct.bottom, 1
invoke Frame3D,hDC,btn_lo,btn_hi,
Rct.left,Rct.top,
Rct.right,Rct.bottom,1
add Rct.left, 2
add Rct.top, 2
sub Rct.right, 2
sub Rct.bottom, 2
invoke Frame3D,hDC,btn_hi,btn_lo,
Rct.left,Rct.top,
Rct.right,Rct.bottom,2
ret
NcPaint_Proc endp
; #########################################################################
Paint_Proc proc hWin:DWORD, hDC:DWORD
invoke FrameCtrl,hEdit1,2,1,1
invoke FrameCtrl,hEdit2,2,1,1
invoke FrameCtrl,hButn1,3,1,0
invoke FrameWindow,hWin,0,1,0
invoke FrameWindow,hWin,4,1,1
return 0
Paint_Proc endp
; ########################################################################
end start