📄 winclock.asm
字号:
.ELSE
mov ax, rect.bottom ; Full or Half Height
mov TextRect.bottom, ax
.IF EnableDate && !Iconized
shr ax, 1 ; height/2
.ENDIF
.ENDIF
;---- Test if desired height is allowed or not
;---- If height>MAX, then height=MAX_HEIGHT. Adjust TextRect.top by
;---- substracting from the bottom the font height (or twice that if Date),
;---- dividing by two, and adding to the TextRect.top.
.IF (ax > MAX_HEIGHT)
mov logfont.lfHeight, MAX_HEIGHT
mov ax, TextRect.bottom
mov bx, MAX_HEIGHT
.IF EnableDate && !Iconized
shl bx, 1
.ENDIF
sub ax, bx
shr ax, 1
mov TextRect.top, ax
.ELSE
mov logfont.lfHeight, ax
mov TextRect.top, 0
.ENDIF
mov TextRect.left, 0 ; Left is Zero
mov ax, rect.right ; Same Rect length
mov TextRect.right, ax
;---- Set font width according to Iconized or not.
.IF Iconized
xor dx, dx
mov bx, ICON_LEN
div bx
.ELSE
shr ax, 4 ; length/16
.ENDIF
mov logfont.lfWidth, ax
ret
Resize ENDP
;----------------------------------------------------------------------------;
; PaintAlarm ;
;----------------------------------------------------------------------------;
; ;
; Painting the alarmtime. Get the hours and minutes from Alarmtime, get AM ;
; or PM by going into szAMPM either at 0 or 3, to get the appropiate string. ;
; Then we simply draw the text into the TextRect calculated by Resize, with ;
; the font that we get from using the logfont structure. ;
; ;
;----------------------------------------------------------------------------;
PaintAlarm PROC USES si di, hWnd:HWND, hDC:HDC
; hWnd is the handle of the window that received WinPaint
; hDC is the Device context of the window
LOCAL nLength:SWORD, hFont:HFONT,
hour:WORD, minutes:WORD, seconds:WORD
; Locals: nLength is the current length of the buffer
; hFont is a handle to a font.
;---- Get Time from AlarmTime
xor dx, dx
mov ax, AlarmTime
mov bx, 60t
div bx ; ax holds the hours
mov bx, dx ; bx holds the minutes
mov si, ax ; si holds the hours
xor dx, dx
mov di, 12
div di ; will have ax=0 or 1 (am/pm)
xor dx, dx
mov cx, AMPM ; AMPM = 3: 'am'+\0
mul cx
mov di, ax
add di,offset szAMPM ; get into di the correct
; memory address
mov ax, si ; ax == tm_hour
xor dx, dx
mov cx, 12
div cx
.IF (dx == 0) ; so we don't have 00:45
mov cx, 12
.ELSE
mov cx, dx
.ENDIF
;---- on using wsprintf below: since the wsprintf prototype has VARARG,
;---- we can't tell the assemble the distance of those arguments, so we
;---- have to do a specific far pointer to the data. wsprintf expects all
;---- pointers to be far pointers, no exceptions.
INVOKE wsprintf, ADDR cBuffer, ADDR AlarmFmt,
cx, bx, ds::di
mov nLength,ax
;---- Set Font & Draw Text
INVOKE CreateFontIndirect, ADDR logfont
mov hFont, ax
INVOKE SelectObject, hDC, ax
mov hFont, ax
INVOKE DrawText, hDC, ADDR cBuffer, nLength, ADDR TextRect,
(DT_CENTER)
INVOKE SelectObject, hDC, hFont
INVOKE DeleteObject, ax
ret
PaintAlarm ENDP
;----------------------------------------------------------------------------;
; PaintTime ;
;----------------------------------------------------------------------------;
; ;
; Painting the time. We get a index to szMonths by multiplying the [0-11] ;
; month by 4 ('jan'+\0). We print everything to a string and store the length;
; as an index. We do this only if Date's enabled. ;
; For the time, we do the same AM/PM thing as in PaintAlarm, and print it to ;
; the same string after the Date's carriage return (included in DateFmt. ;
; Then we simply draw the text into the TextRect calculated by Resize, with ;
; the font that we get from using the logfont structure. ;
; If we're minimized, we also draw a rectangle around the time. We get a pen ;
; of width 2, black, and a hollow (transparent) brush. We save the pen ID in ;
; the stack so that we can deselect it later. ;
; Then, we check to see if we have to spring the alarm. If TestAlarm is not ;
; enabled, check the time and re-enable TestAlarm if it's NOT the AlarmTime ;
; (i.e. so that after we ring it it will ring in 24 hours). If TestAlarm is ;
; set, check if EnableAlarm is set. If it is, multiply the hours by 60, add ;
; the minutes, compare with AlarmTime. Notice that the 'mov bx, datetime' is ;
; necessary because the wsprintf and DrawText will trash ax, bx, cx. If it's ;
; alarm time, disable TestAlarm, invert the rectangle, sound a beep, revert ;
; the rect, and do a message box. This way, TestAlarm enables us to always ;
; have at least one check of the alarm time. ;
; ;
;----------------------------------------------------------------------------;
PaintTime PROC USES si di, hWnd:HWND, hDC:HDC
; hWnd is the handle of the window that received WinPaint
; hDC is the Device context of the window
LOCAL nLength:SWORD, hFont:HFONT, pen:WORD,
hour:WORD, minutes:WORD, seconds:WORD
; Locals: nLength is the current length of the buffer
; hFont is a handle to a font.
;---- Set Date Variables
.IF (EnableDate && !Iconized)
mov ah, 2Ah ; function: Get Date
INVOKE DOS3Call ; do the interrupt
; dh will have months
; dl will have days
; cx will have years
mov al, dh ; months (1-12)
xor ah, ah
xor dh, dh ; day-of-month (1-31)
mov si, ax ; (Month-1) * 4
dec si
shl si, 2
add si, offset szMonths
;---- For note on wsprintf below, see PaintAlarm
INVOKE wsprintf, ADDR cBuffer, ADDR DateFmt,
ds::si, dx, cx
mov nLength, ax
.ELSE
mov nLength, 0
.ENDIF ; of EnableDate
;---- Get Time from CPU clock
xor dx, dx
mov ah, 2Ch ; function: Get Time
INVOKE DOS3Call ; do the interrupt
; ch will have hours
; cl will have minutes
; dh will have seconds
mov al, ch ; hours (0-23)
xor ah, ah
mov hour, ax
mov al, cl ; minutes (0-59)
mov minutes, ax
mov al, dh ; seconds (0-59)
mov seconds, ax
mov ax, hour ; divide hour/12, multiply
xor dx, dx ; by 3 to get offset into
mov bx, 12 ; szAMPM, then add the
div bx ; szAMPM offset
mov si, dx ; dx would have hours
xor dx, dx
mov cx, AMPM
mul cx
mov bx, ax
add bx, offset szAMPM ; get into di the correct
; memory address
.IF (si == 0) ; get hour into cx
mov cx, 12 ; or 12 if hour=0
.ELSE
mov cx, si
.ENDIF
mov si, nLength
.IF !Iconized
INVOKE wsprintf, ADDR cBuffer[si], ADDR TimeFmt,
cx, minutes, seconds, ds::bx
.ELSE
INVOKE wsprintf, ADDR cBuffer[si], ADDR IconFmt,
cx, minutes
.ENDIF
add nLength, ax
;---- Set Font, Draw the Text
INVOKE CreateFontIndirect, ADDR logfont
mov hFont, ax
INVOKE SelectObject, hDC, ax
mov hFont, ax
INVOKE DrawText, hDC, ADDR cBuffer, nLength, ADDR TextRect,
DT_NOCLIP OR DT_CENTER
INVOKE SelectObject, hDC, hFont
INVOKE DeleteObject, ax
;---- If Iconized, draw rectangle with transparent background
.IF Iconized
INVOKE GetStockObject, HOLLOW_BRUSH
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -