📄 clock.asm
字号:
invoke RegisterClassEx,offset stWcMain
;***************** 建立输出窗口 *****************************************
; 属性:没有标题栏,不显示在任务栏
;********************************************************************
invoke CreateWindowEx,WS_EX_TOOLWINDOW,\
offset szClassName,NULL,\
WS_POPUP or WS_SYSMENU,\
0,0,1,1,\
NULL,NULL,hInstance,NULL
test dwFlag,F_MINIMIZE
.if ZERO?
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
.else
invoke ShowWindow,hWinMain,SW_MINIMIZE
.endif
;********************************************************************
.while TRUE
invoke GetMessage,offset stMsg,NULL,0,0
.break .if eax == 0
invoke TranslateMessage,offset stMsg
invoke DispatchMessage,offset stMsg
.endw
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 子程序开始 !!!
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_AlarmSetupCommand proto :DWORD,:DWORD,:DWORD
_LookSetupCommand proto :DWORD,:DWORD,:DWORD
HyperLinkProc proto :DWORD,:DWORD,:DWORD,:DWORD
;********************************************************************
; 对话框窗口主程序
;********************************************************************
DialogMainProc proc uses ebx edi esi, \
hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
local @stWindow:RECT
local @dwWidth:DWORD,@dwHeight:DWORD
local @hWinTemp:DWORD
local @stFont:LOGFONT,@hFont:DWORD
mov eax,uMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
mov eax,hWnd
mov hWinDialog,eax
invoke _CenterWindow,hWnd
mov eax,lParam
mov idActiveDialog,eax
.if eax == DLG_SETUP
call _InitSetupDialog
.elseif eax == DLG_LOOK
call _InitLookDialog
.elseif eax == DLG_ABOUT
invoke GetDlgItem,hWnd,ID_HOMEPAGE
mov @hWinTemp,eax
invoke SetWindowLong,@hWinTemp,GWL_WNDPROC,addr HyperLinkProc
invoke SetWindowLong,@hWinTemp,GWL_USERDATA,eax
invoke GetDlgItem,hWnd,ID_EMAIL
mov @hWinTemp,eax
invoke SetWindowLong,@hWinTemp,GWL_WNDPROC,addr HyperLinkProc
invoke SetWindowLong,@hWinTemp,GWL_USERDATA,eax
.elseif eax == DLG_SHUTDOWN
mov dwShutDownCount,10
invoke SetTimer,hWnd,2,1000,NULL
.endif
.elseif eax == WM_CTLCOLORSTATIC
invoke GetDlgCtrlID,lParam
.if eax == ID_HOMEPAGE || eax == ID_EMAIL
invoke SendMessage,lParam,WM_GETFONT,0,0
mov @hFont,eax
invoke GetObject,@hFont,sizeof LOGFONT,addr @stFont
mov @stFont.lfUnderline,TRUE
invoke CreateFontIndirect,addr @stFont
mov @hFont,eax
invoke SelectObject,wParam,eax
invoke SetTextColor,wParam,Blue
invoke GetSysColor,COLOR_MENU
invoke SetBkColor,wParam,eax
;********************************************************************
; 注意此处一定要把StockOject的返回值返回,否则无法显示颜色
;********************************************************************
invoke GetStockObject,HOLLOW_BRUSH
.else
mov eax,FALSE
ret
.endif
ret
.elseif eax == WM_PAINT
mov eax,idActiveDialog
.if eax == DLG_LOOK
call _PaintLookDialog
.endif
mov eax,FALSE
ret
.elseif eax == WM_TIMER
mov eax,idActiveDialog
.if eax == DLG_SHUTDOWN
dec dwShutDownCount
invoke wsprintf,offset szBuffer,offset szShutDownText,dwShutDownCount
invoke SetDlgItemText,hWnd,ID_SHUTDOWN_COUNT,offset szBuffer
.if dwShutDownCount == 0
invoke KillTimer,hWnd,2
invoke EndDialog,hWnd,NULL
invoke ExitWindowsEx,EWX_SHUTDOWN,NULL
.endif
.endif
.elseif eax == WM_COMMAND
mov eax,idActiveDialog
.if eax == DLG_SETUP
invoke _AlarmSetupCommand,hWnd,wParam,lParam
.elseif eax == DLG_LOOK
invoke _LookSetupCommand,hWnd,wParam,lParam
.else
mov eax,wParam
;********************************************************************
.if eax == ID_ABOUT_OK
invoke EndDialog,hWnd,NULL
.elseif eax == ID_SHUTDOWN
invoke KillTimer,hWnd,2
invoke EndDialog,hWnd,NULL
invoke ExitWindowsEx,EWX_SHUTDOWN,NULL
.elseif eax == ID_SHUTDOWN_CANCEL
invoke KillTimer,hWnd,2
invoke EndDialog,hWnd,NULL
.endif
.endif
.else
;********************************************************************
; 注意:对话框的消息处理后,要返回 TRUE,对没有处理的消息
; 要返回 FALSE
;********************************************************************
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DialogMainProc endp
;********************************************************************
; 主窗口程序
;********************************************************************
WndMainProc proc uses ebx edi esi, \
hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
local @stPos:POINT
local @stPs:PAINTSTRUCT,@hDC:DWORD
mov eax,uMsg
.if eax == WM_CREATE
mov eax,hWnd
mov hWinMain,eax
call _Init
;********************************************************************
.elseif eax == WM_PAINT
invoke BeginPaint,hWnd,addr @stPs
mov @hDC,eax
mov eax,@stPs.rcPaint.right
sub eax,@stPs.rcPaint.left
mov ecx,@stPs.rcPaint.bottom
sub ecx,@stPs.rcPaint.top
invoke BitBlt,@hDC,@stPs.rcPaint.left,@stPs.rcPaint.top,eax,ecx,\
hDcBack,@stPs.rcPaint.left,@stPs.rcPaint.top,SRCCOPY
invoke EndPaint,hWnd,addr @stPs
;********************************************************************
.elseif eax == WM_TIMER
call _FreshClock
;********************************************************************
.elseif eax == WM_SIZE
.if wParam == SIZE_MINIMIZED
;********************************************************************
; 最小化时建立小图标用的数据结构并建立小图标
;********************************************************************
or dwFlag,F_NOW_MINIMIZE
invoke EnableMenuItem,hMenu,IDM_LOOK,MF_GRAYED
mov stIcon.cbSize,sizeof NOTIFYICONDATA
push hWnd
pop stIcon.hwnd
mov stIcon.uID,1
mov stIcon.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP
mov stIcon.uCallbackMessage,WM_SHELLNOTIFY
mov eax,hIcon
mov stIcon.hIcon,eax
invoke ShowWindow,hWnd,SW_HIDE
invoke Shell_NotifyIcon,NIM_ADD,addr stIcon
;********************************************************************
; 恢复窗口时删除小图标
;********************************************************************
.else
and dwFlag,not F_NOW_MINIMIZE
invoke EnableMenuItem,hMenu,IDM_LOOK,MF_ENABLED
invoke Shell_NotifyIcon,NIM_DELETE,addr stIcon
.endif
.elseif eax == WM_COMMAND
.if lParam == 0
mov eax,wParam
.if ax == IDM_RESTORE
invoke ShowWindow,hWnd,SW_RESTORE
.elseif ax == IDM_MINI
invoke ShowWindow,hWnd,SW_MINIMIZE
.elseif ax == IDM_SETUP
invoke DialogBoxParam,hInstance,DLG_SETUP,\
hWnd,offset DialogMainProc,DLG_SETUP
.elseif ax == IDM_LOOK
invoke DialogBoxParam,hInstance,DLG_LOOK,\
hWnd,offset DialogMainProc,DLG_LOOK
.elseif ax == IDM_ONTOP
xor dwFlag,F_ALWAYS_ON_TOP
call _CheckOnTop
.elseif ax == IDM_AUTOMIN
xor dwFlag,F_MINIMIZE
call _CheckAutoMin
.elseif ax == IDM_AUTORUN
xor dwFlag,F_AUTORUN
call _CheckAutoRun
.elseif ax == IDM_ABOUT
invoke DialogBoxParam,hInstance,DLG_ABOUT,\
hWnd,offset DialogMainProc,DLG_ABOUT
.elseif ax == IDM_EXIT
call _Quit
.endif
.endif
;********************************************************************
; 左键双击时最小化
;********************************************************************
.elseif eax == WM_LBUTTONDBLCLK
invoke SendMessage,hWnd,WM_COMMAND,IDM_MINI,0
;********************************************************************
; 由于没有标题栏,下面代码用于按下左键时移动窗口
;********************************************************************
.elseif eax == WM_LBUTTONDOWN
invoke UpdateWindow,hWnd ;即时刷新
invoke ReleaseCapture
invoke SendMessage,hWnd,WM_NCLBUTTONDOWN,HTCAPTION,0
;********************************************************************
; 由于没有菜单,下面代码用于按下右键时弹出POPUP菜单
;********************************************************************
.elseif eax == WM_RBUTTONDOWN
.if wParam == MK_RBUTTON
invoke ModifyMenu,hMenu,0,MF_BYPOSITION,\
IDM_MINI,addr szMenuMini
invoke GetCursorPos,addr @stPos
invoke TrackPopupMenu,hMenu,TPM_LEFTALIGN,@stPos.x,@stPos.y,NULL,hWnd,NULL
.endif
;********************************************************************
; 自定义消息:小图标菜单及鼠标事件
;********************************************************************
.elseif eax == WM_SHELLNOTIFY
.if wParam == 1
.if lParam == WM_RBUTTONDOWN
;********************** 鼠标右键弹出菜单 ****************************
invoke ModifyMenu,hMenu,0,MF_BYPOSITION,\
IDM_RESTORE,addr szMenuRestore
invoke GetCursorPos,addr @stPos
invoke SetForegroundWindow,hWnd
invoke TrackPopupMenu,hMenu,TPM_RIGHTALIGN,@stPos.x,@stPos.y,NULL,hWnd,NULL
invoke PostMessage,hWnd,WM_NULL,0,0
.elseif lParam == WM_LBUTTONDBLCLK
invoke SendMessage,hWnd,WM_COMMAND,IDM_RESTORE,0
.endif
.endif
.elseif eax == WM_CLOSE
call _Quit
.elseif eax == WM_DESTROY
invoke PostQuitMessage,NULL
.elseif eax == WM_ENDSESSION
.if wParam == TRUE
call _Quit
.endif
;********************************************************************
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;********************************************************************
; 注意:WndProc 处理 Windows 消息后,必须在 Eax 中返回 0
; 但是由 DefWindowProc 处理后的返回值不能改变,否则窗口
; 将无法显示!
;********************************************************************
xor eax,eax
ret
WndMainProc endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 主窗口控制子程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_CheckOnTop proc
test dwFlag,F_ALWAYS_ON_TOP
.if !ZERO?
invoke CheckMenuItem,hMenu,IDM_ONTOP,MF_CHECKED
invoke SetWindowPos,hWinMain,HWND_TOPMOST,0,0,0,0,\
SWP_NOMOVE or SWP_NOSIZE
.else
invoke CheckMenuItem,hMenu,IDM_ONTOP,MF_UNCHECKED
invoke SetWindowPos,hWinMain,HWND_NOTOPMOST,0,0,0,0,\
SWP_NOMOVE or SWP_NOSIZE
.endif
ret
_CheckOnTop endp
;********************************************************************
_CheckAutoMin proc
test dwFlag,F_MINIMIZE
.if !ZERO?
invoke CheckMenuItem,hMenu,IDM_AUTOMIN,MF_CHECKED
.else
invoke CheckMenuItem,hMenu,IDM_AUTOMIN,MF_UNCHECKED
.endif
ret
_CheckAutoMin endp
;********************************************************************
_CheckAutoRun proc
test dwFlag,F_AUTORUN
.if !ZERO?
invoke CheckMenuItem,hMenu,IDM_AUTORUN,MF_CHECKED
invoke GetModuleFileName,hInstance,addr szBuffer,255
invoke _SetRegKeySz,addr szKeyName1,addr szKeyProgram,addr szBuffer,255
.else
invoke CheckMenuItem,hMenu,IDM_AUTORUN,MF_UNCHECKED
invoke _DelRegKey,addr szKeyName1,addr szKeyProgram
.endif
ret
_CheckAutoRun endp
;********************************************************************
_Init proc
local @stDeskTop:RECT,@stWindow:RECT
local @dwTop:DWORD,@dwLeft:DWORD
local @dwWidth:DWORD,@dwHeight:DWORD
invoke GetTickCount
mov dwRandom,eax
;************** 设置窗口名,以便同时运行时可以检测 ******************
invoke SendMessage,hWinMain,WM_SETTEXT,0,offset szClassName
invoke SendMessage,hWinMain,WM_SETICON,ICON_SMALL,hIcon
invoke _GetRegKeyDw,addr szKeyName,addr szKeyAlarmTime
.if eax == -1
xor eax,eax
.endif
push eax
shr eax,16
mov dwAlarmHour,eax
pop eax
and eax,0000ffffh
mov dwAlarmMinute,eax
invoke _GetRegKeyDw,addr szKeyName,addr szKeyFlag
.if eax != -1
mov dwFlag,eax
.endif
;************** 从注册表取得窗口坐标 ********************************
invoke _GetRegKeyDw,addr szKeyName,addr szKeyPosTop
mov @dwTop,eax
invoke _GetRegKeyDw,addr szKeyName,addr szKeyPosLeft
mov @dwLeft,eax
;************** 设置窗口位置 ****************************************
invoke GetWindowRect,hWinMain,addr @stWindow
invoke GetDesktopWindow
mov ebx,eax
invoke GetWindowRect,ebx,addr @stDeskTop
mov eax,@stWindow.bottom
sub eax,@stWindow.top
mov @dwHeight,eax
mov eax,@stWindow.right
sub eax,@stWindow.left
mov @dwWidth,eax
mov eax,@dwTop
mov ebx,@dwLeft
.if eax > @stDeskTop.bottom || ebx > @stDeskTop.right
mov ebx,@stDeskTop.bottom
sub ebx,@dwHeight
shr ebx,1
mov ecx,@stDeskTop.right
sub ecx,@dwWidth
shr ecx,1
.else
mov ecx,@dwLeft
mov ebx,@dwTop
.endif
invoke MoveWindow,hWinMain,ecx,ebx,@dwWidth,@dwHeight,FALSE
;*************** Check or UnCheck 菜单项 ****************************
call _CheckOnTop
call _CheckAutoMin
call _CheckAutoRun
;********************************************************************
call _CreateClock
call _FreshClock
ret
_Init endp
;********************************************************************
_Quit proc
local @stWindow:RECT
;************** 如果没有最小化,则保存窗口坐标 **********************
test dwFlag,F_NOW_MINIMIZE
.if ZERO?
invoke GetWindowRect,hWinMain,addr @stWindow
invoke _SetRegKeyDw,addr szKeyName,addr szKeyPosTop,@stWindow.top
invoke _SetRegKeyDw,addr szKeyName,addr szKeyPosLeft,@stWindow.left
.endif
mov eax,dwAlarmHour
shl eax,16
or eax,dwAlarmMinute
invoke _SetRegKeyDw,addr szKeyName,addr szKeyAlarmTime,eax
invoke _SetRegKeyDw,addr szKeyName,addr szKeyFlag,dwFlag
;************** 清除分配的资源 **************************************
invoke Shell_NotifyIcon,NIM_DELETE,addr stIcon
invoke DestroyMenu,hMenu
call _DeleteClock
invoke DestroyWindow,hWinMain
ret
_Quit endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 闹钟显示子程序
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -