📄 shuzishizhong.asm.txt
字号:
jmp got
t3: cmp figure,3
jne t4
Num3 left,attr
jmp got
t4: cmp figure,4
jne t5
Num4 left,attr
jmp got
t5: cmp figure,5
jne t6
Num5 left,attr
jmp got
t6: cmp figure,6
jne t7
Num6 left,attr
jmp got
t7: cmp figure,7
jne t8
Num7 left,attr
jmp got
t8: cmp figure,8
jne t9
Num8 left,attr
jmp got
t9: cmp figure,9
jne t0
Num9 left,attr
jmp got
t0: Num0 left,attr
got:
endm
ClearFigure macro ;清除原有的数字
DrawWindow 2eh,6,39,14,74;绘出数字钟的表盘
SetPos 8,50
OutPutChar 3h,1eh,1
SetPos 12,50
OutPutChar 3h,1eh,1
SetPos 8,62
OutPutChar 3h,1eh,1
SetPos 12,62
OutPutChar 3h,1eh,1
endm
ShowTime macro attr ;显示当前的时间,默认为数字式的时钟
local then
GetSysTime curr_h1,curr_h2,curr_m1,curr_m2,curr_s1,curr_s2
IsTimeChanged
cmp istchanged,1
jne then
ClearFigure
EVAFigure curr_h1,40,attr
EVAFigure curr_h2,45,attr
EVAFigure curr_m1,52,attr
EVAFigure curr_m2,57,attr
EVAFigure curr_s1,64,attr
EVAFigure curr_s2,69,attr
then:
endm
IsTimeAlert macro ;判断是否是整点
local notgot,got
cmp curr_s1,0
jne notgot
cmp curr_s2,0
jne notgot
cmp curr_m1,0
jne notgot
cmp curr_m2,0
jne notgot
mov isring,1
jmp got
notgot: mov isring,0
got:
endm
IsKeyDown ` macro a,b ;判断是否有健按下
local ConfirmQuit
mov ah,0bh
int 21h
je b
mov ah,6;键盘输入无回显
mov dl,0ffh
int 21h
cmp al,'q'
jne ConfirmQuit
je a
ConfirmQuit:
cmp al,'Q'
jne b
je a
endm
; 应用Win32下的汇编语言编写的简易时钟
; 周永豪 华中科技大学计算机系0203班
; 学号: 012002013526
; Clock.rc
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <resource.h>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define ICO_MAIN 0x1000
#define IDA_MAIN 0x2000
#define IDM_MAIN 0x2000
#define IDM_NEW 0x4101
#define IDM_CLOSE 0x4102
#define IDM_EXIT 0x4103
#define IDM_MODED 0x4211
#define IDM_MODER 0x4212
#define IDM_ABOUT 0x4401
#define IDM_HELP 0x4402
#define IDM_MENUHELP 0x4400
#define IDW_SOUND 8000
#define IDW_START 8001
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN ICON "Main.ico"
IDW_SOUND wave "Sound.wav"
IDW_START WAVE "Start.wav"
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
IDM_MAIN MENU DISCARDABLE
BEGIN
POPUP "文件(&F)"
BEGIN
MENUITEM "新建时钟(&N)...\tCtrl+N",IDM_NEW
MENUITEM "关闭时钟(&C)...\tCtrl+C",IDM_CLOSE,GRAYED
MENUITEM separator
MENUITEM "退出(&E)...\tCtrl+E",IDM_EXIT
END
POPUP "设置(&S)"
BEGIN
POPUP "显示模式(&M)"
BEGIN
MENUITEM "数字模式(&D)...\tCtrl+ALT+D",IDM_MODED,GRAYED
MENUITEM "钟面模式(&R)...\tCtrl+ALT+R",IDM_MODER,GRAYED
END
END
POPUP "帮助(H)"
BEGIN
MENUITEM "关于(&A)...\tCtrl+A",IDM_ABOUT
end
end
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
IDA_MAIN accelerators
BEGIN
VK_F1, IDM_HELP, VIRTKEY
"F", IDM_MAIN, ALT
"^N", IDM_NEW
"^C", IDM_NEW
"^E", IDM_EXIT
"S", IDM_MAIN, ALT
"^D", IDM_MODED, ALT
"^R", IDM_MODER, ALT
"^A", IDM_ABOUT
END
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
stringtable discardable
BEGIN
IDM_MENUHELP "包含对时钟的基本操作"
IDM_MENUHELP+1 "设置时钟属性"
IDM_MENUHELP+2 "帮助和关于..."
IDM_NEW "新建一个时钟"
IDM_CLOSE "关闭时钟"
IDM_EXIT "退出程序"
IDM_MODED "设置为数字显示方式"
IDM_MODER "设置为表面显示方式"
END
;***************************************************************************
; Clock.asm
.386
.model flat, stdcall
option casemap :none
include windows.inc ; Include 文件定义
include user32.inc
include kernel32.inc
include comctl32.inc
include comdlg32.inc
include shell32.inc
include advapi32.inc
include gdi32.inc
include winmm.inc
includelib user32.lib
includelib kernel32.lib
includelib comctl32.lib
includelib comdlg32.lib
includelib shell32.lib
includelib advapi32.lib
includelib gdi32.lib
includelib winmm.lib
ICO_MAIN equ 1000h ; Equ 等值定义
IDA_MAIN equ 2000h
IDM_MAIN equ 2000h
IDM_NEW equ 4101h
IDM_CLOSE equ 4102h
IDM_EXIT equ 4103h
IDM_MODED equ 4211h
IDM_MODER equ 4212h
IDM_ABOUT equ 4401h
IDM_MENUHELP equ 4400h
ID_STATUSBAR equ 1
IDW_SOUND equ 8000 ;sound
IDW_START equ 8001 ;sound
ID_TIMER equ 1
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
.data?
hInstance dd ?
hWinMain dd ?
hMenu dd ?
hSubMenu dd ?
hDC dd ? ;只设置一个DC以便更新和传参
hWinStatus dd ?
dwCenterX dd ? ;圆心X
dwCenterY dd ? ;圆心Y
dwRadius dd ? ;半径
.data
bIsClockVis dw 0;
dwHeightTemp dd 20 ;状态栏的高度
bAppMode dw 0 ;默认为钟表方式
wCurrHour dw -1
wCurrMinute dw -1
wCurrSecond dw -1
.const
szClassName db 'Clock',0
szNewCursor db 'Radar.ani',0
dwStatusWidth dd 100,130,372,-1
dwMenuHelp dd 0,IDM_MENUHELP,0,0
szAppStatus db '程序已经启动',0
szAppModeR db '当前为钟表显示模式',0
szAppModeD db '当前为钟数字钟显示模式',0
wOpand1 dw 10
wOpand2 dw 4
wOpand3 dw 2
szCurrTime db '当前的时间是:',0
szSoundFile db 'Sound.wav',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
.code
szText MACRO Name, Text:VARARG ;Macro定义
LOCAL then
jmp then
Name db Text,0
then:
ENDM
_SetNewFlag proc NewFlag:word ;设置是否为新建的时钟,初值为False
pushad
mov ax,NewFlag
mov bIsClockVis,ax
popad
ret
_SetNewFlag endp
_IsAddPopMenu proc bAddMenu:word ;是否允许添加右键弹出菜单
LOCAL @stPos:POINT
pushad
mov ax,bAddMenu
cmp ax,1
jne @f
invoke GetSubMenu,hMenu,1
mov hSubMenu, eax
jmp @QuitAddMenu
@@:
invoke DeleteMenu,hSubMenu,1,MF_BYPOSITION
mov hSubMenu, eax
@QuitAddMenu: popad
ret
_IsAddPopMenu endp
_UpdateMenu proc bVisible:word ;在选中“新建”菜单后激活功能部分的灰色菜单
pushad
mov ax,bVisible
cmp ax,0
je @f
invoke EnableMenuItem,hMenu,IDM_MODED,MF_ENABLED
invoke EnableMenuItem,hMenu,IDM_MODER,MF_ENABLED
invoke EnableMenuItem,hMenu,IDM_CLOSE,MF_ENABLED
jmp @exit
@@:
invoke EnableMenuItem,hMenu,IDM_MODED,MF_GRAYED
invoke EnableMenuItem,hMenu,IDM_MODER,MF_GRAYED
invoke EnableMenuItem,hMenu,IDM_CLOSE,MF_GRAYED
@exit: popad
ret
_UpdateMenu endp
_Quit proc
invoke DestroyWindow,hWinMain ;退出时触发_Quit
invoke PostQuitMessage,NULL
ret
_Quit endp
_AutoSizeStaBar proc ;通过消息自动设置新的状态栏的大小
LOCAL @stRect:RECT
LOCAL @stRectTemp:RECT
LOCAL @dwWidthTemp
pushad
invoke GetClientRect,hWinMain,addr @stRect
mov eax,@stRect.left
mov ebx,@stRect.right
sub ebx,eax
mov @dwWidthTemp,ebx
mov eax,@stRect.bottom
mov eax,@stRect.top
sub ebx,eax
invoke MoveWindow,hWinStatus,0,0,0,0,TRUE;计算新的状态栏的属性
popad
ret
_AutoSizeStaBar endp
_CalcClockParam proc ;计算时钟的位置、大小等参数
local @stRect:RECT
invoke GetClientRect,hWinMain,addr @stRect
mov eax,@stRect.right
sub eax,@stRect.left ;eax = 宽度
mov ecx,@stRect.bottom
sub ecx,@stRect.top ;ecx = 高度
sub ecx,dwHeightTemp
.if ecx > eax ;计算钟的圆心位置和半径
mov edx,eax ;高度 > 宽度
sub ecx,eax
shr ecx,1
mov dwCenterX,0
mov dwCenterY,ecx
.else
mov edx,ecx
sub eax,ecx
shr eax,1
mov dwCenterX,eax
mov dwCenterY,0
.endif
shr edx,1
mov dwRadius,edx
add dwCenterX,edx
add dwCenterY,edx
ret
_CalcClockParam endp
_dwPara180 dw 180
_CalcX proc _dwDegree,_dwRadius ;计算时钟圆周上某个角度对应的 X 坐标
local @dwReturn
fild dwCenterX ;dwCenterX = 圆心X + Sin(角度) * 半径
fild _dwDegree
fldpi
fmul
fild _dwPara180
fdivp st(1),st
fsin
fild _dwRadius
fmul
fadd
fistp @dwReturn
mov eax,@dwReturn
ret
_CalcX endp
_CalcY proc _dwDegree,_dwRadius ;计算时钟圆周上某个角度对应的 Y 坐标
local @dwReturn
fild dwCenterY ;dwCenterY = 圆心Y - Cos(角度) * 半径
fild _dwDegree
fldpi
fmul
fild _dwPara180
fdivp st(1),st
fcos
fild _dwRadius
fmul
fsubp st(1),st
fistp @dwReturn
mov eax,@dwReturn
ret
_CalcY endp
_DrawDot proc _hDC,_dwDegreeInc,_dwRadius;画 _dwRadius 为半径的小圆点
local @dwNowDegree,@dwR
local @dwX,@dwY
mov @dwNowDegree,0
mov eax,dwRadius
sub eax,10
mov @dwR,eax
.while @dwNowDegree <= 360
finit
invoke _CalcX,@dwNowDegree,@dwR ; 计算小圆点的圆心坐标
mov @dwX,eax
invoke _CalcY,@dwNowDegree,@dwR
mov @dwY,eax
mov eax,@dwX ;画点
mov ebx,eax
mov ecx,@dwY
mov edx,ecx
sub eax,_dwRadius
add ebx,_dwRadius
sub ecx,_dwRadius
add edx,_dwRadius
invoke Ellipse,_hDC,eax,ecx,ebx,edx
mov eax,_dwDegreeInc
add @dwNowDegree,eax
.endw
ret
_DrawDot endp
_DrawLine proc _hDC,_dwDegree,_dwRadiusAdjust; 画 _dwDegree 角度的线条作为指针
local @dwX1,@dwY1,@dwX2,@dwY2
local @dwR
LOCAL @szBuff[255]
mov eax,dwRadius
sub eax,_dwRadiusAdjust
mov @dwR,eax
invoke _CalcX,_dwDegree,@dwR ;计算线条两端的坐标
mov @dwX1,eax
invoke _CalcY,_dwDegree,@dwR
mov @dwY1,eax
add _dwDegree,180
invoke _CalcX,_dwDegree,10
mov @dwX2,eax
invoke _CalcY,_dwDegree,10
mov @dwY2,eax
invoke MoveToEx,_hDC,@dwX1,@dwY1,NULL
invoke LineTo,_hDC,@dwX2,@dwY2
ret
_DrawLine endp
_SetAppRMode proc _hWnd,_hDC ;时钟显示时间方式为钟面式
LOCAL @stTime:SYSTEMTIME
LOCAL @dwX1,@dwX2,@dwY1,@dwY2
pushad
mov ax, bIsClockVis
cmp ax, 1
jne @f
invoke GetLocalTime,addr @stTime
mov ax,@stTime.wHour
mov wCurrHour,ax
mov ax,@stTime.wMinute
mov wCurrMinute,ax
mov ax,@stTime.wSecond
mov wCurrSecond,ax
invoke _CalcClockParam
mov eax,dwCenterX ; 画时钟圆周上的点
push eax
sub eax,dwRadius
mov @dwX1,eax
pop eax
add eax,dwRadius
mov @dwX2,eax
mov eax,dwCenterY
push eax
sub eax,dwRadius
mov @dwY1,eax
pop eax
add eax,dwRadius
mov @dwY2,eax
invoke CreatePen,PS_SOLID,2,00F000f0h
push eax
invoke SelectObject,_hDC,eax
invoke CreateHatchBrush,HS_DIAGCROSS,0003ff79h
push eax
invoke SelectObject,_hDC,eax
invoke Ellipse,_hDC,@dwX1,@dwY1,@dwX2,@dwY2
pop eax
pop eax
invoke DeleteObject,eax
invoke CreatePen,PS_SOLID,1,00FF0521h
invoke SelectObject,_hDC,eax
invoke _DrawDot,_hDC,360/60,1 ;画60个小圆点
invoke CreatePen,PS_SOLID,1,00061ffah
push eax
invoke SelectObject,_hDC,eax
invoke _DrawDot,_hDC,360/12,3 ;画12个大圆点
pop eax
invoke DeleteObject,eax
invoke CreatePen,PS_SOLID,1,0000ffh ; 画时钟指针
push eax
invoke SelectObject,_hDC,eax
movzx eax,@stTime.wSecond
mov ecx,360/60
mul ecx ;秒针度数 = 秒 * 360/60
invoke _DrawLine,_hDC,eax,10
pop eax
invoke DeleteObject,eax
invoke CreatePen,PS_SOLID,2,00ffff00h
push eax
invoke SelectObject,_hDC,eax
invoke DeleteObject,eax
movzx eax,@stTime.wMinute
mov ecx,360/60
mul ecx ;分针度数 = 分 * 360/60
invoke _DrawLine,_hDC,eax,20
pop eax
invoke DeleteObject,eax
invoke CreatePen,PS_SOLID,5,00ff1847h
push eax
invoke SelectObject,_hDC,eax
movzx eax,@stTime.wHour
.if eax >= 12
sub eax,12
.endif
mov ecx,360/12
mul ecx
movzx ecx,@stTime.wMinute
shr ecx,1
add eax,ecx
invoke _DrawLine,_hDC,eax,40
pop eax
invoke DeleteObject,eax
@@: popad
ret
_SetAppRMode endp
_Num0 proc _hDC,StartX,StartY ;在指定位置显示数字0
LOCAL @stLastPoint:POINT
LOCAL @dwx0,@dwx1,@dwy0,@dwy1,@dwy2,@dwy3
pushad
mov eax,0
mov @stLastPoint.x,eax
mov @stLastPoint.y,eax
mov eax,StartX
add eax,25
mov @dwx0,eax
add eax,50
mov @dwx1,eax
mov eax,StartY
add eax,25
mov @dwy0,eax
add eax,70
mov @dwy1,eax
add eax,10
mov @dwy2,eax
add eax,70
mov @dwy3,eax
invoke MoveToEx,_hDC,@dwx0,@dwy0,addr @stLastPoint
invoke LineTo,_hDC,@dwx1,@dwy0
invoke LineTo,_hDC,@dwx1,@dwy1
invoke MoveToEx,_hDC,@dwx1,@dwy2,addr @stLastPoint
INVOKE LineTo,_hDC,@dwx1,@dwy3
invoke LineTo,_hDC,@dwx0,@dwy3
invoke LineTo,_hDC,@dwx0,@dwy2
invoke MoveToEx,_hDC,@dwx0,@dwy1,addr @stLastPoint
invoke LineTo,_hDC,@dwx0,@dwy0
popad
ret
_Num0 endp
_Num1 proc _hDC,StartX,StartY ;在指定位置显示数字1
LOCAL @stLastPoint:POINT
LOCAL @dwx0,@dwy0,@dwy1,@dwy2,@dwy3
pushad
mov eax,0
mov @stLastPoint.x,eax
mov @stLastPoint.y,eax
mov eax,StartX
add eax,75
mov @dwx0,eax
mov eax,StartY
add eax,25
mov @dwy0,eax
add eax,70
mov @dwy1,eax
add eax,10
mov @dwy2,eax
add eax,70
mov @dwy3,eax
invoke MoveToEx,_hDC,@dwx0,@dwy0,addr @stLastPoint
invoke LineTo,_hDC,@dwx0,@dwy1
invoke MoveToEx,_hDC,@dwx0,@dwy2,addr @stLastPoint
INVOKE LineTo,_hDC,@dwx0,@dwy3
popad
ret
_Num1 endp
_Num2 proc _hDC,StartX,StartY ;在指定位置显示数字2
LOCAL @stLastPoint:POINT
LOCAL @dwx0,@dwx1,@dwy0,@dwy1,@dwy2,@dwy3
pushad
mov eax,0
mov @stLastPoint.x,eax
mov @stLastPoint.y,eax
mov eax,StartX
add eax,25
mov @dwx0,eax
add eax,50
mov @dwx1,eax
mov eax,StartY
add eax,25
mov @dwy0,eax
add eax,70
mov @dwy1,eax
add eax,10
mov @dwy2,eax
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -