- Alarm combined.png (33.55 KiB) Viewed 666 times
Features
- "In x time" or "At time x"
- Keeps alarm in memory even after pc shutdown, script reload/error, etc.
- Keeps previous alarm text if you want a repeating reminder
- Updates remaining time if called again
- Set it to Sleep, Hibernate, ShutDown or actually stay awake during that time
- Dragable toolwindow
- Tasbkar tooltip with remaining time and "at time"
Code: Select all
/*_________________Alarm by e-motiv.net
https://www.autohotkey.com/boards/viewtopic.php?f=83&t=121936
*/
TNoSleep := TShut := SecsLeft := 0
;In case pc shut down before alarm went off
if ATTime:=IniRead("alarm.ini", "" , "ATTime",0) {
Alarm()
}
AlarmShutdown()
{
global
;Don't shutdown at restart/waking! Set it here before actual shutdown so it's certainly processed
oldTShut := TShut
TShut := 0
;MsgBox AlarmShutdown TShut = %TShut%
if (oldTShut = 3)
Shutdown(9)
else ;Hibernate or Suspend
DllCall("PowrProf\SetSuspendState", "int", oldTShut = 2?1:0, "int", 0, "int", 0)
return
}
AlarmEnd()
{
global
if TShut
{
SoundPlay("C:\Users\Ruby\Audio\Sounds\140 Grime Synth D 01.wav")
WhichShut := TShut=3?"Shutdown":(TShut=2?"Hibernate":"Suspend")
A_IconTip := WhichShut . " in 20 seconds. Trigger alarm again to cancel. `n " . AlarmText
myTrayTip(WhichShut " in 20 seconds. Trigger alarm again to cancel. `n " AlarmText)
SetTimer(AlarmShutdown,-20000)
}
else
{ ;Display text and new alarm
Alarm()
}
return
}
Alarm(A_ThisMenuItem?, A_ThisMenuItemPos?, MyMenu?)
{
global
;Disable existing AlarmTimer
SetTimer(AlarmEnd,0)
if TNoSleep
{
DllCall("SetThreadExecutionState", "UInt", 0x80000000) ; Reset don't sleep command
}
if TShut
{
SetTimer(AlarmShutdown,0) ; Cancel shutdown
TShut := 0
myTrayTip(WhichShut " cancelled.")
A_IconTip := "Menu,TRAY, Tip"
}
SoundPlay("C:\Users\Ruby\Audio\Sounds\140 Grime Synth D 01.wav")
if !(alarmGui??false)
{
alarmGui := Gui("-Caption +LastFound +ToolWindow +AlwaysOnTop", "Alarm")
WinSetTransparent 240
systemAccentColor := RegRead("HKCU\SOFTWARE\Microsoft\Windows\DWM", "ColorizationColor")
alarmGui.BackColor := systemAccentColor
alarmGui.SetFont("ccccccc")
alarmGui.OnEvent("Close", GuiEscape)
alarmGui.OnEvent("Escape", GuiEscape)
alarmGui.Opt("+AlwaysOnTop -Border")
alarmGui.SetFont("ccccccc s10", "Verdana")
alarmGui.AddText( "ym+10 Center Section", "In:")
alarmGui.SetFont("s20", "Verdana")
alarmGui.AddEdit( "xm+70 cblack ym W55 R1 Center Number Limit2 vINxHours",0)
.OnEvent("Change", updateAT)
alarmGui.AddUpDown()
alarmGui.AddText( "x+2 yp+7", ":")
alarmGui.AddEdit( "x+7 cblack ym W55 R1 Center Number Limit2 vINxMins", 0)
.OnEvent("Change", updateAT)
alarmGui.AddUpDown("Range0-60", 5)
alarmGui.AddText( "x+2", ":")
alarmGui.AddEdit( "x+5 cblack ym W55 R1 Center Number Limit2 vINxSecs", 0)
.OnEvent("Change", updateAT)
alarmGui.AddUpDown("Range0-60", 5)
alarmGui.SetFont("s10", "Verdana")
alarmGui.AddText( "xm y+30", "At:")
alarmGui.SetFont("s20", "Verdana")
alarmGui.AddDateTime( "xm+70 yp-10 W160 Center vATTime", "Time")
.OnEvent("Change", updateIN)
alarmGui.SetFont("s10", "Verdana")
alarmGui.AddEdit( "xm y+20 w300 R4 cblack -VScroll vAlarmText",
StrReplace(StrReplace(IniRead("alarm.ini", "" , "AlarmText",""), "#r", "`r"), "#n", "`n")
)
alarmGui.AddRadio("xm+10 y+20 vTShut", "Sleep")
alarmGui.AddRadio("xp+80 yp", "Hibernate")
alarmGui.AddRadio("xp+90 yp", "Shut down")
alarmGui.AddRadio("xm+10 yp+20 Group vTNoSleep", "Stay awake")
alarmGui.AddButton("xm y+20 Center W300 R2 Default", "Set!")
.OnEvent("Click", ButtonSet)
;In case pc shut down before alarm went off
if ATTime {
alarmGui["ATTime"].Value := ATTime
updateIN()
ButtonSet()
return
}
}
if IsSet(StartTime) {
;Get more exact SecsLeft in case AlarmIconTipUpdate is not run every sec
updateSecsLeft()
; Fill in values based on current time left or NOW
if (SecsLeft>0) {
alarmGui["INxHours"].Value := Round(SecsLeft // (60*60))
alarmGui["INxMins"].Value := Round(Mod(SecsLeft,60*60) // (60))
alarmGui["INxSecs"].Value := Round(Mod(Mod(SecsLeft,60*60),60))
updateAT()
updateIN()
}
}
alarmGui.show("Restore") ;%A_Now%
OnMessage( 0x201, WM_MOUSEMOVE )
}
;To be able to move the window without caption
WM_MOUSEMOVE( wparam, lparam, msg, hwnd )
{
if wparam = 1 ; LButton
PostMessage 0xA1, 2,,, "A" ; WM_NCLBUTTONDOWN
}
updateAT(gC := 0, Info := 0)
{
global
;Prevent empty fields since user can still do that
if alarmGui["INxSecs"] == ""
alarmGui["INxSecs"] = 0
if alarmGui["INxMins"] == ""
alarmGui["INxMins"] = 0
if alarmGui["INxHours"] == ""
alarmGui["INxHours"] = 0
CF := alarmGui.FocusedCtrl ; Not really the same, this returns the focused gui control object...
if (CF = "ATTime")
Return ; Don't loop since edit alarmGui-label gets triggered by script (updateIN)
if (alarmGui["INxSecs"].Value>59) {
alarmGui["INxSecs"].Value:=0
alarmGui["INxMins"].Value+=1
}
if (alarmGui["INxMins"].Value>59) {
alarmGui["INxMins"].Value:=0
alarmGui["INxHours"].Value+=1
}
Temp:=A_Now
Temp := DateAdd(Temp, alarmGui["INxHours"].Value, 'h')
Temp := DateAdd(Temp, alarmGui["INxMins"].Value, 'm')
Temp := DateAdd(Temp, alarmGui["INxSecs"].Value, 's')
alarmGui["ATTime"].Value := Temp
return
}
updateIN(gC := 0, Info := 0)
{
global
ATTime := DateDiff(alarmGui["ATTime"].Value, A_Now, 's')
Temp2:=ATTime // (60*60)
;MsgBox %ATTime%, %Temp2%
alarmGui["INxHours"].Value := Temp2
Temp2:=Mod(ATTime,60*60) // 60
alarmGui["INxMins"].Value := Temp2
Temp2:=Mod(Mod(ATTime,60*60),60)
alarmGui["INxSecs"].Value := Temp2
return
}
updateSecsLeft() {
global
ElapsedTime := A_TickCount - StartTime
SecsLeft := Round(INTotSecs - ElapsedTime/1000)
}
AlarmIconTipUpdate()
;Add icontip
;MSgBox %ATTimeXIUpdate% %SecsLeft% %A_IconTip%
{
global
updateSecsLeft()
HMSLeft:=SecsLeft // (60*60) . "h " . Mod(SecsLeft,60*60) // 60 . "m " . Mod(Mod(SecsLeft,60*60),60) . "s"
ATTimeXText2:= " -- Alarm -- " . TExtraText . " `n" .
" - At: " . FTime . "`n" .
" - In: " . HMSLeft . " ( " . SecsLeft . " sec.) `n" .
(IsSet(AlarmText) ? " -- Text -- `n" AlarmText : "") .
" -- -- "
NewIconTip := RegExReplace(A_IconTip, " -- Alarm --[\s\S]* -- -- ", ATTimeXText2, &Replaced)
If !Replaced
NewIconTip := A_IconTip . (A_IconTip=""?"":"`n") . ATTimeXText2
;MsgBox Old: %A_IconTip%`nReplaced: %Replaced%`nNew: %NewIconTip%
A_IconTip := NewIconTip
return
}
;FORM SUBMITTED
ButtonSet(gC := 0, Info := 0)
{
global
alarmGui.Submit()
H := alarmGui["INxHours"].Value
m := alarmGui["INxMins"].Value
s := alarmGui["INxSecs"].Value
ATTime := alarmGui["ATTime"].Value
AlarmText := alarmGui["AlarmText"].Text
TShut := alarmGui["TShut"].Value
TNoSleep := alarmGui["TNoSleep"].Value
StartTime := A_TickCount
INTotSecs :=
SecsLeft :=((H*60 + m)*60+s)
;// Set one-time alarm timer
SetTimer(AlarmEnd, -SecsLeft*1000)
IniWrite ATTime, "alarm.ini", "" , "ATTime"
IniWrite StrReplace(StrReplace(AlarmText, "`n", "#n"), "`r", "#r"), "alarm.ini", "" , "AlarmText"
ATTimeXText:=(H!=0 ? H . "h " : "") . (m!=0 ? m . "' " : "") . (s!=0 ? s . "'' " : "") . " from now"
FTime := FormatTime(ATTime, "HH : mm : ss")
if TNoSleep
{
;MsgBox TNoSleep = %TNoSleep% !!
TExtraText .= " (stay awake)"
DllCall("SetThreadExecutionState", "UInt", 0x80000001) ; Don't sleep and do this At I say so
}
else
TExtraText:=""
myTrayTip("Alarm Set" TExtraText "`n" FTime " = " ATTimeXText)
AlarmIconTipUpdate()
SetTimer(AlarmIconTipUpdate,1000)
}
GuiEscape(*)
{
global
SecsLeft:=0
alarmGui.Destroy()
alarmGui:=0
;don't alarm after shut down
ATTime:=0
IniDelete "alarm.ini", "" , "ATTime"
SetTimer(AlarmIconTipUpdate,0)
NewIconTip := RegExReplace(A_IconTip, "\n*--[\s\S]*--", "")
A_IconTip := NewIconTip
}
;What to do when reloaded?
OnExit ExitFunc
ExitFunc(ExitReason, ExitCode)
{
if !(alarmGui??false)
return
if ExitReason != "Logoff" and ExitReason != "Shutdown"
{
Result := MsgBox("Do you want to retain the alarm?","An alarm was set!", 4)
if Result = "No" {
IniDelete "alarm.ini", "" , "ATTime"
}
}
}