⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clock.asm

📁 用汇编语言编的闹钟程序
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		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 + -