📄 见招拆招《windows程序设计》(七) .txt
字号:
mov ebx,bigword
shr ebx,16;; Shift 16 for high word to set to high word
ENDM
RGB MACRO red, green, blue ;; Get composite number from red green and blue bytes
mov al,blue ;; ,,,blue
shl eax,8 ;; ,,blue,
add al,green;; ,,blue,green
shl eax,8 ;; ,blue,green,
add al,red ;; ,blue,green,red
and eax,0FFFFFFh;; Mask out top byte to complete COLORREF dword
ENDM
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
ID_TIMER equ 1
.DATA
szAppName db "Clock",0
theta real4 ? ; Required rotation in degrees
math_X_Coord real4 ? ; Math space coords
math_Y_Coord real4 ? ;
New_X1 real4 ?
New_Y1 real4 ?
pt POINT {0, -150},{100,0},{0,600},{-100,0},{0,-150}, \
{0, -200},{ 50,0},{0,800},{ -50,0},{0,-200}, \
{0, 0},{ 0,0},{0, 0},{ 0,0},{0, 800}
.DATA?
hInstance dd ?
stPrevious SYSTEMTIME <> ; Previous time data
stCurrent SYSTEMTIME <> ; Current
cxClient dd ?
cyClient dd ?
fChange BOOL ?
.CODE
START: ;从这里开始执行
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke WinMain,hInstance,NULL,NULL,SW_SHOWDEFAULT
invoke ExitProcess,0
WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,iCmdShow:DWORD
LOCAL wndclass :WNDCLASSEX
LOCAL msg :MSG
LOCAL hWnd :HWND
LOCAL cxWindow,cyWindow:DWORD
mov wndclass.cbSize,sizeof WNDCLASSEX
mov wndclass.style,CS_HREDRAW or CS_VREDRAW
mov wndclass.lpfnWndProc,offset WndProc
mov wndclass.cbClsExtra,0
mov wndclass.cbWndExtra,0
push hInst
pop wndclass.hInstance
invoke LoadIcon,NULL,IDI_APPLICATION
mov wndclass.hIcon,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wndclass.hCursor,eax
invoke GetStockObject,WHITE_BRUSH
mov wndclass.hbrBackground,EAX
mov wndclass.lpszMenuName,NULL
mov wndclass.lpszClassName,offset szAppName
mov wndclass.hIconSm,0
invoke RegisterClassEx, ADDR wndclass
.if (EAX==0)
invoke MessageBox,NULL,CTXT("This program requires Windows NT!"),addr szAppName,MB_ICONERROR
ret
.endif
invoke CreateWindowEx,
NULL,
ADDR szAppName, ;window class name
CTXT("Analog Clock"), ;window caption
WS_OVERLAPPED or WS_CAPTION or WS_SYSMENU or WS_BORDER, ;window style
CW_USEDEFAULT, ;initial x position
CW_USEDEFAULT, ;initial y position
CW_USEDEFAULT, ;initial x size
CW_USEDEFAULT,;initial y size
NULL,;parent window handle
NULL,;window menu handle
hInstance,;program instance handle
NULL;creation parameters
mov hWnd,eax
invoke ShowWindow,hWnd,iCmdShow
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:
mov eax,msg.wParam
ret
WinMain endp
SetIsotropic proc hdc:HDC,cxC:DWORD,cyC:DWORD
invoke SetMapMode, hdc, MM_ISOTROPIC ; Select isotropic mapping
; Set window extents to 1000 and the viewport extents to 1/2 width of client area,
; and the negative of 1/2 height of client area
invoke SetWindowExtEx, hdc, 1000, 1000, NULL
push NULL
mov eax,cyC
shr eax,1
neg eax ; Get -cyClient/2
push eax
mov eax,cxC
shr eax,1
push eax
push hdc
call SetViewportExtEx
push NULL
mov eax,cyC
shr eax,1
push eax
mov eax,cxC
shr eax,1
push eax
push hdc
call SetViewportOrgEx
ret
SetIsotropic endp
DrawClock proc hdc:HDC
LOCAL iAngle:DWORD, pt4[3]:POINT
mov iAngle,0
.WHILE iAngle < 360
mov pt4[0].x,0
mov pt4[0].y,900
fild pt4[0*8].x
fstp math_X_Coord
fild pt4[0*8].y
fstp math_Y_Coord
fild iAngle
fstp theta
mov esi,offset theta ; Point at parameter block
call rotate ; Rotate the 5-minute or minute marks
fld New_X1 ; Get new X coord
fistp pt4[0*8].x; Store in structure
fld New_Y1 ; Ditto for Y coord
fistp pt4[0*8].y;
mov eax,iAngle
mov ecx,5
mov edx,0
div ecx ; Get the remainder in dx
.IF edx
mov pt4[2*8].x,33; if edx is true its a minute mark (small circle)
mov pt4[2*8].y,33
.ELSEIF
mov pt4[2*8].x,100; if its false its a 5-minute mark (larger circle)
mov pt4[2*8].y,100
.ENDIF
mov eax,pt4[2*8].x
shr eax,1 ; (pt[2].x)/2
sub pt4[0].x,eax
mov eax,pt4[2*8].y
shr eax,1 ; (pt[2].y)/2
sub pt4[0].y,eax
mov eax,pt4[0].x
add eax,pt4[2*8].x
mov pt4[1*8].x,eax
mov eax,pt4[0].y
add eax,pt4[2*8].y
mov pt4[1*8].y,eax
invoke GetStockObject, BLACK_BRUSH
invoke SelectObject, hdc, eax
invoke Ellipse, hdc, pt4[0].x, pt4[0].y, pt4[1*8].x, pt4[1*8].y
add iAngle,6
.ENDW
ret
DrawClock endp
DrawHands proc hdc:HDC, pst:DWORD, Change:BOOL ; pst points @ current or previous TIME data
LOCAL iAngle[3]:DWORD, ptTemp[15]:POINT ; Provide space for copy of polyline points
; This routine is entered twice, once to erase the old hand position and then
; a second time it uses the new time data to update the hand positions.
; Convert time data (hour, min and sec) into angles for the three hands
mov ebx,pst ; Get address of current or previous SYSTEMTIME
mov ax,[ebx+8]; Get hours
mov edx,0
mov cx,30 ; Scaling factor for 360 degrees
mul cx
mov cx,360
div cx ; mod 360 divide; get hours-remainder in edx
mov cx,[ebx+10]; Get minute value
shr cx,1 ;
add dx,cx ; Add on angle for fractional part of the hour
mov iAngle[0],edx; Now have hour-hand angle
mov ax,[ebx+10]; Get minutes again
mov edx,0
mov cx,6 ; Scale factor for minute-hand angle
mul cx
mov iAngle[4],eax; Got minute-hand angle
mov ax,[ebx+12]; Get seconds
mov edx,0
mov cx,6 ; Scale factor for second-hand angle
mul cx
mov iAngle[8],eax; Got second-hand angle
; Copy polyline data to temp storage
mov esi,offset pt; es and ds point to same segment
lea edi,ptTemp
mov ecx,sizeof pt
cld
rep movsb ; Copy polyline points to ptTemp
.IF Change
mov esi,0 ; If hour or minute hands have changed position
mov ebx,0
.ELSE
mov esi,2*4 ; If second hand only has changed
mov ebx,2*40
.ENDIF
.WHILE ebx < 3*40
mov edi,0 ; Index to point
.WHILE edi < 40; Loop for all points in the structure
push edi
add edi,ebx ; Add offset for the appropriate hand
fild iAngle[esi]; Load data into the rotate parameter block
fstp theta ;
fild ptTemp[edi].x;
fstp math_X_Coord;
fild ptTemp[edi].y;
fstp math_Y_Coord;
push esi
mov esi,offset theta ; Point at parameter block
call rotate ; Rotate the point
pop esi
fld New_X1 ; Get new X coord
fistp ptTemp[edi].x; Store in hands structure
fld New_Y1 ; Ditto for Y coord
fistp ptTemp[edi].y;
pop edi
add edi,8
.ENDW
invoke Polyline, hdc,ADDR ptTemp[ebx],5 ; Draw the hand
add ebx,40; Inc to next hand
add esi,4; Inc index for angle of next hand
.ENDW
ret
DrawHands endp
WndProc proc uses ebx esi edi ,hwnd:DWORD,message:DWORD,wParam :DWORD,lParam :DWORD
LOCAL hdc:HDC
LOCAL ps :PAINTSTRUCT
.if message == WM_CREATE
finit
invoke SetTimer,hwnd,ID_TIMER,500,NULL
invoke GetLocalTime, ADDR stCurrent
;invoke GetLocalTime, ADDR stPrevious;stPrevious = st ;
xor eax,eax
ret
.elseif message == WM_SIZE
LOWORD lParam; Get low word from lParam in eax
mov cxClient,eax
HIWORD lParam; Get high " " " ebx
mov cyClient,ebx
xor eax,eax
ret
.elseif message == WM_TIMER
invoke GetLocalTime, ADDR stCurrent
mov cx,stCurrent.wHour
mov dx,stCurrent.wMinute
.IF cx != stPrevious.wHour
mov fChange, TRUE
.ELSEIF dx != stPrevious.wMinute
mov fChange, TRUE
.ELSE
mov fChange, FALSE
.ENDIF
invoke GetDC, hwnd
mov hdc,eax
invoke SetIsotropic, hdc,cxClient,cyClient
invoke GetStockObject, WHITE_PEN; Erase hands
invoke SelectObject, hdc, eax
invoke DrawHands, hdc, ADDR stPrevious, fChange
invoke GetStockObject, BLACK_PEN; Draw hands at new position
invoke SelectObject, hdc, eax
invoke DrawHands, hdc, ADDR stCurrent, TRUE
invoke ReleaseDC, hwnd, hdc
mov ax,stCurrent.wHour; Save the current time
mov stPrevious.wHour,ax;
mov ax,stCurrent.wMinute;
mov stPrevious.wMinute,ax;
mov ax,stCurrent.wSecond;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -