📄 jacts.asm
字号:
.386
.model flat,stdcall
option casemap:none
;-----------------------------------------------------
;About Joe's Alarm/Countdown Timer/StopWatch!
;Author: farrier jcurran@network-one.com
;Dialog window with the following functions
; Stopwatch with "1/100 sec accuracy" at least that is what is displayed!
; immediate lap times can be displayed briefly without stopping SW
; Countdown Timer (CDT) with drop down box controls for hour, minute, & seconds
; Upper limit 59 Hours, 59 minutes, & 59 seconds
; If Repeat After Countdown checkbox is checked CDT will repeat
; Alarm Clock (AC) using DateTimePicker control to set alarm time and date
;For CDT & AC when time expires, an "alarm" sound is played using
; multimedia playback "PlaySound" API. A file picker control is used to
; allow the user to change the sound played.
;The most recently selected options are saved in a file \Windows\jacts.ini
; When the program runs the next time, that file is used to set the options
; for the current session.
;-----------------------------------------------------
;-----------------------------------------------------
;INCLUDES
;______________________________________
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\shell32.inc ;For GetModuleFileName
include \masm32\include\comctl32.inc ;For DateTimePicker
include \masm32\include\comdlg32.inc ;For GetOpenFileName
include \masm32\include\winmm.inc ;For MultiMedia Playback
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\winmm.lib
;-------------------------------------
;PROTOTYPES
;_____________________________________________
DlgProc PROTO :HWND, :DWORD, :DWORD, :DWORD
dwtoa PROTO :DWORD, :PTR BYTE ;Converts Double to ASCII
populate_lists PROTO ;Populates Hour & Minute Lists
set_ini PROTO :WORD , :HWND ;Interacts with JCT.ini file
start_timer PROTO :HWND
s_length PROTO :PTR BYTE ;String length returned
update_display PROTO :HWND ;Updates dialog box display
;---------------------------------------------
;CONSTANTS
;_____________________________________________
.CONST
timer_num equ 10 ;identifier for timer as used by SetTimer
IDC_CDTB equ 106 ;identifier for CountDownTimerButton
IDC_AB equ 108 ;identifier for AlarmButton
IDC_SW equ 109 ;identifier for StopWatch button
IDC_RAB equ 111 ;identifier for RepeatAfter countdown button
IDC_SC equ 116 ;identifier for Countdown Seconds
IDC_HC equ 117 ;identifier for Countdown Hours
IDC_MC equ 118 ;identifier for Countdown Minutes
IDC_PICK equ 119 ;identifier for PICK sound button
IDC_START equ 121 ;identifier for START button
IDC_CANCEL equ 122 ;identifier for CANCEL button
IDC_STOP equ 123 ;identifier for STOP button
IDC_LAP equ 124 ;identifier for LAP button
IDI_CLOCK equ 132
IDC_START_DATE equ 3004 ;identifier for alram time/date button
;----------------------------------------------------------------------------------
;INITIALIZED DATA
;__________________________________________________________________________________
.DATA
AppName db "Joe's Alarm/Countdown Timer/StopWatch!", 0
DlgName db "MyDialog", 0
IDStr db "Joe's Alarm/Countdown Timer/StopWatch (c) 2000-2001 MASM32", 13, 10
hStr db "Hours:01", 13, 10 ;initial hours string
mStr db "Minutes:30", 13, 10 ;initial minutes string
sStr db "Seconds:00", 13, 10 ;initial seconds string
ACorR db "ACorR:A", 13, 10 ;initial Alarm,Countdown,Repeat,stopwatch choice
wStr db "Wav:"
initial_wav_name db "\MEDIA\THE MICROSOFT SOUND.WAV", 0 ;initial sound file
w_buffer db MAX_PATH - sizeof initial_wav_name dup(0) ;place holder to reserve space for a MAX_PATH sized event/file name
lib_name db "\comctl32.dll", 0 ;library for DateTimePicker
dgv db "DllGetVersion", 0 ;function to check version of DLL
lib_err db "This Program Requires Version 4.70 of COMCTL32.DLL!", 0 ;warning message
ini_nom db "No match with the existing " ;warning if existing JCTA.ini is not ours?
JACTS_Name db "\JACTS.INI", 0 ;name of our .ini file
DateFormat db "hh':'mm' 'tt' 'ddd' 'dd' 'MMMM' 'yyyy", 0 ;Format for Time/Date in DateTimePicker
date_error db "Starting Date/Time Cannot be The Same as or Prior to Current Date/Time!", 0
;Warning that Alarm time cannot be at or before current time
time_up db "The Timer has expired!", 0 ;MessageBox prompt when timer has expired
nocdt db "There is No time on Countdown Timer!", 0 ;MessageBox prompt when Hours & Minutes are both zero for Countdown Timer
OurTitle db "Pick a WAV File for Your Alarm Sound!", 0 ;Title for file dialog for Pick Sound
FilterString db "WAV Files", 0, "*.wav", 0 ;Template for file dialog
db "All Files", 0, "*.*", 0, 0 ;" "
hour_str db " :Hours" ;Strings for time display
minute_str db " :Minutes" ;" "
second_str db " :Seconds" ;" "
msec_str db " :mSecs" ;" "
end_string db 0 ;zero to terminate display string
p_cnt db 0 ;used for timer to delay lap time display
;-------------------------------------------------------------------------------------------
;UNINITIALIZED DATA
;___________________________________________________________________________________________
.DATA?
hInstance HINSTANCE ?
lib_handle HWND ? ;Handle to check for dll version
ab_handle HWND ? ;Handle for alarm button window
cdtb_handle HWND ? ;Handle for count down timer button window
sw_handle HWND ? ;Handle for stopwatch button window
hc_handle HWND ? ;Handle for Hour combo box window
mc_handle HWND ? ;Handle for Minute combo box window
sc_handle HWND ? ;Handle for Second combo box window
rab_handle HWND ? ;Handle for repeat after countdown timer checkbox window
sdc_handle HWND ? ;Hanlde for startdate control window
start_handle HWND ? ;Handle for Start button
cancel_handle HWND ? ;Handle for Cancel button
stop_handle HWND ? ;Handle for Stop button
lap_handle HWND ? ;Handle for Lap button
stat_handle HWND ? ;Handle for Status bar
timer_handle HWND ? ;Handle used to reference the timer
dvi DLLVERSIONINFO <> ;Structure for Dll Version Info
ofn OPENFILENAME <> ;Structure for selecting WAV file
system_time SYSTEMTIME <> ;used to gather current time
alarm_time FILETIME <> ;used to keep next alarm time
time_now FILETIME <> ;used to gather current time
tseconds FILETIME <> ;used to store seconds left till alarm
icex INITCOMMONCONTROLSEX <> ;structure for DateTimePicker
proc_add DWORD ? ;used to store address for DLL
def_hours DWORD ? ;used to set initial value of CD Hours
def_mins DWORD ? ;used to set initial value of CD Minutes
def_secs DWORD ? ;used to set initial value of CD Seconds
repeat_mins DWORD ? ;store countdown minutes for repeat
repeat_secs DWORD ? ;store countdown minutes for repeat
hc_str WORD ? ;2 bytes for the hour control
mc_str WORD ? ;2 bytes for the minute control
sc_str WORD ? ;2 bytes for the second control
newcw WORD ? ;storage for the updated fpu control word
oldcw WORD ? ;storage for the old FPU control word
def_acorr BYTE ? ;Is the Alarm,Countdown,or Repeat After button pushed
mb_up BYTE ? ;Is MessageBox already up, don't repeat MessageBox is RepeatAfterCountdown
d_buffer BYTE MAX_PATH + 1 dup (?) ;allows us to read MAX filename size and 0
WindowsDir db MAX_PATH dup(?)
wav_name db MAX_PATH dup(?)
iniFileName db MAX_PATH dup(?)
;-----------------------------------------------------
;CODE
;_____________________________________________________
.CODE
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
;===========================================
; obtain the windows directory
;===========================================
invoke GetWindowsDirectory, addr WindowsDir, sizeof WindowsDir
invoke lstrcpy, addr wav_name, addr WindowsDir
invoke lstrcat, addr wav_name, addr initial_wav_name
invoke lstrcpy, addr iniFileName, addr WindowsDir
invoke lstrcat, addr iniFileName, addr JACTS_Name
invoke GetSystemDirectory, addr d_buffer, sizeof d_buffer
invoke lstrcat, addr d_buffer, addr lib_name
invoke LoadLibrary, addr d_buffer
;Load comctl32.dll to see if we have at least version 4.70
mov lib_handle, eax ;save handle
.if (eax == NULL) ;no valid handle returned
invoke MessageBox, NULL, addr lib_err, NULL, MB_OK
invoke ExitProcess, -1
ret
.endif
invoke GetProcAddress, lib_handle, addr dgv
;get address of DllGetVersion within comctl32.dll
mov proc_add, eax
.if (eax == NULL) ;no valid address to Proc returned
invoke MessageBox, NULL, addr lib_err, NULL, MB_OK
invoke FreeLibrary, lib_handle
invoke ExitProcess, -1
ret
.endif
invoke RtlZeroMemory, addr dvi, sizeof DLLVERSIONINFO
;set DLLVERSIONINFO Stru to zeroes
mov dvi.cbSize, sizeof DLLVERSIONINFO
push OFFSET dvi ;push structure address for DLLGetVersion
call proc_add ;call COMCTL32.DLL's DllGetVersion routine
cmp dvi.dwMajorVersion, 4 ;major version should be at least 4
jae @F
invoke MessageBox, NULL, addr lib_err, NULL, MB_OK
invoke FreeLibrary, lib_handle
invoke ExitProcess, -1
ret
@@: cmp dvi.dwMinorVersion, 70 ;minor version should be at least 70
jae @F
invoke MessageBox, NULL, addr lib_err, NULL, MB_OK
invoke FreeLibrary, lib_handle
invoke ExitProcess, -1
ret
@@:
mov icex.dwSize, sizeof INITCOMMONCONTROLSEX ;prepare common control structure
mov icex.dwICC, ICC_DATE_CLASSES
invoke InitCommonControlsEx, addr icex
;initialize common controls for DateTimePicker
finit ;initialize FPU
fstcw oldcw ;get current FPU control register & save for later
fwait
mov ax, oldcw ;move it to ax
and ax, 0f3ffh ;make sure the 2 rounding bits are zero
or ax, 0400h ;set the rounding down bit
mov newcw, ax ;save this new setting set in next command
fldcw newcw ;set FPU control register to round down
invoke DialogBoxParam, hInstance, addr DlgName, NULL, addr DlgProc, NULL
;start the program
fldcw oldcw ;restore old control register
invoke FreeLibrary, lib_handle
invoke ExitProcess, 1
;-----------------------------------------------------
DlgProc PROC hWnd:HWND,iMsg:DWORD,wParam:WPARAM, lParam:LPARAM
;______________________________________________________________
LOCAL is_zero:BYTE
LOCAL icon_r:WORD
.if (iMsg == WM_INITDIALOG) ;initialize dialog elements
invoke GetModuleFileName, NULL, addr WindowsDir, icon_r
invoke ExtractIcon, hWnd, addr WindowsDir, 0
push eax
invoke SendMessage, hWnd, WM_SETICON, ICON_SMALL, eax
pop eax
invoke SendMessage, hWnd, WM_SETICON, ICON_BIG, eax
mov mb_up, 0 ;to keep track whether a MessageBox is currently 'up'
invoke CreateStatusWindow, WS_CHILD or WS_VISIBLE, NULL, hWnd, NULL
;create status window at bottom of dialog box
mov stat_handle, eax ;get & save handles for controls
invoke GetDlgItem, hWnd, IDC_AB ;AlarmButton
mov ab_handle, eax
invoke GetDlgItem, hWnd, IDC_CDTB ;CountDownTimer
mov cdtb_handle, eax
invoke GetDlgItem, hWnd, IDC_SW ;StopWatch
mov sw_handle, eax
invoke GetDlgItem, hWnd, IDC_RAB ;RepeatAfterButton
mov rab_handle, eax
invoke GetDlgItem, hWnd, IDC_START_DATE ;DateTimePicker Control
mov sdc_handle, eax
invoke GetDlgItem, hWnd, IDC_START ;START button
mov start_handle, eax
invoke GetDlgItem, hWnd, IDC_CANCEL ;CANCEL button
mov cancel_handle, eax
invoke GetDlgItem, hWnd, IDC_STOP ;STOP button
mov stop_handle, eax
invoke GetDlgItem, hWnd, IDC_LAP ;LAP button
mov lap_handle, eax
invoke GetDlgItem, hWnd, IDC_MC ;MinutesCountdown
mov mc_handle, eax
invoke GetDlgItem, hWnd, IDC_HC ;HoursCountdown
mov hc_handle, eax
invoke GetDlgItem, hWnd, IDC_SC ;SecondsCountdown
mov sc_handle, eax
invoke SendMessage, sdc_handle, DTM_SETFORMAT, NULL, addr DateFormat
;set format of DateTime control to string in DateFormat
invoke ShowWindow, stop_handle, SW_HIDE ;hide Stop button until needed
invoke ShowWindow, lap_handle, SW_HIDE ;hide Lap button until needed
invoke populate_lists ;Set up Hour & Minute list
invoke set_ini, 0, hWnd ;Read in previous settings
invoke SendMessage, hc_handle, CB_SETCURSEL, def_hours, 0
;set hour control to setting from last use
invoke SendMessage, mc_handle, CB_SETCURSEL, def_mins, 0
;set minute control to setting from last use
invoke SendMessage, sc_handle, CB_SETCURSEL, def_secs, 0
;set second control to setting from last use
.if (def_acorr == 'A') ;enable alarm function if set from last use
invoke SendMessage, ab_handle, BM_CLICK, 0, 0 ;click the Alarm button
invoke EnableWindow, rab_handle, FALSE ;disable repeat after checkbox
invoke EnableWindow, sc_handle, FALSE ;disable second listbox
invoke EnableWindow, mc_handle, FALSE ;disable minute listbox
invoke EnableWindow, hc_handle, FALSE ;disable hour listbox
invoke SetFocus, sdc_handle ;set focus to DateTime control
.elseif (def_acorr == 'S') ;enable stopwatch function is set from last use
invoke SendMessage, sw_handle, BM_CLICK, 0, 0 ;click the Stopwatch button
invoke EnableWindow, sdc_handle, FALSE ;disable DateTime Control
invoke EnableWindow, rab_handle, FALSE ;disable Repeat After checkbox
invoke EnableWindow, sc_handle, FALSE ;disable second listbox
invoke EnableWindow, mc_handle, FALSE ;disable minute listbox
invoke EnableWindow, hc_handle, FALSE ;disable hour listbox
.else ;enable Countdown Timer is set from last use
.if (def_acorr == 'R')
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -