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