www.pudn.com > benq.rar > Clock.asm


;******************************************************************** 
	DEBUG	=	0 
;******************************************************************** 
;	卡通小闹钟 by 罗云彬,http://asm.yeah.net 
;	V1.0.0423 - 2000年4月23日 
;		* 初始版本 
;	V1.1.0521 - 2000年5月21日 
;		* 修正在Windows2000下无法显示的错误(将Bitmap改为24bit) 
;		* 修正在Windows2000下无法访问注册表的错误 
;		* 屏幕分辨率改变后自动修正位置 
;	V1.1.0720 - 2000年7月20日 
;		* 更正图片 - 原认为图片在 Windows2000下无法是 256 色 
;		  后发现问题在于2000下图片不能用压缩格式,所以将图片 
;		  改为 256色不压缩格式。 
;******************************************************************** 
;	本程序主要练习使用: 
;	1. 注册表键值的建立和读取 
;	2. 任务栏小图标的使用 
;	3. PopUp 菜单的使用 
;	4. 常用对话框控件-单选钮,复选钮等的使用,对话框画图的刷新 
;	5. 不规则窗口的创建 
;	6. 位图,光标的使用 
;	7. 声音文件(WAV)的使用 
;******************************************************************** 
 
	.386 
	.model flat, stdcall 
	option casemap :none   ; case sensitive 
 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	Include 数据 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
	include		windows.inc 
	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 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	Equ 数据 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
ID_TIMER	equ		1 
;**************	Equ 数据 ********************************** 
IDI_MAIN	equ		1		;icon 
IDC_MAIN	equ		100		;cursor 
IDC_HANDLE	equ		101 
;**************	Equ 数据 ********************************** 
DLG_SETUP	equ		1100		;dialog - setup 
CHK_ONCE	equ		1101 
CHK_REPORT	equ		1102 
CHK_ALARM	equ		1103 
REP_WAV1	equ		1104 
REP_WAV2	equ		1105 
REP_PLAY1	equ		1110 
REP_PLAY2	equ		1111 
REP_FILE	equ		1112 
REP_BROWSE	equ		1113 
ALM_WAV1	equ		1106 
ALM_WAV2	equ		1107 
ALM_MSG		equ		1108 
ALM_SHUTDOWN	equ		1109 
ALM_PLAY1	equ		1114 
ALM_PLAY2	equ		1115 
ALM_FILE	equ		1116 
ALM_BROWSE	equ		1117 
ALM_TIME	equ		1118 
ALM_FROMNOW	equ		1119 
ALM_HOUR1	equ		1120 
ALM_MIN1	equ		1122 
ALM_HOUR2	equ		1124 
ALM_MIN2	equ		1126 
ALM_MESSAGE	equ		1128 
ID_SETUP_OK	equ		1129 
ID_SETUP_APPLY	equ		1130 
ID_SETUP_CANCEL	equ		1131 
;**************	Equ 数据 ********************************** 
DLG_ABOUT	equ		1200		;dialog - about 
ID_ABOUT_OK	equ		1201 
ID_EMAIL	equ		1202 
ID_HOMEPAGE	equ		1203 
;**************	Equ 数据 ********************************** 
DLG_SHUTDOWN		equ	1300		;dialog - shutdown 
ID_SHUTDOWN		equ	1301 
ID_SHUTDOWN_CANCEL	equ	1302 
ID_SHUTDOWN_COUNT	equ	1303 
;**************	Equ 数据 ********************************** 
DLG_LOOK	equ		1400		;dialog - look setup 
ID_LOOK_OK	equ		1401 
ID_LOOK_APPLY	equ		1402 
ID_LOOK_CANCEL	equ		1403 
IDL_RNDBACK	equ		1404 
IDL_RNDNUMBER	equ		1405 
IDL_B01		equ		1411 
IDL_B02		equ		1412 
IDL_B03		equ		1413 
IDL_B04		equ		1414 
IDL_B05		equ		1415 
IDL_B06		equ		1416 
IDL_B07		equ		1417 
IDL_B08		equ		1418 
IDL_N01		equ		1421 
IDL_N02		equ		1422 
IDL_N03		equ		1423 
IDL_N04		equ		1424 
IDL_N05		equ		1425 
IDL_N06		equ		1426 
IDL_N07		equ		1427 
IDL_N08		equ		1428 
IDL_LOOK_PIC1	equ		1429 
IDL_LOOK_PIC2	equ		1430 
IDL_LOOK_PIC3	equ		1431 
;**************	Equ 数据 ********************************** 
IDM_MAIN	equ		2000		;menu 
IDM_MINI	equ		2001 
IDM_RESTORE	equ		2002 
IDM_SETUP  	equ		2003 
IDM_LOOK	equ		2004 
IDM_ONTOP	equ	  	2005 
IDM_AUTORUN	equ		2006 
IDM_AUTOMIN	equ		2007 
IDM_ABOUT	equ		2008 
IDM_EXIT	equ		2009 
;**************	Equ 数据 ********************************** 
IDB_0		equ 		3000		;bitmap 
IDB_1		equ 		3001 
IDB_2		equ 		3002 
IDB_3		equ 		3003 
IDB_4		equ 		3004 
IDB_5		equ 		3005 
IDB_6		equ 		3006 
IDB_7		equ 		3007 
IDB_NUM0	equ		3100 
IDB_NUM1	equ		3101 
IDB_NUM2	equ		3102 
IDB_NUM3	equ		3103 
IDB_NUM4	equ		3104 
IDB_NUM5	equ		3105 
IDB_NUM6	equ		3106 
IDB_NUM7	equ		3107 
;**************	Equ 数据 ********************************** 
IDW_SOUND	equ		4000		;sound 
IDS_0		equ		5000		;string 
 
WM_SHELLNOTIFY	equ		WM_USER+100 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	数据段 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
		.data? 
hInstance	dd		? 
hWinMain	dd		? 
hWinDialog	dd		? 
hWinLookSetup	dd		? 
hIcon		dd		? 
hCursor		dd		? 
hMenu		dd		? 
hAlarmThread	dd		?	;闹铃子线程 
 
hBmpBack	dd		?	;background bitmap 
hBmpNum		dd		?	;number bitmap 
 
hDcBack		dd		?	;background DC 
hDcNum		dd		?	;number DC 
 
hDcLook1	dd		? 
hDcLook1Mask	dd		? 
hDcLook2	dd		? 
hDcLook3	dd		? 
hDcTemp		dd		? 
hBmpLook1	dd		? 
hBmpLook1Mask	dd		? 
hBmpLook2	dd		? 
hBmpLook3	dd		? 
 
hWinPic1	dd		? 
hWinPic2	dd		? 
hWinPic3	dd		? 
 
dwNumX		dd		?	;时钟在背景上的位置 
dwNumY		dd		? 
 
dwAlarmHour	dd		?	;闹铃时间 
dwAlarmMinute	dd		? 
dwHour1		dd		?	;设置时临时使用的闹铃时间 
dwHour2		dd		? 
dwMinute1	dd		? 
dwMinute2	dd		? 
dwTempFlag	dd		?	;设置时临时使用的标志 
dwShutDownCount	dd		?	;关机倒计时 
idActiveDialog	dd		?	;当前激活的对话框 
wLastSecond	dw		?	; 
dwRandom	dd		? 
 
szBuffer	db	256 dup	(?) 
stIcon		NOTIFYICONDATA	 
stOpenFile	OPENFILENAME	 
stTime		SYSTEMTIME	 
 
stWcMain	WNDCLASSEX	 
stMsg		MSG		 
 
;**************	数据段 ************************************ 
		.data 
 
;********************************************************** 
;	标志位定义 
;********************************************************** 
F_ALWAYS_ON_TOP	equ		00000001h	;Always on top 
F_MINIMIZE	equ		00000002h	;Minimize on run 
F_AUTORUN	equ		00000004h	;AutoRun on Boot 
F_NOW_MINIMIZE	equ		00000008h	;现在是最小化状态 
F_REPORT	equ		00000010h	;启用整点报时 
F_ALARM		equ		00000020h	;启用闹钟功能 
F_REPORT_MODE	equ		00000040h	;用标准声音/指定声音 
F_TIME_MODE	equ		00000080h	;闹铃时间/开始计时 
F_ALARM_MODE	equ		00000300h	;00-11 闹铃音/指定声音/提示框/关机 
F_ALARM_MODE_	equ		8		;右移位数 
F_RND_BACK	equ		00000400h	;随机选择背景 
F_RND_FONT	equ		00000800h	;随机选择字形 
F_BACK_NO	equ		0000f000h	;背景编号 
F_BACK_NO_	equ		12 
F_FONT_NO	equ		000f0000h	;字形编号 
F_FONT_NO_	equ		16 
F_ALARM_ONCE	equ		00100000h	;闹铃一次后即取消 
 
dwFlag		dd		F_ALWAYS_ON_TOP or F_REPORT or F_REPORT_MODE or F_TIME_MODE \ 
				or F_RND_BACK or F_RND_FONT 
;********************************************************** 
dwOffsetTable	dd		6,67		;1 
		dd		15,58		;2 
		dd		25,80		;3 
		dd		6,6		;4 
		dd		6,30		;5 
		dd		5,113		;6 
		dd		5,5		;7 
		dd		5,7		;8 
 
 
szIconText	db	'%4d-%d-%d %d:%02d:%02d',0 
szClassName	db	'小闹钟',0 
;********************************************************** 
;	菜单项 
;********************************************************** 
szMenuMini	db	'闹钟最小化(&M)',0 
szMenuRestore	db	'闹钟还原(&M)',0 
szHomePage	db	"http://asm.yeah.net",0 
szEmail		db	"mailto:bigluo@telekbird.com.cn" 
		db	"?subject=嗨!我喜欢你的程序!",0 
;********************************************************** 
;	注册表项目 
;********************************************************** 
szKeyName	db	'Software\Lyb Software\' 
szKeyProgram	db	'AlarmClock V1.0',0 
szKeyPosLeft	db	'Position.Left',0 
szKeyPosTop	db	'Position.Top',0 
szKeyFlag	db	'Flags',0 
szKeyAlarmTime	db	'Alarm Time',0 
szKeyReportFile	db	'Report WAV file',0 
szKeyAlarmFile	db	'Alarm WAV file',0 
szKeyAlarmText	db	'Alarm String',0 
 
szKeyName1	db	'Software\Microsoft\Windows\CurrentVersion\Run',0 
 
szTitleOpen	db	'打开声音文件...',0 
szExt		db	'*.wav',0 
szFilter	db	'Wave Files(*.wav)',0,'*.wav',0,'All Files(*.*)',0,'*.*',0,0 
szAlarmTitle	db	'小闹钟的提醒',0 
szShutDownText	db	'%d 秒...',0 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	代码段 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
 
		.code 
 
if		DEBUG 
		include		Debug.asm 
endif 
 
include		Reg.asm 
include		Win.asm 
include		Graphic.asm 
 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	公用子程序部分:其它部分 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
_TimeAdd	proto	:DWORD,:DWORD		;和当前时间相加 
_TimeSub	proto	:DWORD,:DWORD		;和时间相减 
;******************************************************************** 
;	时间相加子程序:返回输入时间+当前时间 
;		返回:eax = 小时,edx = 分钟 
;******************************************************************** 
_TimeAdd	proc	dwAddHour:DWORD,dwAddMinute:DWORD 
 
		invoke	GetLocalTime,addr stTime 
 
		xor	eax,eax 
 
		mov	ax,stTime.wHour 
		mov	bx,60 
		mul	bx 
		add	ax,stTime.wMinute 
		mov	ebx,eax		;ebx = now time 
 
		mov	eax,dwAddHour 
		mov	ecx,60 
		mul	ecx 
		add	eax,dwAddMinute 
		add	eax,ebx 
_ta0: 
		cmp	eax,24*60 
		jb	_ta1 
		sub	eax,24*60 
		jmp	_ta0 
_ta1: 
		xor	edx,edx 
		mov	ebx,60 
		div	ebx 
		ret 
 
_TimeAdd	endp 
;******************************************************************** 
;	时间相减子程序:返回输入时间-当前时间 
;		返回:eax = 小时,edx = 分钟 
;******************************************************************** 
_TimeSub	proc	dwAddHour:DWORD,dwAddMinute:DWORD 
 
		invoke	GetLocalTime,addr stTime 
		xor	eax,eax 
		xor	ebx,ebx 
 
		mov	ax,stTime.wHour 
		mov	bx,60 
		mul	bx 
		add	ax,stTime.wMinute 
		mov	ebx,eax 
 
		mov	eax,dwAddHour		;ebx = now time 
		mov	ecx,60 
		mul	ecx 
		add	eax,dwAddMinute 
 
		cmp	eax,ebx 
		jae	_ts0 
		add	eax,24*60 
_ts0: 
		sub	eax,ebx 
 
		xor	edx,edx 
		mov	ebx,60 
		div	ebx 
		ret 
 
_TimeSub	endp 
;******************************************************************** 
;	随机数发生器 
;		输入:al = 随机数 bit 数 
;		返回:eax = 随机数 
;******************************************************************** 
_Random		proc uses ebx ecx 
 
		mov	cl,al 
	        xor	eax,eax 
	        mov	bl,byte ptr dwRandom 
	        and	bl,1 
Gen_bit:			; make n bit numbers 
	        shl	eax,1 
	        mov	edx,dwRandom	; Copy seed 
	        shr	edx,9 
	        xor	bl,dl 
	        shr	edx,5 
	        xor	bl,dl 
	    	bt	ebx,1		; Copy bit 1 to carry flag 
	        rcr	dwRandom,1	; Rotate seed right 1 bit 
	        setc	bl		; Set bl TRUE if carry is set 
		or	al,bl 
 
		dec	cl 
	        jnz	Gen_bit 
		ret 
 
_Random		endp 
 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	程序开始 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
start: 
		invoke	FindWindow,NULL,offset szClassName 
		.if	eax != NULL 
			invoke	ShowWindow,eax,SW_SHOWNORMAL 
			invoke	ExitProcess,NULL 
		.endif 
 
		invoke	InitCommonControls 
		invoke	GetModuleHandle,NULL 
		mov	hInstance,eax 
 
		invoke	LoadIcon,hInstance,IDI_MAIN 
		mov	hIcon,eax 
		invoke	LoadMenu,hInstance,IDM_MAIN 
		invoke	GetSubMenu,eax,0	;PopUp 菜单要用到子菜单 
		mov	hMenu,eax 
 
;***************** 注册窗口类 *************************************** 
		invoke	LoadCursor,hInstance,IDC_HANDLE 
		mov	hCursor,eax 
		invoke	LoadCursor,hInstance,IDC_MAIN 
		mov	stWcMain.hCursor,eax 
		mov	stWcMain.cbSize,sizeof WNDCLASSEX 
		mov	stWcMain.hIconSm,0 
		mov	stWcMain.style,CS_HREDRAW or CS_VREDRAW or CS_DBLCLKS 
		mov	stWcMain.lpfnWndProc,offset WndMainProc 
		mov	stWcMain.cbClsExtra,0 
		mov	stWcMain.cbWndExtra,0 
		mov	eax,hInstance 
		mov	stWcMain.hInstance,eax 
		mov	stWcMain.hIcon,0 
		mov	stWcMain.hbrBackground,COLOR_BTNFACE+1 
		mov	stWcMain.lpszClassName,offset szClassName 
		mov	stWcMain.lpszMenuName,0 
		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 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	闹钟显示子程序 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
_DecToBcd	proc 
 
		push	ebx 
		mov	bl,10 
		div	bl 
		pop	ebx 
		ret 
 
_DecToBcd	endp 
;******************************************************************** 
_DisplayOneNumber	proc	hDcDest:DWORD,hDcSource:DWORD,dwCopyY:DWORD 
		local	@dwBackX,@dwNumX,@dwWidth 
 
		push	eax 
 
		mov	@dwBackX,ebx 
		mov	@dwWidth,15		;每位数字宽为15 Pixel 
		.if	al == ':' 
			mov	al,10 
			mov	@dwWidth,8 
		.elseif	al == -1		;如果显示: 则宽度为8 Pixel 
			mov	al,11 
		.endif 
 
		xor	ah,ah			;计算数字在图片中的位置 
		cwd 
		mov	edx,15 
		mul	edx 
 
		mov	@dwNumX,eax		;显示到 ebx指定的位置 
		invoke	BitBlt,hDcDest,@dwBackX,dwCopyY,@dwWidth,25,\ 
			hDcSource,@dwNumX,0,SRCCOPY 
 
		mov	ebx,@dwBackX 
		add	ebx,@dwWidth 
		pop	eax 
		ret 
 
_DisplayOneNumber	endp 
;******************************************************************** 
_CreateClockPic	proc	hDcDest:DWORD,hDcSource:DWORD,dwCopyX:DWORD,dwCopyY:DWORD 
 
		invoke	BitBlt,hDcDest,dwCopyX,dwCopyY,4,25,\ 
			hDcSource,11*15,0,SRCCOPY 
		mov	eax,dwCopyX 
		add	eax,106 
		invoke	BitBlt,hDcDest,eax,dwCopyY,4,25,\ 
			hDcSource,11*15,0,SRCCOPY 
 
		mov	ebx,dwCopyX 
		add	ebx,2 
 
		xor	eax,eax 
		mov	ax,stTime.wHour	;显示小时 - 十位 
		call	_DecToBcd		;如果为0,显示空白 
		.if	al == 0 
			mov	al,-1 
		.endif 
		invoke	_DisplayOneNumber,hDcDest,hDcSource,dwCopyY 
		mov	al,ah			;显示小时 - 个位 
		invoke	_DisplayOneNumber,hDcDest,hDcSource,dwCopyY 
		mov	al,':' 
		invoke	_DisplayOneNumber,hDcDest,hDcSource,dwCopyY 
 
		mov	ax,stTime.wMinute	;显示分钟 - 十位 
		invoke	_DecToBcd 
		invoke	_DisplayOneNumber,hDcDest,hDcSource,dwCopyY 
		mov	al,ah			;显示分钟 - 个位 
		invoke	_DisplayOneNumber,hDcDest,hDcSource,dwCopyY 
 
		mov	al,':' 
		invoke	_DisplayOneNumber,hDcDest,hDcSource,dwCopyY 
		mov	ax,stTime.wSecond	;显示秒 - 十位 
		invoke	_DecToBcd 
		invoke	_DisplayOneNumber,hDcDest,hDcSource,dwCopyY 
		mov	al,ah			;显示秒 - 个位 
		invoke	_DisplayOneNumber,hDcDest,hDcSource,dwCopyY 
		ret 
 
_CreateClockPic	endp 
;******************************************************************** 
_FreshClock	proc 
		local	@stClock:RECT 
		local	@dwYear:DWORD,@dwMonth:DWORD,@dwDay:DWORD 
		local	@dwHour:DWORD,@dwMinute:DWORD,@dwSecond:DWORD 
 
		invoke	GetLocalTime,addr stTime 
 
		mov	bx,wLastSecond 
		mov	ax,stTime.wSecond	;时间未变则返回 
		mov	wLastSecond,ax 
		.if	ax == bx 
			ret 
		.endif 
 
		test	dwFlag,F_REPORT 
		.if	!ZERO?			;整点报时 
			mov	bx,stTime.wMinute 
			.if	ax == 0 && bx == 0 
				call	_ClockReport 
			.endif 
		.endif 
 
		test	dwFlag,F_ALARM 
		.if	!ZERO?			;闹钟功能 
			mov	ax,stTime.wSecond 
			.if	ax == 0 
				xor	eax,eax 
				xor	ebx,ebx 
				mov	ax,stTime.wHour 
				mov	bx,stTime.wMinute 
				.if	eax == dwAlarmHour && ebx == dwAlarmMinute 
					call	_ClockAlarm 
				.endif 
			.endif 
		.endif 
 
		invoke	_CreateClockPic,hDcBack,hDcNum,dwNumX,dwNumY 
 
		mov	ebx,dwNumX 
		mov	@stClock.left,ebx 
		add	ebx,110 
		mov	@stClock.right,ebx 
		mov	eax,dwNumY 
		mov	@stClock.top,eax 
		add	eax,25 
		mov	@stClock.bottom,eax 
		invoke	InvalidateRect,hWinMain,addr @stClock,0	;刷新屏幕 
 
		xor	eax,eax 
		mov	ax,stTime.wYear 
		mov	@dwYear,eax 
		mov	ax,stTime.wMonth 
		mov	@dwMonth,eax 
		mov	ax,stTime.wDay 
		mov	@dwDay,eax 
		mov	ax,stTime.wHour 
		mov	@dwHour,eax 
		mov	ax,stTime.wMinute 
		mov	@dwMinute,eax 
		mov	ax,stTime.wSecond 
		mov	@dwSecond,eax 
		invoke	wsprintf,offset szBuffer,offset szIconText,\ 
			@dwYear,@dwMonth,@dwDay,@dwHour,@dwMinute,@dwSecond 
		invoke	lstrcpy,addr stIcon.szTip,addr szBuffer 
		invoke	Shell_NotifyIcon,NIM_MODIFY,addr stIcon 
 
		ret 
 
_FreshClock	endp 
;******************************************************************** 
_CreateClock	proc 
		local	@hDC:DWORD 
		local	@stBmp:BITMAP 
		local	@dwX:DWORD,@dwY:DWORD,@rgbBack:DWORD 
 
;*************** 取得背景图片编号 *********************************** 
		test	dwFlag,F_RND_BACK 
		.if	!ZERO? 
			mov	al,3 
			call	_Random 
		.else 
			mov	eax,dwFlag 
			and	eax,F_BACK_NO 
			shr	eax,F_BACK_NO_ 
		.endif 
		push	eax 
		add	eax,IDB_0 
		invoke	LoadBitmap,hInstance,eax	;装入背景图片 
		mov	hBmpBack,eax 
		pop	ebx 
 
		shl	ebx,3			;x 8 
		add	ebx,offset dwOffsetTable 
		mov	eax,[ebx] 
		mov	dwNumX,eax 
		mov	eax,[ebx+4] 
		mov	dwNumY,eax 
;*************** 取得数字图片编号 *********************************** 
		test	dwFlag,F_RND_FONT 
		.if	!ZERO? 
			mov	al,3 
			call	_Random 
		.else 
			mov	eax,dwFlag 
			and	eax,F_FONT_NO 
			shr	eax,F_FONT_NO_ 
		.endif 
 
		add	eax,IDB_NUM0 
		invoke	LoadBitmap,hInstance,eax	;装入数字图片 
		mov	hBmpNum,eax 
 
		invoke	_SetWindowShape,hWinMain,hBmpBack	;设置窗口形状为背景图片 
		invoke  GetDC,hWinMain 
		mov	@hDC,eax 
		invoke	CreateCompatibleDC,@hDC			;建立背景及数字 DC 
		mov	hDcBack,eax 
		invoke	CreateCompatibleDC,@hDC 
		mov	hDcNum,eax 
		invoke	ReleaseDC,hWinMain,@hDC 
 
		invoke	SelectObject,hDcBack,hBmpBack 
		invoke	SelectObject,hDcNum,hBmpNum 
		invoke	SetTimer,hWinMain,ID_TIMER,220,NULL	;开始计时 
 
		mov	ebx,dwNumX				;显示时钟的左右空白部分 
		mov	al,-1 
		call	_DisplayOneNumber 
		mov	ebx,dwNumX 
		add	ebx,95 
		call	_DisplayOneNumber 
		mov	wLastSecond,-1 
 
		ret 
 
_CreateClock	endp 
;******************************************************************** 
_DeleteClock	proc 
 
		invoke	KillTimer,hWinMain,ID_TIMER 
		invoke	DeleteDC,hDcBack 
		invoke	DeleteDC,hDcNum 
		invoke	DeleteObject,hBmpBack 
		invoke	DeleteObject,hBmpNum 
 
		ret 
 
_DeleteClock	endp 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
;	Setup 对话框控制子程序 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 
_CheckItem	proto	:DWORD,:DWORD 
_EnableItem	proto	:DWORD,:DWORD 
;******************************************************************** 
_CheckItem	proc	item:DWORD,flag:DWORD 
 
		invoke	GetDlgItem,hWinDialog,item 
		invoke	SendMessage,eax,BM_SETCHECK,flag,0 
		ret 
 
_CheckItem	endp 
;******************************************************************** 
_EnableItem	proc	item:DWORD,flag:DWORD 
 
		invoke	GetDlgItem,hWinDialog,item 
		invoke	EnableWindow,eax,flag 
		ret 
 
_EnableItem	endp 
;******************************************************************** 
;	“到时播放标准声音文件” 
;******************************************************************** 
_CheckReport1	proc 
 
		invoke	_CheckItem,REP_WAV1,1 
		invoke	_CheckItem,REP_WAV2,0 
		invoke	_EnableItem,REP_PLAY1,TRUE 
		invoke	_EnableItem,REP_PLAY2,FALSE 
		invoke	_EnableItem,REP_FILE,FALSE 
		invoke	_EnableItem,REP_BROWSE,FALSE 
		ret 
 
_CheckReport1	endp 
;******************************************************************** 
;	“到时播放指定声音文件” 
;******************************************************************** 
_CheckReport2	proc 
 
		invoke	_CheckItem,REP_WAV1,0 
		invoke	_CheckItem,REP_WAV2,1 
		invoke	_EnableItem,REP_PLAY1,FALSE 
		invoke	_EnableItem,REP_PLAY2,TRUE 
		invoke	_EnableItem,REP_FILE,TRUE 
		invoke	_EnableItem,REP_BROWSE,TRUE 
		ret 
 
_CheckReport2	endp 
;******************************************************************** 
;	“闹铃时间:为绝对时间” 
;******************************************************************** 
_CheckTime1	proc 
 
		invoke	_CheckItem,ALM_TIME,1	;闹铃时间 
		invoke	_CheckItem,ALM_FROMNOW,0 
		invoke	_EnableItem,ALM_HOUR1,TRUE 
		invoke	_EnableItem,ALM_MIN1,TRUE 
		invoke	_EnableItem,ALM_HOUR2,FALSE 
		invoke	_EnableItem,ALM_MIN2,FALSE 
		ret 
 
_CheckTime1	endp 
;******************************************************************** 
;	“闹铃时间:为相对时间” 
;******************************************************************** 
_CheckTime2	proc 
 
		invoke	_CheckItem,ALM_TIME,0	;闹铃时间 
		invoke	_CheckItem,ALM_FROMNOW,1	;从现在起 
		invoke	_EnableItem,ALM_HOUR1,FALSE 
		invoke	_EnableItem,ALM_MIN1,FALSE 
		invoke	_EnableItem,ALM_HOUR2,TRUE 
		invoke	_EnableItem,ALM_MIN2,TRUE 
		ret 
 
_CheckTime2	endp 
;******************************************************************** 
;	“到时播放标准声音文件” 
;******************************************************************** 
_CheckAlarm1	proc 
 
		invoke	_CheckItem,ALM_WAV1,1 
		invoke	_CheckItem,ALM_WAV2,0 
		invoke	_CheckItem,ALM_MSG,0 
		invoke	_CheckItem,ALM_SHUTDOWN,0 
		invoke	_EnableItem,ALM_PLAY1,TRUE 
		invoke	_EnableItem,ALM_PLAY2,FALSE 
		invoke	_EnableItem,ALM_FILE,FALSE 
		invoke	_EnableItem,ALM_BROWSE,FALSE 
		invoke	_EnableItem,ALM_MESSAGE,FALSE 
		ret 
 
_CheckAlarm1	endp 
;******************************************************************** 
;	“到时播放指定声音文件” 
;******************************************************************** 
_CheckAlarm2	proc 
 
		invoke	_CheckItem,ALM_WAV1,0 
		invoke	_CheckItem,ALM_WAV2,1 
		invoke	_CheckItem,ALM_MSG,0 
		invoke	_CheckItem,ALM_SHUTDOWN,0 
		invoke	_EnableItem,ALM_PLAY1,FALSE 
		invoke	_EnableItem,ALM_PLAY2,TRUE 
		invoke	_EnableItem,ALM_FILE,TRUE 
		invoke	_EnableItem,ALM_BROWSE,TRUE 
		invoke	_EnableItem,ALM_MESSAGE,FALSE 
		ret 
 
_CheckAlarm2	endp 
;******************************************************************** 
;	“到时对话框提示” 
;******************************************************************** 
_CheckAlarm3	proc 
 
		invoke	_CheckItem,ALM_WAV1,0 
		invoke	_CheckItem,ALM_WAV2,0 
		invoke	_CheckItem,ALM_MSG,1 
		invoke	_CheckItem,ALM_SHUTDOWN,0 
		invoke	_EnableItem,ALM_PLAY1,FALSE 
		invoke	_EnableItem,ALM_PLAY2,FALSE 
		invoke	_EnableItem,ALM_FILE,FALSE 
		invoke	_EnableItem,ALM_BROWSE,FALSE 
		invoke	_EnableItem,ALM_MESSAGE,TRUE 
		ret 
 
_CheckAlarm3	endp 
;******************************************************************** 
;	“到时关闭计算机” 
;******************************************************************** 
_CheckAlarm4	proc 
 
		invoke	_CheckItem,ALM_WAV1,0 
		invoke	_CheckItem,ALM_WAV2,0 
		invoke	_CheckItem,ALM_MSG,0 
		invoke	_CheckItem,ALM_SHUTDOWN,1 
		invoke	_EnableItem,ALM_PLAY1,FALSE 
		invoke	_EnableItem,ALM_PLAY2,FALSE 
		invoke	_EnableItem,ALM_FILE,FALSE 
		invoke	_EnableItem,ALM_BROWSE,FALSE 
		invoke	_EnableItem,ALM_MESSAGE,FALSE 
		ret 
 
_CheckAlarm4	endp 
;******************************************************************** 
;	“整点报时功能”关闭 
;******************************************************************** 
_DisableReport	proc 
 
		invoke	_CheckItem,CHK_REPORT,0 
		invoke	_EnableItem,REP_WAV1,FALSE 
		invoke	_EnableItem,REP_WAV2,FALSE 
		invoke	_EnableItem,REP_PLAY1,FALSE 
		invoke	_EnableItem,REP_PLAY2,FALSE 
		invoke	_EnableItem,REP_FILE,FALSE 
		invoke	_EnableItem,REP_BROWSE,FALSE 
		ret 
 
_DisableReport	endp 
;******************************************************************** 
;	“整点报时功能”开启 
;******************************************************************** 
_EnableReport	proc 
 
		invoke	_CheckItem,CHK_REPORT,1 
		invoke	_EnableItem,REP_WAV1,TRUE 
		invoke	_EnableItem,REP_WAV2,TRUE 
		invoke	_EnableItem,REP_PLAY1,TRUE 
		invoke	_EnableItem,REP_PLAY2,TRUE 
		invoke	_EnableItem,REP_FILE,TRUE 
		invoke	_EnableItem,REP_BROWSE,TRUE 
		ret 
 
_EnableReport	endp 
;******************************************************************** 
;	“启用闹钟功能”关闭 
;******************************************************************** 
_DisableAlarm	proc 
 
		invoke	_CheckItem,CHK_ALARM,0 
		invoke	_EnableItem,CHK_ONCE,FALSE 
		invoke	_EnableItem,ALM_TIME,FALSE 
		invoke	_EnableItem,ALM_FROMNOW,FALSE 
		invoke	_EnableItem,ALM_WAV1,FALSE 
		invoke	_EnableItem,ALM_WAV2,FALSE 
		invoke	_EnableItem,ALM_MSG,FALSE 
		invoke	_EnableItem,ALM_SHUTDOWN,FALSE 
		invoke	_EnableItem,ALM_HOUR1,FALSE 
		invoke	_EnableItem,ALM_MIN1,FALSE 
		invoke	_EnableItem,ALM_HOUR2,FALSE 
		invoke	_EnableItem,ALM_MIN2,FALSE 
		invoke	_EnableItem,ALM_PLAY1,FALSE 
		invoke	_EnableItem,ALM_PLAY2,FALSE 
		invoke	_EnableItem,ALM_FILE,FALSE 
		invoke	_EnableItem,ALM_BROWSE,FALSE 
		invoke	_EnableItem,ALM_MESSAGE,FALSE 
		ret 
 
_DisableAlarm	endp 
;******************************************************************** 
;	“启用闹钟功能”开启 
;******************************************************************** 
_EnableAlarm	proc 
 
		invoke	_CheckItem,CHK_ALARM,1 
		invoke	_EnableItem,CHK_ONCE,TRUE 
		invoke	_EnableItem,ALM_WAV1,TRUE 
		invoke	_EnableItem,ALM_WAV2,TRUE 
		invoke	_EnableItem,ALM_PLAY1,TRUE 
		invoke	_EnableItem,ALM_PLAY2,TRUE 
		invoke	_EnableItem,ALM_FILE,TRUE 
		invoke	_EnableItem,ALM_BROWSE,TRUE 
		invoke	_EnableItem,ALM_TIME,TRUE 
		invoke	_EnableItem,ALM_FROMNOW,TRUE 
		invoke	_EnableItem,ALM_MSG,TRUE 
		invoke	_EnableItem,ALM_SHUTDOWN,TRUE 
		invoke	_EnableItem,ALM_HOUR1,TRUE 
		invoke	_EnableItem,ALM_MIN1,TRUE 
		invoke	_EnableItem,ALM_HOUR2,TRUE 
		invoke	_EnableItem,ALM_MIN2,TRUE 
		invoke	_EnableItem,ALM_MESSAGE,TRUE 
		ret 
 
_EnableAlarm	endp 
;******************************************************************** 
;	设置对话框初始化 
;******************************************************************** 
_InitSetupDialog	proc 
 
;*************** 取标志到临时位置 *********************************** 
		mov	eax,dwFlag 
;		mov	ebx,001003f0h 
;		and	eax,ebx 
;		not	ebx 
;		and	dwTempFlag,ebx 
;		or	dwTempFlag,eax 
		mov	dwTempFlag,eax 
 
		mov	eax,dwAlarmHour 
		mov	dwHour1,eax 
		mov	eax,dwAlarmMinute 
		mov	dwMinute1,eax 
;*************** 计算时间 ******************************************* 
		invoke	_TimeSub,dwAlarmHour,dwAlarmMinute 
		mov	dwHour2,eax 
		mov	dwMinute2,edx 
;*************** 从注册表取出文本信息 ******************************* 
		mov	szBuffer,0 
		invoke	_GetRegKeySz,addr szKeyName,addr szKeyReportFile,addr szBuffer,255 
		invoke	SetDlgItemText,hWinDialog,REP_FILE,offset szBuffer 
		invoke	_GetRegKeySz,addr szKeyName,addr szKeyAlarmFile,addr szBuffer,255 
		invoke	SetDlgItemText,hWinDialog,ALM_FILE,offset szBuffer 
		invoke	_GetRegKeySz,addr szKeyName,addr szKeyAlarmText,addr szBuffer,255 
		invoke	SetDlgItemText,hWinDialog,ALM_MESSAGE,offset szBuffer 
;*************** 设置文本编辑框的最大文本长度 *********************** 
		invoke	SendDlgItemMessage,hWinDialog,ALM_HOUR1,EM_LIMITTEXT,2,NULL 
		invoke	SendDlgItemMessage,hWinDialog,ALM_HOUR2,EM_LIMITTEXT,2,NULL 
		invoke	SendDlgItemMessage,hWinDialog,ALM_MIN1,EM_LIMITTEXT,2,NULL 
		invoke	SendDlgItemMessage,hWinDialog,ALM_MIN2,EM_LIMITTEXT,2,NULL 
		invoke	SendDlgItemMessage,hWinDialog,ALM_MIN2,EM_LIMITTEXT,2,NULL 
		invoke	SendDlgItemMessage,hWinDialog,REP_FILE,EM_LIMITTEXT,250,NULL 
		invoke	SendDlgItemMessage,hWinDialog,ALM_FILE,EM_LIMITTEXT,250,NULL 
		invoke	SendDlgItemMessage,hWinDialog,ALM_MESSAGE,EM_LIMITTEXT,100,NULL 
		call	_FreshSetupDialog 
		ret 
 
_InitSetupDialog	endp 
;******************************************************************** 
;	根据标志位刷新设置对话框的屏幕 
;******************************************************************** 
_FreshSetupDialog	proc 
 
		invoke	SetDlgItemInt,hWinDialog,ALM_HOUR1,dwHour1,FALSE 
		invoke	SetDlgItemInt,hWinDialog,ALM_MIN1,dwMinute1,FALSE 
		invoke	SetDlgItemInt,hWinDialog,ALM_HOUR2,dwHour2,FALSE 
		invoke	SetDlgItemInt,hWinDialog,ALM_MIN2,dwMinute2,FALSE 
 
		test	dwTempFlag,F_REPORT 
		.if	ZERO? 
			call	_DisableReport 
		.else 
			call	_EnableReport 
			test	dwTempFlag,F_REPORT_MODE 
			.if	!ZERO? 
				call	_CheckReport1 
			.else 
				call	_CheckReport2 
			.endif 
		.endif 
 
		test	dwTempFlag,F_ALARM 
		.if	ZERO? 
			call	_DisableAlarm 
		.else 
			call	_EnableAlarm 
			test	dwTempFlag,F_ALARM_ONCE 
			.if	ZERO? 
				invoke	_CheckItem,CHK_ONCE,0 
			.else 
				invoke	_CheckItem,CHK_ONCE,1 
			.endif 
 
			test	dwTempFlag,F_TIME_MODE 
			.if	!ZERO? 
				call	_CheckTime1 
			.else 
				call	_CheckTime2 
			.endif 
 
			mov	eax,dwTempFlag 
			and	eax,F_ALARM_MODE 
			shr	eax,F_ALARM_MODE_ 
			.if	eax == 0000h 
				call	_CheckAlarm1 
			.elseif	eax == 0001h 
				call	_CheckAlarm2 
			.elseif	eax == 0002h 
				call	_CheckAlarm3 
			.elseif	eax == 0003h 
				call	_CheckAlarm4 
			.endif 
		.endif 
 
		ret 
 
_FreshSetupDialog	endp 
;******************************************************************** 
;	校验输入的时间是否正确 
;******************************************************************** 
_CheckSetupTime		proc 
		local	@dwTemp:DWORD 
 
		invoke	GetDlgItemInt,hWinDialog,ALM_HOUR1,addr @dwTemp,FALSE 
		.if	eax > 23 
			mov	eax,23 
		.endif 
		mov	dwHour1,eax 
		invoke	GetDlgItemInt,hWinDialog,ALM_HOUR2,addr @dwTemp,FALSE 
		.if	eax > 23 
			mov	eax,23 
		.endif 
		mov	dwHour2,eax 
		invoke	GetDlgItemInt,hWinDialog,ALM_MIN1,addr @dwTemp,FALSE 
		.if	eax > 59 
			mov	eax,59 
		.endif 
		mov	dwMinute1,eax 
		invoke	GetDlgItemInt,hWinDialog,ALM_MIN2,addr @dwTemp,FALSE 
		.if	eax > 59 
			mov	eax,59 
		.endif 
		mov	dwMinute2,eax 
		ret 
 
_CheckSetupTime		endp 
;******************************************************************** 
;	闹钟设置对话框的命令处理程序 
;	根据子控件设置相应的标志位 
;******************************************************************** 
_AlarmSetupCommand	proc	hWnd:DWORD,wParam:DWORD,lParam:DWORD 
 
		mov	eax,wParam 
		.if	eax ==	ID_SETUP_OK 
			call	_ApplyAlarmSetup 
			invoke	EndDialog,hWinDialog,NULL 
		.elseif eax ==	ID_SETUP_APPLY 
			call	_ApplyAlarmSetup 
		.elseif eax ==	ID_SETUP_CANCEL 
			invoke	EndDialog,hWinDialog,NULL 
;**************** 启用整点报时 ************************************** 
		.elseif	eax ==	CHK_REPORT 
			invoke	SendMessage,lParam,BM_GETCHECK,0,0 
			.if	eax == TRUE 
				or	dwTempFlag,F_REPORT 
			.else 
				and	dwTempFlag,not F_REPORT 
			.endif 
;**************** 启用闹铃功能 ************************************** 
		.elseif	eax ==	CHK_ALARM 
			invoke	SendMessage,lParam,BM_GETCHECK,0,0 
			.if	eax == TRUE 
				or	dwTempFlag,F_ALARM 
			.else 
				and	dwTempFlag,not F_ALARM 
			.endif 
;**************** 闹铃一次后关闭 ************************************ 
		.elseif	eax ==	CHK_ONCE 
			invoke	SendMessage,lParam,BM_GETCHECK,0,0 
			.if	eax == TRUE 
				or	dwTempFlag,F_ALARM_ONCE 
			.else 
				and	dwTempFlag,not F_ALARM_ONCE 
			.endif 
;**************** 标准报时声音 ************************************** 
		.elseif	eax ==	REP_WAV1 
			mov	eax,F_REPORT_MODE 
			or	dwTempFlag,eax 
;**************** 指定报时声音 ************************************** 
		.elseif	eax ==	REP_WAV2 
			and	dwTempFlag,not F_REPORT_MODE 
;**************** 绝对时间 ****************************************** 
		.elseif	eax ==	ALM_TIME 
			mov	eax,F_TIME_MODE 
			or	dwTempFlag,eax 
;**************** 相对时间 ****************************************** 
		.elseif	eax ==	ALM_FROMNOW 
			and	dwTempFlag,not F_TIME_MODE 
;**************** 标准闹铃声音 ************************************** 
		.elseif	eax == ALM_WAV1 
			and	dwTempFlag,not F_ALARM_MODE 
			or	dwTempFlag,000000000000b 
;**************** 指定闹铃声音 ************************************** 
		.elseif	eax == ALM_WAV2 
			and	dwTempFlag,not F_ALARM_MODE 
			or	dwTempFlag,000100000000b 
;**************** 到时候显示对话框 ********************************** 
		.elseif	eax == ALM_MSG 
			and	dwTempFlag,not F_ALARM_MODE 
			or	dwTempFlag,001000000000b 
;**************** 到时候关闭计算机 ********************************** 
		.elseif	eax == ALM_SHUTDOWN 
			and	dwTempFlag,not F_ALARM_MODE 
			or	dwTempFlag,001100000000b 
;**************** 声音预览 ****************************************** 
		.elseif	eax == REP_PLAY1 
			invoke	PlaySound,IDW_SOUND,hInstance,SND_RESOURCE or SND_ASYNC 
		.elseif	eax == REP_PLAY2 
			invoke	_GetRegKeySz,addr szKeyName,addr szKeyReportFile,addr szBuffer,255 
			invoke	PlaySound,addr szBuffer,NULL,SND_FILENAME or SND_ASYNC 
		.elseif	eax == ALM_PLAY1 
			invoke	PlaySound,IDW_SOUND,hInstance,SND_RESOURCE or SND_ASYNC 
		.elseif	eax == ALM_PLAY2 
			invoke	_GetRegKeySz,addr szKeyName,addr szKeyAlarmFile,addr szBuffer,255 
			invoke	PlaySound,addr szBuffer,NULL,SND_FILENAME or SND_ASYNC 
;**************** 声音文件浏览打开 *********************************** 
		.elseif	eax == REP_BROWSE 
			invoke	GetDlgItemText,hWinDialog,REP_FILE,offset szBuffer,255 
			mov	stOpenFile.Flags,OFN_FILEMUSTEXIST 
			mov	stOpenFile.lStructSize,SIZEOF stOpenFile 
			mov	eax,hWinDialog 
			mov	stOpenFile.hWndOwner,eax 
			mov	stOpenFile.lpstrFilter,offset szFilter 
			mov	stOpenFile.lpstrFile,offset szBuffer 
			mov	stOpenFile.nMaxFile,255 
			mov	stOpenFile.lpstrInitialDir,0 
			mov	stOpenFile.lpstrTitle,offset szTitleOpen 
			mov	stOpenFile.lpstrDefExt,offset szExt 
			invoke	GetOpenFileName,addr stOpenFile 
			.if	eax != FALSE 
				invoke	SetDlgItemText,hWinDialog,REP_FILE,offset szBuffer 
				invoke	_SetRegKeySz,addr szKeyName,\ 
					addr szKeyReportFile,addr szBuffer,255 
			.endif 
		.elseif	eax == ALM_BROWSE 
			invoke	GetDlgItemText,hWinDialog,ALM_FILE,offset szBuffer,255 
			mov	stOpenFile.Flags,OFN_FILEMUSTEXIST 
			mov	stOpenFile.lStructSize,SIZEOF stOpenFile 
			mov	eax,hWinDialog 
			mov	stOpenFile.hWndOwner,eax 
			mov	stOpenFile.lpstrFilter,offset szFilter 
			mov	stOpenFile.lpstrFile,offset szBuffer 
			mov	stOpenFile.nMaxFile,255 
			mov	stOpenFile.lpstrInitialDir,0 
			mov	stOpenFile.lpstrTitle,offset szTitleOpen 
			mov	stOpenFile.lpstrDefExt,offset szExt 
			invoke	GetOpenFileName,addr stOpenFile 
			.if	eax != FALSE 
				invoke	SetDlgItemText,hWinDialog,ALM_FILE,offset szBuffer 
				invoke	_SetRegKeySz,addr szKeyName,\ 
					addr szKeyAlarmFile,addr szBuffer,255 
			.endif 
		.else 
			ret 
		.endif 
 
		call	_CheckSetupTime 
		call	_FreshSetupDialog 
		ret 
 
_AlarmSetupCommand	endp 
;******************************************************************** 
;	提交设置参数 
;******************************************************************** 
_ApplyAlarmSetup	proc 
 
		call	_CheckSetupTime		;校验时间输入是否正确 
 
		mov	eax,dwTempFlag		;提交标志 
;		mov	ebx,001003f0h 
;		and	eax,ebx 
;		not	ebx 
;		and	dwFlag,ebx 
;		or	dwFlag,eax 
		mov	dwFlag,eax 
 
		test	dwFlag,F_TIME_MODE	;将“从现在起”时间计算为“闹铃时间” 
		.if	!ZERO? 
			mov	eax,dwHour1 
			mov	edx,dwMinute1 
			mov	dwAlarmHour,eax 
			mov	dwAlarmMinute,edx 
			invoke	_TimeSub,dwAlarmHour,dwAlarmMinute 
			mov	dwHour2,eax 
			mov	dwMinute2,edx 
		.else 
			invoke	_TimeAdd,dwHour2,dwMinute2 
			mov	dwAlarmHour,eax 
			mov	dwAlarmMinute,edx 
			mov	dwHour1,eax 
			mov	dwMinute1,edx 
		.endif 
		call	_FreshSetupDialog	;刷新屏幕信息 
 
;*************** 保存文本信息到注册表 ******************************* 
		invoke	GetDlgItemText,hWinDialog,REP_FILE,offset szBuffer,255 
		invoke	_SetRegKeySz,addr szKeyName,addr szKeyReportFile,addr szBuffer,255 
		invoke	GetDlgItemText,hWinDialog,ALM_FILE,offset szBuffer,255 
		invoke	_SetRegKeySz,addr szKeyName,addr szKeyAlarmFile,addr szBuffer,255 
		invoke	GetDlgItemText,hWinDialog,ALM_MESSAGE,offset szBuffer,255 
		invoke	_SetRegKeySz,addr szKeyName,addr szKeyAlarmText,addr szBuffer,255 
 
		ret 
 
_ApplyAlarmSetup	endp 
;******************************************************************** 
;	整点报时 
;******************************************************************** 
_ClockReport	proc 
 
		test	dwFlag,F_REPORT_MODE 
		.if	!ZERO? 
			invoke	PlaySound,IDW_SOUND,hInstance,SND_RESOURCE or SND_ASYNC 
		.else 
			invoke	_GetRegKeySz,addr szKeyName,addr szKeyReportFile,addr szBuffer,255 
			.if	szBuffer == 0 
				invoke	PlaySound,IDW_SOUND,hInstance,SND_RESOURCE or SND_ASYNC 
			.else 
				invoke	PlaySound,addr szBuffer,NULL,SND_FILENAME or SND_ASYNC 
			.endif 
		.endif 
		ret 
 
_ClockReport	endp 
;******************************************************************** 
;	闹铃标准声音播放后台线程 
;******************************************************************** 
_AlarmUseWave	proc	uses ebx ecx edx esi edi,\ 
			dwParam:DWORD 
			local	@dwCount 
 
		mov	@dwCount,0 
		.while	@dwCount < 15 
			invoke	Sleep,1000 
			invoke	PlaySound,IDW_SOUND,hInstance,SND_RESOURCE or SND_ASYNC 
			inc	@dwCount 
		.endw 
 
		ret 
 
_AlarmUseWave	endp 
;******************************************************************** 
_AlarmUseStand	proc		;标准声音报时 
 
		invoke	PlaySound,IDW_SOUND,hInstance,SND_RESOURCE or SND_ASYNC 
		.if	eax == FALSE 
			call	_AlarmUseDialog	;如果放声音失败,使用对话框 
		.else 
			invoke	CreateThread,NULL,NULL,offset _AlarmUseWave,\ 
				NULL,NULL,offset hAlarmThread 
		.endif 
		ret 
 
_AlarmUseStand	endp 
;******************************************************************** 
_AlarmUseDialog	proc 
 
		invoke	_GetRegKeySz,addr szKeyName,addr szKeyAlarmText,addr szBuffer,255 
		.if	szBuffer == 0 
			mov	al,3 
			call	_Random 
			add	eax,IDS_0 
			invoke	LoadString,hInstance,eax,offset szBuffer,255 
		.endif 
		invoke	MessageBox,hWinMain,offset szBuffer,\ 
			offset szAlarmTitle,MB_ICONINFORMATION or MB_OK 
		ret 
 
_AlarmUseDialog	endp 
;******************************************************************** 
;	闹铃 
;******************************************************************** 
_ClockAlarm	proc 
 
		mov	eax,dwFlag 
		and	eax,F_ALARM_MODE 
		shr	eax,F_ALARM_MODE_ 
		.if	eax ==	0000h 
			call	_AlarmUseStand 
		.elseif	eax ==	0001h 
			invoke	_GetRegKeySz,addr szKeyName,addr szKeyAlarmFile,addr szBuffer,255 
			.if	szBuffer == 0 
				call	_AlarmUseStand 
			.else 
				invoke	PlaySound,addr szBuffer,NULL,SND_FILENAME or SND_ASYNC 
				.if	eax == FALSE	;如果放声音失败,使用对话框 
					call	_AlarmUseDialog 
				.endif 
			.endif 
		.elseif	eax ==	0002h 
			call	_AlarmUseDialog 
		.elseif	eax ==	0003h 
			invoke	DialogBoxParam,hInstance,DLG_SHUTDOWN,\ 
				hWinMain,offset DialogMainProc,DLG_SHUTDOWN 
		.endif 
		test	dwFlag,F_ALARM_ONCE		;闹铃一次后取消 
		.if	!ZERO? 
			and	dwFlag,not F_ALARM;关闭闹铃功能 
		.endif 
		ret 
 
_ClockAlarm	endp 
;******************************************************************** 
;	外观设置对话框的命令处理程序 
;	根据子控件设置相应的标志位 
;******************************************************************** 
_LookSetupCommand	proc	hWnd:DWORD,wParam:DWORD,lParam:DWORD 
 
		mov	eax,wParam 
		.if	eax ==	ID_LOOK_OK 
			call	_ApplyLookSetup 
			call	_DeleteLookDC 
			invoke	EndDialog,hWinDialog,NULL 
		.elseif eax ==	ID_LOOK_APPLY 
			call	_FreshLookDialog 
			call	_ApplyLookSetup 
		.elseif eax ==	ID_LOOK_CANCEL 
			call	_DeleteLookDC 
			invoke	EndDialog,hWinDialog,NULL 
		.elseif	eax ==	IDL_RNDBACK 
			invoke	SendMessage,lParam,BM_GETCHECK,0,0 
			.if	eax == TRUE 
				or	dwTempFlag,F_RND_BACK 
			.else 
				and	dwTempFlag,not F_RND_BACK 
			.endif 
			call	_FreshLookDialog 
		.elseif	eax ==	IDL_RNDNUMBER 
			invoke	SendMessage,lParam,BM_GETCHECK,0,0 
			.if	eax == TRUE 
				or	dwTempFlag,F_RND_FONT 
			.else 
				and	dwTempFlag,not F_RND_FONT 
			.endif 
			call	_FreshLookDialog 
		.elseif	eax >=	IDL_B01 && eax <= IDL_B08 
			sub	eax,IDL_B01 
			shl	eax,F_BACK_NO_ 
			and	dwTempFlag,not F_BACK_NO 
			or	dwTempFlag,eax 
			call	_FreshLookDialog 
		.elseif	eax >=	IDL_N01 && eax <= IDL_N08 
			sub	eax,IDL_N01 
			shl	eax,F_FONT_NO_ 
			and	dwTempFlag,not F_FONT_NO 
			or	dwTempFlag,eax 
			call	_FreshLookDialog 
		.endif 
		ret 
 
_LookSetupCommand	endp 
;******************************************************************** 
_PaintLookSetupNum	proc hDcDest:DWORD,idBmpSrc:DWORD,dwDestY:DWORD 
		local	@hBmp:DWORD 
 
		invoke	LoadBitmap,hInstance,idBmpSrc 
		mov	@hBmp,eax 
		invoke	SelectObject,hDcTemp,eax 
 
		invoke	BitBlt,hDcDest,0,dwDestY,4,25,\ 
			hDcTemp,11*15,0,SRCCOPY 
		invoke	BitBlt,hDcDest,4,dwDestY,30,25,\ 
			hDcTemp,1*15,0,SRCCOPY 
		invoke	BitBlt,hDcDest,34,dwDestY,8,25,\ 
			hDcTemp,10*15,0,SRCCOPY 
		invoke	BitBlt,hDcDest,42,dwDestY,30,25,\ 
			hDcTemp,3*15,0,SRCCOPY 
		invoke	BitBlt,hDcDest,72,dwDestY,4,25,\ 
			hDcTemp,11*15,0,SRCCOPY 
 
		invoke	DeleteObject,@hBmp 
		ret 
_PaintLookSetupNum	endp 
;******************************************************************** 
_InitLookDialog	proc 
		local	@hDC:DWORD 
		local	@dwCount:DWORD,@dwY 
 
;*************** 建立临时用的标志 *********************************** 
		mov	eax,dwFlag 
;		mov	ebx,0ffc00h 
;		and	eax,ebx 
;		not	ebx 
;		and	dwTempFlag,ebx 
;		or	dwTempFlag,eax 
		mov	dwTempFlag,eax 
;*************** 获取3个图片子控件的窗口句柄 ************************ 
		invoke	GetDlgItem,hWinDialog,IDL_LOOK_PIC1 
		mov	hWinPic1,eax 
		invoke	GetDlgItem,hWinDialog,IDL_LOOK_PIC2 
		mov	hWinPic2,eax 
		invoke	GetDlgItem,hWinDialog,IDL_LOOK_PIC3 
		mov	hWinPic3,eax 
;*************** 建立预览用的 DC 和位图 ***************************** 
		invoke  GetDC,hWinMain 
		mov	@hDC,eax 
		invoke	CreateCompatibleDC,@hDC 
		mov	hDcLook1,eax 
		invoke	CreateCompatibleDC,@hDC 
		mov	hDcLook1Mask,eax 
		invoke	CreateCompatibleDC,@hDC 
		mov	hDcLook2,eax 
		invoke	CreateCompatibleDC,@hDC 
		mov	hDcLook3,eax 
		invoke	CreateCompatibleDC,@hDC 
		mov	hDcTemp,eax 
		invoke	CreateCompatibleBitmap,@hDC,1,1 
		mov	hBmpLook1,eax 
		invoke	CreateCompatibleBitmap,@hDC,1,1 
		mov	hBmpLook1Mask,eax 
		invoke	CreateCompatibleBitmap,@hDC,76,160 
		mov	hBmpLook2,eax 
		invoke	CreateCompatibleBitmap,@hDC,76,160 
		mov	hBmpLook3,eax 
		invoke	ReleaseDC,hWinPic2,@hDC 
 
		invoke	SelectObject,hDcLook2,hBmpLook2 
		invoke  GetStockObject,1 
		invoke  SelectObject,hDcLook2,eax 
		invoke	PatBlt,hDcLook2,0,0,76,160,PATCOPY 
		invoke	SelectObject,hDcLook3,hBmpLook3 
		invoke  GetStockObject,1 
		invoke  SelectObject,hDcLook3,eax 
		invoke	PatBlt,hDcLook3,0,0,76,160,PATCOPY 
;*************** 在字形预览图片上画图 ******************************* 
		mov	@dwCount,0 
		mov	@dwY,0 
		.while	@dwCount < 4 
			mov	eax,@dwCount 
			add	eax,IDB_NUM0 
			invoke	_PaintLookSetupNum,hDcLook2,eax,@dwY 
			inc	@dwCount 
			add	@dwY,40 
		.endw 
 
		mov	@dwCount,0 
		mov	@dwY,0 
		.while	@dwCount < 4 
			mov	eax,@dwCount 
			add	eax,IDB_NUM4 
			invoke	_PaintLookSetupNum,hDcLook3,eax,@dwY 
			inc	@dwCount 
			add	@dwY,40 
		.endw 
 
		call	_FreshLookDialog 
		ret 
 
_InitLookDialog	endp 
;******************************************************************** 
_DeleteLookDC	proc 
 
		invoke	DeleteDC,hDcLook1 
		invoke	DeleteDC,hDcLook1Mask 
		invoke	DeleteDC,hDcLook2 
		invoke	DeleteDC,hDcLook3 
		invoke	DeleteDC,hDcTemp 
		invoke	DeleteDC,hDcLook1 
		invoke	DeleteObject,hBmpLook1 
		invoke	DeleteObject,hBmpLook1Mask 
		invoke	DeleteObject,hBmpLook2 
		invoke	DeleteObject,hBmpLook3 
		ret 
 
_DeleteLookDC	endp 
;******************************************************************** 
_ApplyLookSetup	proc 
		local	@stOldWin:RECT,@stNewWin:RECT,@stDeskTop:RECT 
		local	@dwOldWidth:DWORD,@dwOldHeight:DWORD 
		local	@dwNewWidth:DWORD,@dwNewHeight:DWORD 
 
		mov	eax,dwTempFlag		;提交标志 
;		mov	ebx,0ffc00h 
;		and	eax,ebx 
;		not	ebx 
;		and	dwFlag,ebx 
;		or	dwFlag,eax 
		mov	dwFlag,eax 
 
		invoke	GetDesktopWindow 
		mov	ebx,eax 
		invoke	GetWindowRect,ebx,addr @stDeskTop 
 
		invoke	GetWindowRect,hWinMain,addr @stOldWin 
		mov	eax,@stOldWin.bottom 
		sub	eax,@stOldWin.top 
		mov	@dwOldHeight,eax 
		mov	eax,@stOldWin.right 
		sub	eax,@stOldWin.left 
		mov	@dwOldWidth,eax 
 
		invoke	_DeleteClock 
		invoke	_CreateClock 
 
		invoke	GetWindowRect,hWinMain,addr @stNewWin 
		mov	eax,@stNewWin.bottom 
		sub	eax,@stNewWin.top 
		mov	@dwNewHeight,eax 
		mov	eax,@stNewWin.right 
		sub	eax,@stNewWin.left 
		mov	@dwNewWidth,eax 
;***************** 使时钟始终跟屏幕边对齐 *************************** 
		mov	eax,@stDeskTop.right 
		sub	eax,@stDeskTop.left 
		shr	eax,1 
		mov	ebx,@stDeskTop.bottom 
		sub	ebx,@stDeskTop.top 
		shr	ebx,1 
 
		mov	ecx,@stOldWin.left 
		mov	edx,@stOldWin.top 
		.if	@stOldWin.left >= eax 
			add	ecx,@dwOldWidth 
			sub	ecx,@dwNewWidth 
		.endif 
		.if	@stOldWin.top >= ebx 
			add	edx,@dwOldHeight 
			sub	edx,@dwNewHeight 
		.endif 
 
		invoke	MoveWindow,hWinMain,ecx,edx,@dwNewWidth,@dwNewHeight,FALSE 
		invoke	ShowWindow,hWinMain,SW_SHOW 
		call	_FreshClock 
 
		ret 
 
_ApplyLookSetup	endp 
;******************************************************************** 
_EnableItemLoop	proc	dwStartID:DWORD,dwLoop:DWORD,bFlags:DWORD 
 
		.while	TRUE 
			invoke	_EnableItem,dwStartID,bFlags 
			inc	dwStartID 
			dec	dwLoop 
			.break .if dwLoop == 0 
		.endw 
		ret 
 
_EnableItemLoop	endp 
;******************************************************************** 
_CheckItemLoop	proc	dwStartID:DWORD,dwLoop:DWORD,bFlags:DWORD 
 
		.while	TRUE 
			invoke	_CheckItem,dwStartID,bFlags 
			inc	dwStartID 
			dec	dwLoop 
			.break .if dwLoop == 0 
		.endw 
		ret 
 
_CheckItemLoop	endp 
;******************************************************************** 
_FreshLookDialog	proc 
 
		test	dwTempFlag,F_RND_BACK 
		.if	ZERO? 
;*************** 不允许随机选择背景 ********************************* 
			invoke	_CheckItem,IDL_RNDBACK,0 
			invoke	_EnableItemLoop,IDL_B01,8,TRUE 
			mov	eax,dwTempFlag 
			and	eax,F_BACK_NO 
			shr	eax,F_BACK_NO_ 
			add	eax,IDL_B01 
			invoke	CheckRadioButton,hWinDialog,IDL_B01,IDL_B08,eax 
		.else 
;*************** 随机选择背景 *************************************** 
			invoke	_CheckItem,IDL_RNDBACK,1 
			invoke	_EnableItemLoop,IDL_B01,8,FALSE 
		.endif 
 
		test	dwTempFlag,F_RND_FONT 
		.if	ZERO? 
;*************** 不允许随机选择字形 ********************************* 
			invoke	_CheckItem,IDL_RNDNUMBER,0 
			invoke	_EnableItemLoop,IDL_N01,8,TRUE 
			mov	eax,dwTempFlag 
			and	eax,F_FONT_NO 
			shr	eax,F_FONT_NO_ 
			add	eax,IDL_N01 
			invoke	CheckRadioButton,hWinDialog,IDL_N01,IDL_N08,eax 
		.else 
;*************** 随机选择字形 *************************************** 
			invoke	_CheckItem,IDL_RNDNUMBER,1 
			invoke	_EnableItemLoop,IDL_N01,8,FALSE 
		.endif 
		call	_PaintLookDialog 
		ret 
 
_FreshLookDialog	endp 
;******************************************************************** 
_PaintLookDialog	proc 
		local	@stBmp:BITMAP,@hDC:DWORD 
		local	@hBmpBack:DWORD,@hBmpNum:DWORD 
		local	@dwNumX:DWORD,@dwNumY:DWORD 
		local	@stRect:RECT 
 
;*************** 取得背景图片编号 *********************************** 
		test	dwTempFlag,F_RND_BACK 
		.if	!ZERO? 
			mov	al,3 
			call	_Random 
		.else 
			mov	eax,dwTempFlag 
			and	eax,F_BACK_NO 
			shr	eax,F_BACK_NO_ 
		.endif 
		push	eax 
		add	eax,IDB_0 
		invoke	LoadBitmap,hInstance,eax	;装入背景图片 
		mov	@hBmpBack,eax 
		pop	ebx 
 
		shl	ebx,3			;x 8 
		add	ebx,offset dwOffsetTable 
		mov	eax,[ebx] 
		mov	@dwNumX,eax 
		mov	eax,[ebx+4] 
		mov	@dwNumY,eax 
;*************** 取得数字图片编号 *********************************** 
		test	dwTempFlag,F_RND_FONT 
		.if	!ZERO? 
			mov	al,3 
			call	_Random 
		.else 
			mov	eax,dwTempFlag 
			and	eax,F_FONT_NO 
			shr	eax,F_FONT_NO_ 
		.endif 
		add	eax,IDB_NUM0 
		invoke	LoadBitmap,hInstance,eax	;装入数字图片 
		mov	@hBmpNum,eax 
 
		invoke	GetDC,hWinPic1 
		mov	@hDC,eax 
		invoke	GetObject,@hBmpBack,sizeof BITMAP,addr @stBmp 
;*************** 删除预览1 BMP ************************************* 
		invoke	DeleteObject,hBmpLook1 
		invoke	DeleteObject,hBmpLook1Mask 
;*************** 建立预览1 BMP 和 MASK BMP ************************* 
		invoke	CreateCompatibleBitmap,@hDC,\ 
			@stBmp.bmWidth,@stBmp.bmHeight 
		mov	hBmpLook1,eax 
		invoke	CreateCompatibleBitmap,@hDC,\ 
			@stBmp.bmWidth,@stBmp.bmHeight 
		mov	hBmpLook1Mask,eax 
;*************** 从背景图片拷贝预览 BMP ***************************** 
		invoke	SelectObject,hDcLook1,hBmpLook1 
		invoke	SelectObject,hDcLook1Mask,hBmpLook1Mask 
		invoke	SelectObject,hDcTemp,@hBmpBack 
		invoke	BitBlt,hDcLook1,0,0,\ 
			@stBmp.bmWidth,@stBmp.bmHeight,hDcTemp,0,0,SRCCOPY 
		invoke	BitBlt,hDcLook1Mask,0,0,\ 
			@stBmp.bmWidth,@stBmp.bmHeight,hDcTemp,0,0,SRCCOPY 
		invoke	_CreateMask,hDcLook1Mask,@stBmp.bmWidth,@stBmp.bmHeight 
 
		invoke	SelectObject,hDcTemp,@hBmpNum 
		invoke	_CreateClockPic,hDcLook1,hDcTemp,@dwNumX,@dwNumY 
 
;*************** 刷新预览图片 *************************************** 
		invoke	GetClientRect,hWinPic1,addr @stRect 
		mov	eax,@stRect.right 
		sub	eax,@stRect.left 
		sub	eax,@stBmp.bmWidth 
		shr	eax,1 
		mov	@dwNumX,eax 
		mov	eax,@stRect.bottom 
		sub	eax,@stRect.top 
		sub	eax,@stBmp.bmHeight 
		shr	eax,1 
		mov	@dwNumY,eax 
;*************** 图片去背景 ***************************************** 
		invoke	BitBlt,hDcLook1,0,0,@stBmp.bmWidth,@stBmp.bmHeight,\ 
			hDcLook1Mask,0,0,SRCAND 
		invoke	BitBlt,hDcLook1Mask,0,0,@stBmp.bmWidth,@stBmp.bmHeight,\ 
			hDcLook1Mask,0,0,DSTINVERT 
 
		invoke	InvalidateRect,hWinPic1,NULL,TRUE 
		invoke	UpdateWindow,hWinPic1 
;*************** 背景挖空,准备画图 ********************************* 
		invoke	BitBlt,@hDC,@dwNumX,@dwNumY,@stBmp.bmWidth,@stBmp.bmHeight,\ 
			hDcLook1Mask,0,0,SRCAND 
		invoke	BitBlt,hDcLook1Mask,0,0,@stBmp.bmWidth,@stBmp.bmHeight,\ 
			hDcLook1Mask,0,0,DSTINVERT 
;*************** 更新到屏幕 ***************************************** 
		invoke	BitBlt,@hDC,@dwNumX,@dwNumY,@stBmp.bmWidth,@stBmp.bmHeight,\ 
			hDcLook1,0,0,SRCPAINT 
		invoke	DeleteObject,@hBmpBack 
		invoke	DeleteObject,@hBmpNum 
		invoke	ReleaseDC,hWinPic1,@hDC 
 
		invoke	InvalidateRect,hWinPic2,NULL,TRUE 
		invoke	UpdateWindow,hWinPic2 
		invoke	GetDC,hWinPic2 
		mov	@hDC,eax 
		invoke	BitBlt,@hDC,0,0,76,160,\ 
			hDcLook2,0,0,SRCCOPY 
		invoke	ReleaseDC,hWinPic2,@hDC 
 
		invoke	InvalidateRect,hWinPic3,NULL,TRUE 
		invoke	UpdateWindow,hWinPic3 
		invoke	GetDC,hWinPic3 
		mov	@hDC,eax 
		invoke	BitBlt,@hDC,0,0,76,160,\ 
			hDcLook3,0,0,SRCCOPY 
		invoke	ReleaseDC,hWinPic3,@hDC 
		ret 
 
_PaintLookDialog	endp 
;******************************************************************** 
;	关于对话框中超级连接的窗口程序 
;******************************************************************** 
HyperLinkProc	proc	hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD 
 
		mov	eax,uMsg 
		.if	eax ==	WM_LBUTTONUP 
			invoke	GetDlgCtrlID,hWnd 
			.if	eax ==	ID_HOMEPAGE 
				invoke	ShellExecute,0,0,offset szHomePage,0,0,0 
			.elseif	eax ==	ID_EMAIL 
				invoke	ShellExecute,0,0,offset szEmail,0,0,0 
			.endif 
		.elseif	eax ==	WM_NCHITTEST 
;将 WM_NCHITTEST 返回 TRUE 可以接收鼠标动作,实现按下功能 ! 
		.elseif	eax ==	WM_SETCURSOR 
			invoke	SetCursor,hCursor 
		.else 
			invoke	GetWindowLong,hWnd,GWL_USERDATA 
			invoke	CallWindowProc,eax,hWnd,uMsg,wParam,lParam 
			ret 
		.endif 
		mov	eax,TRUE 
		ret 
 
HyperLinkProc	endp 
;******************************************************************** 
		end	start