Thanks, this is another countdown timer script from my archive that I use frequently:
Code: Select all
; http://www.autohotkey.com/forum/topic71384.html
; Multiple CountDown Timer Utility
; SmartCountDownTimer.ahk - Multiple Countdown timer with sound alerts
; Tested with AutoHotkey 1.0.92.02
path := "C:\...\Sound Effects"
#SingleInstance Off ; Allow multiple instances
#NoTrayIcon
#NoEnv
cd_IniFile := A_ScriptDir "\CountDown.ini"
; Read settings from INI file
IniRead cd_Duration, %cd_IniFile%, Main, Duration, %A_Space%
IniRead cd_PlaySound, %cd_IniFile%, Main, PlaySound, %True%
IniRead cd_SoundFile, %cd_IniFile%, Main, SoundFile, %A_ScriptDir%\
gui, font, s18, Arial, cBlack, w700
Gui, Color , 00FFFF, 00FFFF
; Generated using SmartGUI Creator 4.0
Gui, Add, Text, cBlack x30 y5 w100 h40;h30 , Message:
Gui, Add, Edit, cBlack x30 y35 w415;w430 h40;h30 vcd_Message,
Gui, Add, Text, cBlack x30 y80 w100 h40 , &Hours:
Gui, Add, Edit, cBlack x30 y110 w98 h40 Number vcd_HoursEdit gTimeEdited, % cd_Duration // 3600
Gui, Add, Text, cBlack x130 y80 w100 h40 , &Minutes:
Gui, Add, Edit, cBlack x130 y110 w98 h40 Number vcd_MinutesEdit gTimeEdited, % mod(cd_Duration, 3600) // 60
Gui, Add, Text, cBlack x230 y80 w100 h40 , S&econds:
Gui, Add, Edit, cBlack x230 y110 w100;w98 h40 Number vcd_SecondsEdit gTimeEdited, % mod(cd_Duration, 60)
Gui, Add, Text, cBlack x30 y166 w415;w410 h40 vcd_DurationText,
Gui, Add, Checkbox, x30 y200 w450 h40 vcd_PlaySoundCheckBox, &Play sound at the end of countdown
GuiControl,, cd_PlaySoundCheckBox, %cd_PlaySound%
Gui, Add, Button, x30 y256 w150 h40;h42 gSoundFileBrowse, Sound &file:
Gui, Add, Edit, cBlack x30 y316 w415 h40 vcd_SoundFileEdit, %cd_SoundFile%
Gui, Add, Button, x375.5;x255 y256 w70 h40;h42 gPlayFinishSound, &Test
Gui, Add, Button, x30 y380 w415 h40;h50 vcd_Button gCountDownPress Default, &Start (Press Enter)
Gui, Add, Text, x30 y440;y450 w415;w430 h40;h50, Alt+c for another timer. Esc to close
Gosub TimeEdited
Gui, Show, x131 y91 h500 w472, CountDown
Gui +LastFound
cd_Gui := WinExist() ; Remember Gui window ID
Return
CountDownPress:
GuiControlGet yourmessage,, Edit1
; msgbox your message is %yourmessage%
GuiControlGet cd_ButtonCaption,, cd_Button
if cd_ButtonCaption = &STOP ; Compare button text
{
SetTimer CountDownTimer, Off
WinSetTitle ahk_id %cd_Gui%,, CountDown
GuiControl,, cd_Button, &START
Return
}
cd_Duration := GetDurationInSec()
if cd_Duration <= 0
{
MsgBox 16, Error, Invalid time.
Return
}
WinSetTitle ahk_id %cd_Gui%,, %cd_Duration% (%yourmessage%) ; Refresh tray button text
GuiControl,, cd_Button, &STOP
SetTimer CountDownTimer, 1000
WinMinimize, A
Return
CountDownTimer:
GuiControlGet yourmessage,, Edit1
cd_Duration--
;WinSetTitle ahk_id %cd_Gui%,, %cd_Duration% (%yourmessage%) ; Refresh tray button text
;WinSetTitle ahk_id %cd_Gui%,, %cd_Duration% (Seconds) ; Refresh tray button text
r:=secsToStr(cd_Duration) ; Added 01/21/20
WinSetTitle ahk_id %cd_Gui%,, %r% << Remaining Time ; Refresh tray button text
if cd_Duration > 0
Return
SoundPlay, %path%\alarm_clock.wav ; <<<<<<<<<<
yourmessage = %yourmessage% (Click me to dismiss)
NotifyID := Notify("Countdown Completed!",yourmessage,0) ; = lasts until clicked
Sleep, 5000
Loop, 10
{
; SoundBeep, 2300, 1000 ; 100
}
;MsgBox, 4128, Countdown, Countdown Completed! ; On top. No sound. Icon (info)
;MsgBox, 32, Countdown, Countdown Completed! ; Not on top. No sound. Icon (info)
MsgBox, 262208, Countdown, Countdown Completed! ; On top. Sound. Icon (info)
;MsgBox, 262144, Countdown, Countdown Completed! ; On top. Sound
Reload
;ExitApp
Gui Flash ; Flash the tray button
GuiControlGet cd_PlaySound,, cd_PlaySoundCheckBox
if cd_PlaySound ; Play sound if checked
Gosub PlayFinishSound ; Let me hear that sound!
Gosub CountDownPress
Return
SoundFileBrowse:
FileSelectFile cd_SoundFile, 1, %cd_SoundFile% ; Open file selection dialog
if cd_SoundFile
GuiControl,, cd_SoundFileEdit, %cd_SoundFile%
Return
PlayFinishSound:
GuiControlGet cd_SoundFile,, cd_SoundFileEdit ; Get filename
IfExist %cd_SoundFile%
SoundPlay %cd_SoundFile%
Return
TimeEdited: ; Update duration text
GuiControl,, cd_DurationText, % "Duration: " GetDurationInSec() " seconds"
Return
GetDurationInSec()
{
local Hours, Minutes, Seconds
GuiControlGet Hours,, cd_HoursEdit
if ! Hours
Hours := 0
GuiControlGet Minutes,, cd_MinutesEdit
if ! Minutes
Minutes := 0
GuiControlGet Seconds,, cd_SecondsEdit
if ! Seconds
Seconds := 0
Return Hours * 3600 + Minutes * 60 + Seconds
}
!c::
; WinActivate ahk_id %cd_Gui%
; Run, %A_ScriptDir%\SmartCountDownTimer.exe
Run, G:\Documents and Settings\NA\My Documents\AutoHotkey\Multiple CountDown Timer.ahk
; Run %comspec% /c %A_ScriptDir%\SmartCountDownTimer.exe
Return
GuiEscape:
GuiClose: ; Close window, save settings to INI file
GuiControlGet cd_PlaySound,, cd_PlaySoundCheckBox
GuiControlGet cd_SoundFile,, cd_SoundFileEdit
IniWrite % GetDurationInSec(), %cd_IniFile%, Main, Duration
IniWrite %cd_PlaySound%, %cd_IniFile%, Main, PlaySound
IniWrite %cd_SoundFile%, %cd_IniFile%, Main, SoundFile
Gui, Submit ; Save each control's contents to its associated variable.
ExitApp ; Exit from script
Return
;
; Notify() 0.45 made by gwarble - sept 09
; multiple tray area notifications
; thanks to Rhys/engunneer/HugoV/Forum Posters
;
; Notify([Title,Message,Duration,Options,Image])
;
; Title [!!!] "" to omit title line
; Message [] "" to omit message line
; Duration [15] seconds to show notification
; 0 to flash until clicked
; <0 to ExitApp on click/timeout
; "-0" for permanent and exitOnClick
; Options string of options... see function
; [SI=999 GC=Blue...] most options are remembered (static)
; "Reset" to restore default options
; if you want to show as well, use NO=Reset
; "Wait" to wait for a notification ***
; Image [] Image file name/library or
; number of icon in shell32.dll
; Gui Number to "Wait" for ***
;
; Return Gui Number used ***
; 0 if failed (too many open)
;
Notify(Title="Time's up !",Message="Time's up ! - Click me to dismiss",Duration=30,Options="",Image="")
{
Static ; Options string: "TS=12 GC=Blue..."
static GF := 50 ; Gui First Number ; = override Gui: # used
static GL := 74 ; Gui Last Number ; = between GF and GL
static GC := "FFFFAA" ; Gui Color ; ie: don't use GF<=Gui#<=GL
static GR := 9 ; Gui Radius ; elsewhere in your script
static GT := "Off" ; Gui Transparency
static TS := 14 ; Title Font Size
static TW := 625 ; Title Font Weight
static TC := "Black" ; Title Font Color
static TF := "Lucida Console" ; Title Font Face
static MS := 14 ; Message Font Size
static MW := 550 ; Message Font Weight
static MC := "Black" ; Message Font Color
static MF := "Lucida Console" ; Message Font Face
static BC := "000000" ; Border Colors
static BW := 2 ; Border Width/Thickness
static BR := 13 ; Border Radius
static BT := 105 ; Border Transpacency
static BF := 150 ; Border Flash Speed
static SI := 350 ; Speed In (AnimateWindow)
static SC := 100 ; Speed Clicked (AnimateWindow)
static ST := 450 ; Speed TimeOut (AnimateWindow)
static IW := 32 ; Image Width
static IH := 32 ; Image Height
static IN := 0 ; Image Icon Number (from Image)
static AX := 0 ; Action X Close Button (maybe add yes/no ok/cancel, etc...)
local AC, AT ; Actions Clicked/Timeout
local _Notify_Action, ImageOptions, GY, OtherY
_Notify_:
local NO := 0 ; NO is Notify Option [NO=Reset]
If (Options)
{
IfInString, Options, =
{
Loop,Parse,Options,%A_Space%
If (Option:= SubStr(A_LoopField,1,2))
%Option%:= SubStr(A_LoopField,4)
If NO = Reset
{
Options := "GF=50 GL=74 GC=FFFFAA GR=9 GT=Off "
. "TS=8 TW=625 TC=Black TF=Arial MS=8 MW=550 MC=Black MF=Arial "
. "BC=Black BW=2 BR=9 BT=105 BF=150 SC=300 SI=250 ST=100 "
. "IW=32 IH=32 IN=0"
Goto, _Notify_
}
}
Else If Options = Wait
Goto, _Notify_Wait_
}
GN := GF
Loop
IfNotInString, NotifyList, % "|" GN
Break
Else
If (++GN > GL)
Return 0 ; too many notifications open!
NotifyList .= "|" GN
GN2 := GN + GL - GF + 1
If AC <>
ActionList .= "|" GN "=" AC
Prev_DetectHiddenWindows := A_DetectHiddenWindows
Prev_TitleMatchMode := A_TitleMatchMode
DetectHiddenWindows On
SetTitleMatchMode 1
If (WinExist("NotifyGui")) ; find all Notifications from ALL scripts, for placement
WinGetPos, OtherX, OtherY ; change this to a loop for all open notifications?
DetectHiddenWindows %Prev_DetectHiddenWindows%
SetTitleMatchMode %Prev_TitleMatchMode%
Gui, %GN%:-Caption +ToolWindow +AlwaysOnTop -Border
Gui, %GN%:Color, %GC%
Gui, %GN%:Font, w%TW% s%TS% c%TC%, %TF%
If (Image)
{
If FileExist(Image)
Gui, %GN%:Add, Picture, w%IW% h%IH% Icon%IN%, % Image
Else
Gui, %GN%:Add, Picture, w%IW% h%IH% Icon%Image%, c:\windows\system32\shell32.dll
ImageOptions = x+10
}
If Title <>
Gui, %GN%:Add, Text, % ImageOptions, % Title
Gui, %GN%:Font, w%MW% s%MS% c%MC%, %MF%
If ((Title) && (Message))
Gui, %GN%:Margin, , -5
If Message <>
Gui, %GN%:Add, Text,, % Message
If ((Title) && (Message))
Gui, %GN%:Margin, , 8
Gui, %GN%:Show, Hide, NotifyGui
Gui %GN%:+LastFound
WinGetPos, GX, GY, GW, GH
If AX =
{
GW += 10
Gui, %GN%:Font, w800 s6 c%MC%
Gui, %GN%:Add, Text, % "x" GW-11 " y-1 Border Center w12 h12 g_Notify_Kill_" GN - GF + 1, X
}
Gui, %GN%:Add, Text, x0 y0 w%GW% h%GH% g_Notify_Action BackgroundTrans
If (GR)
WinSet, Region, % "0-0 w" GW " h" GH " R" GR "-" GR
If (GT)
WinSet, Transparent, % GT
SysGet, Workspace, MonitorWorkArea
NewX := WorkSpaceRight-GW-5
If (OtherY)
NewY := OtherY-GH-5
Else
NewY := WorkspaceBottom-GH-5
If NewY < % WorkspaceTop
NewY := WorkspaceBottom-GH-5
Gui, %GN2%:-Caption +ToolWindow +AlwaysOnTop -Border +E0x20
Gui, %GN2%:Color, %BC%
Gui %GN2%:+LastFound
If (BR)
WinSet, Region, % "0-0 w" GW+(BW*2) " h" GH+(BW*2) " R" BR "-" BR
If (BT)
WinSet, Transparent, % BT
Gui, %GN2%:Show, % "Hide x" NewX-BW " y" NewY-BW " w" GW+(BW*2) " h" GH+(BW*2)
Gui, %GN%:Show, % "Hide x" NewX " y" NewY " w" GW, NotifyGui
Gui %GN%:+LastFound
If SI
DllCall("AnimateWindow","UInt",WinExist(),"Int",SI,"UInt","0x00040008")
Else
Gui, %GN%:Show, NA, NotifyGui
Gui, %GN2%:Show, NA
WinSet, AlwaysOnTop, On
If ((Duration < 0) OR (Duration = "-0"))
Exit := GN
If (Duration)
SetTimer, % "_Notify_Kill_" GN - GF + 1, % - Abs(Duration) * 1000
Else
SetTimer, % "_Notify_Flash_" GN - GF + 1, % BF
Return % GN
; when a notification is clicked:
_Notify_Action:
; Critical
SetTimer, % "_Notify_Kill_" A_Gui - GF + 1, Off
Gui, % A_Gui + GL - GF + 1 ":Destroy"
Gui %A_Gui%:+LastFound
If SC
DllCall("AnimateWindow","UInt",WinExist(),"Int",SC,"UInt", "0x00050001")
Gui, %A_Gui%:Destroy
If (ActionList)
Loop,Parse,ActionList,|
If ((Action := SubStr(A_LoopField,1,2)) = A_Gui)
{
Temp_Notify_Action:= SubStr(A_LoopField,4)
StringReplace, ActionList, ActionList, % "|" A_Gui "=" Temp_Notify_Action, , All
If IsLabel(_Notify_Action := Temp_Notify_Action)
Gosub, %_Notify_Action%
_Notify_Action =
Break
}
StringReplace, NotifyList, NotifyList, % "|" GN, , All
SetTimer, % "_Notify_Flash_" A_Gui - GF + 1, Off
If (Exit = A_Gui)
ExitApp
Return
; when a notification times out:
_Notify_Kill_1:
_Notify_Kill_2:
_Notify_Kill_3:
_Notify_Kill_4:
_Notify_Kill_5:
_Notify_Kill_6:
_Notify_Kill_7:
_Notify_Kill_8:
_Notify_Kill_9:
_Notify_Kill_10:
_Notify_Kill_11:
_Notify_Kill_12:
_Notify_Kill_13:
_Notify_Kill_14:
_Notify_Kill_15:
_Notify_Kill_16:
_Notify_Kill_17:
_Notify_Kill_18:
_Notify_Kill_19:
_Notify_Kill_20:
_Notify_Kill_21:
_Notify_Kill_22:
_Notify_Kill_23:
_Notify_Kill_24:
_Notify_Kill_25:
; Critical
StringReplace, GK, A_ThisLabel, _Notify_Kill_
SetTimer, _Notify_Flash_%GK%, Off
GK += GF - 1
Gui, % GK + GL - GF + 1 ":Destroy"
Gui %GK%:+LastFound
If ST
DllCall("AnimateWindow","UInt",WinExist(),"Int",ST,"UInt", "0x00050001")
Gui, %GK%:Destroy
StringReplace, NotifyList, NotifyList, % "|" GK
If (Exit = GK)
ExitApp
Return
; flashes a permanent notification:
_Notify_Flash_1:
_Notify_Flash_2:
_Notify_Flash_3:
_Notify_Flash_4:
_Notify_Flash_5:
_Notify_Flash_6:
_Notify_Flash_7:
_Notify_Flash_8:
_Notify_Flash_9:
_Notify_Flash_10:
_Notify_Flash_11:
_Notify_Flash_12:
_Notify_Flash_13:
_Notify_Flash_14:
_Notify_Flash_15:
_Notify_Flash_16:
_Notify_Flash_17:
_Notify_Flash_18:
_Notify_Flash_19:
_Notify_Flash_20:
_Notify_Flash_21:
_Notify_Flash_22:
_Notify_Flash_23:
_Notify_Flash_24:
_Notify_Flash_25:
StringReplace, FlashGN, A_ThisLabel, _Notify_Flash_
FlashGN += GF - 1
FlashGN2 := FlashGN + GL - GF + 1
If Flashed%FlashGN2% := !Flashed%FlashGN2%
Gui, %FlashGN2%:Color, Silver
Else
Gui, %FlashGN2%:Color, % BC
Return
; wait for (or force) a notification to close:
_Notify_Wait_:
; Critical
If (Image)
{
Gui %Image%:+LastFound
If NotifyGuiID := WinExist()
{
WinWaitClose, , , % Abs(Duration)
If (ErrorLevel && Duration < 1)
{
Gui, % Image + GL - GF + 1 ":Destroy"
DllCall("AnimateWindow","UInt",NotifyGuiID,"Int",ST,"UInt","0x00050001")
Gui, %Image%:Destroy
}
}
}
Else
Loop, % GL-GF
{
Image := GL - (A_Index) ; + GF - 1)
Gui %Image%:+LastFound
If NotifyGuiID := WinExist()
{
; WinWaitClose, , , % Abs(Duration)
; If (ErrorLevel && Duration < 1)
; {
Gui, % Image + GL - GF + 1 ":Destroy"
DllCall("AnimateWindow","UInt",NotifyGuiID,"Int",ST,"UInt","0x00050001")
Gui, %Image%:Destroy
; }
}
}
Return
}
secsToStr(s)
{
if (s >= 86400)
{
d := floor(s / 86400), s := mod(s, 86400)
r := d " day"
r .= (d <> 1) ? "s" : "", r .= (s > 0) ? ", " : ""
}
if (s >= 3600)
{
h := floor(s / 3600), s := mod(s, 3600)
r .= h " hour"
r .= (h <> 1) ? "s" : "", r .= (s > 0) ? ", " : ""
}
if (s >= 60)
{
m := floor(s / 60), s := mod(s, 60)
r .= m " minute"
r .= (m <> 1) ? "s" : "", r .= (s > 0) ? ", " : ""
}
r .= s " second", r .= (s <> 1) ? "s" : ""
return, % r
}
;MsgBox, % secsToStr(1234567)
+^9::ExitApp
Esc::ExitApp