ThatGuySky wrote:
...is it possible to have the sounds overlap each other in the chance that the timers are roughly the same?
Yes, I've modified the script to use a workaround provided in
this post.
ThatGuySky wrote:
I have everything just the way I want it.. however when I go to compile the script to a .exe it fails. It gives me a partial .exe about 410kb and when I run it, i says ".EXE Corrupt"
I have no idea why it fails to compile on your machine. I will email you the whole project, if you still want to compile from source, I suggest you download and install AutoHotkey and try again. Good luck with your tournaments and I really hope you donate something considering I put it many hours on this.
ThatGuySky wrote:
I have removed the Save/Reset functions as those are not yet implemented
I've now implemented the Save/Reset buttons. Clicking on save will save the timer and hotkey to the ini file. Reset will read the settings from the ini file and set the GUI controls and stop any active timers.
The script now minimizes to the system tray instead of showing up in the taskbar. Hovering over the tray icon will display any currently active timers and clicking on the tray will display the interface. All the media (Pictures, sounds, icon) can be configured from the ini file or by replacing the existing media files, but keeping the same file names. I added a setting in the ini called HotkeysAreGlobal which is set to 1 by default. I you set it to 0, the hotkeys will only work when the GUI is the active window.
I'll admit I thought -for no reason at all- that this was going to be used for something a little more serious than a game trainer, but I've learned a few things while working on this and although the final code is about four times as big as it should be (Most of the code is 4x because of the 4 timers) I'm rather pleased with the final result and I hope you are too.
You have the entire source so you can modify it as you see fit. If you want to use SmartGUI to modify the GUI I suggest you not use it directly on the script, but rather examine the resulting code from SmartGUI and manually make the adjustments.
TimeTrainer.ahk
Code:
#Singleinstance force
SetWorkingDir %A_ScriptDir%
Gosub, SetGlobals
Gosub, CreateTrayMenu
Gosub, CreateGui
Gosub, SetGuiDefaults
Gosub, ShowGui
Gosub, StartUpdateGuiTimer
Gosub, ActivateHotkeys
return
SetGlobals:
IniPath = %A_Scriptdir%\Settings.ini
SoundPath = %A_Scriptdir%\Sounds
PicturePath = %A_Scriptdir%\Pictures
ProgramName := GetIni("General", "ProgramName")
TimerRestartThreshold := GetIni("General", "WarningSeconds")
return
CreateTrayMenu:
ProgramIconPath := PicturePath . "" . GetIni("General", "ProgramIcon")
menu, tray, tip, %ProgramName%
menu, tray, icon, %ProgramIconPath%
Menu, Tray, Click, 1
menu, tray, NoStandard
menu, tray, add, &Configure, Configure
menu, tray, add, &Exit, Exit
menu, tray, default, &Configure
return
Configure:
gui, show
return
CreateGui:
gui, +owner
gui, font, s20 cNavy, Verdana
Gui, Add, Text, x200 y05 w300 h040 +Center, %ProgramName%
gui, font
Gui, Add, Picture, x075 y050 w100 h100 Border vPicture0, %Picture0Path%
Gui, Add, Picture, x225 y050 w100 h100 Border vPicture1, %Picture1Path%
Gui, Add, Picture, x375 y050 w100 h100 Border vPicture2, %Picture2Path%
Gui, Add, Picture, x525 y050 w100 h100 Border vPicture3, %Picture3Path%
Gui, Add, Text, x005 y170 w055 h020 , Alarm:
Gui, Add, Text, x005 y190 w055 h020 , Hotkey:
Gui, Add, Text, x005 y210 w055 h020 , Remaining:
Gui, Add, Edit, x075 y170 w100 h020 limit number +Center vEditDelay0,
Gui, Add, Edit, x225 y170 w100 h020 limit number +Center vEditDelay1,
Gui, Add, Edit, x375 y170 w100 h020 limit number +Center vEditDelay2,
Gui, Add, Edit, x525 y170 w100 h020 limit number +Center vEditDelay3,
Gui, Add, Hotkey, x075 y190 w100 h020 vHK0 +Center,
Gui, Add, Hotkey, x225 y190 w100 h020 vHK1 +Center,
Gui, Add, Hotkey, x375 y190 w100 h020 vHK2 +Center,
Gui, Add, Hotkey, x525 y190 w100 h020 vHK3 +Center,
Gui, Add, Text, x075 y210 w100 h020 +Center vRemaining0
Gui, Add, Text, x225 y210 w100 h020 +Center vRemaining1
Gui, Add, Text, x375 y210 w100 h020 +Center vRemaining2
Gui, Add, Text, x525 y210 w100 h020 +Center vRemaining3
Gui, Add, Picture, x400 y250 w300 h050 Border vProgramLogo
Gui, Add, Button, x050 y250 w100 h030 gSaveSettings, Save
Gui, Add, Button, x200 y250 w100 h030 gSetGuiDefaults, Reset
Return
SetGuiDefaults:
Picture0Path := PicturePath . "" . GetIni("Timer0", "Picture")
Picture1Path := PicturePath . "" . GetIni("Timer1", "Picture")
Picture2Path := PicturePath . "" . GetIni("Timer2", "Picture")
Picture3Path := PicturePath . "" . GetIni("Timer3", "Picture")
ProgramLogoPath := PicturePath . "" . GetIni("General", "ProgramLogo")
GuiControl, , Picture0, %Picture0Path%
GuiControl, , Picture1, %Picture1Path%
GuiControl, , Picture2, %Picture2Path%
GuiControl, , Picture3, %Picture3Path%
GuiControl, , ProgramLogo, %ProgramLogoPath%
Timer0DefaultDelay := GetIni("Timer0", "TimerSeconds")
Timer1DefaultDelay := GetIni("Timer1", "TimerSeconds")
Timer2DefaultDelay := GetIni("Timer2", "TimerSeconds")
Timer3DefaultDelay := GetIni("Timer3", "TimerSeconds")
GuiControl, , EditDelay0, %Timer0DefaultDelay%
GuiControl, , EditDelay1, %Timer1DefaultDelay%
GuiControl, , EditDelay2, %Timer2DefaultDelay%
GuiControl, , EditDelay3, %Timer3DefaultDelay%
GuiControl, , Remaining0
GuiControl, , Remaining1
GuiControl, , Remaining2
GuiControl, , Remaining3
Timer0DefaultHotkey := GetIni("Timer0", "Hotkey")
Timer1DefaultHotkey := GetIni("Timer1", "Hotkey")
Timer2DefaultHotkey := GetIni("Timer2", "Hotkey")
Timer3DefaultHotkey := GetIni("Timer3", "Hotkey")
GuiControl, , HK0, %Timer0DefaultHotkey%
GuiControl, , HK1, %Timer1DefaultHotkey%
GuiControl, , HK2, %Timer2DefaultHotkey%
GuiControl, , HK3, %Timer3DefaultHotkey%
;Kill all timers
SetMyTimer("Timer0", Timer0, "Off")
SetMyTimer("TimerWarning0", TimerWarning0, "Off")
SetMyTimer("Timer1", Timer1, "Off")
SetMyTimer("TimerWarning1", TimerWarning1, "Off")
SetMyTimer("Timer2", Timer2, "Off")
SetMyTimer("TimerWarning2", TimerWarning2, "Off")
SetMyTimer("Timer3", Timer3, "Off")
SetMyTimer("TimerWarning3", TimerWarning3, "Off")
SetTimer, TimerWarning0, Off
SetTimer, Timer1, Off
SetTimer, TimerWarning1, Off
SetTimer, Timer2, Off
SetTimer, TimerWarning2, Off
SetTimer, Timer3, Off
SetTimer, TimerWarning3, Off
return
SaveSettings:
gui, +owndialogs
gosub, ActivateHotkeys
gui, submit, nohide
SetIni("Timer0", "TimerSeconds", GetControl("EditDelay0"))
SetIni("Timer1", "TimerSeconds", GetControl("EditDelay1"))
SetIni("Timer2", "TimerSeconds", GetControl("EditDelay2"))
SetIni("Timer3", "TimerSeconds", GetControl("EditDelay3"))
SetIni("Timer0", "Hotkey", GetControl("HK0"))
SetIni("Timer1", "Hotkey", GetControl("HK1"))
SetIni("Timer2", "Hotkey", GetControl("HK2"))
SetIni("Timer3", "Hotkey", GetControl("HK3"))
MsgBox,, %ProgramName%, Settings saved.
return
StartUpdateGuiTimer:
gosub, UpdateGui
SetMyTimer("UpdateGui", UpdateGui, 500)
return
UpdateGui:
if Round(GetMyTimer(Timer0) / 1000) > 0
Remaining0 := Round(GetMyTimer(Timer0) / 1000)
else
Remaining0 := ""
if Round(GetMyTimer(Timer1) / 1000) > 0
Remaining1 := Round(GetMyTimer(Timer1) / 1000)
else
Remaining1 := ""
if Round(GetMyTimer(Timer2) / 1000) > 0
Remaining2 := Round(GetMyTimer(Timer2) / 1000)
else
Remaining2 := ""
if Round(GetMyTimer(Timer3) / 1000) > 0
Remaining3 := Round(GetMyTimer(Timer3) / 1000)
else
Remaining3 := ""
GuiControl, , Remaining0, %Remaining0%
GuiControl, , Remaining1, %Remaining1%
GuiControl, , Remaining2, %Remaining2%
GuiControl, , Remaining3, %Remaining3%
if Remaining0 > 0
Timer0Title := "`n" . GetIni("Timer0", "Title") . ": "
else
Timer0Title := ""
if Remaining1 > 0
Timer1Title := "`n" . GetIni("Timer1", "Title") . ": "
else
Timer1Title := ""
if Remaining2 > 0
Timer2Title := "`n" . GetIni("Timer2", "Title") . ": "
else
Timer2Title := ""
if Remaining3 > 0
Timer3Title := "`n" . GetIni("Timer3", "Title") . ": "
else
Timer3Title := ""
menu, tray, tip, %ProgramName%%Timer0Title%%Remaining0%%Timer1Title%%Remaining1%%Timer2Title%%Remaining2%%Timer3Title%%Remaining3%
return
HandleHotkey0:
GuiControlGet, Delay, , EditDelay0
ElapsedTime := GetMyTimer("Timer0", 2)
;if (ElapsedTime < TimerRestartThreshold * 1000)
;{
WarningTime := (Delay - TimerRestartThreshold) * 1000
SetMyTimer("Timer0", Timer0, Delay * 1000) ;Start/Restart timer
SetMyTimer("TimerWarning0", TimerWarning0, WarningTime) ;Start/Restart timer to sound warning alarm 5 seconds before above timer
PlaySound(GetIni("Timer0", "SoundStart")) ;Play sound when timer starts
;}
;else
;{
;What to do if hotkey is pressed but more than 5 seconds have passed?
;}
return
HandleHotkey1:
GuiControlGet, Delay, , EditDelay1
ElapsedTime := GetMyTimer("Timer1", 2)
;if (ElapsedTime < TimerRestartThreshold * 1000)
;{
SetMyTimer("Timer1", Timer1, Delay * 1000) ;Start/Restart timer
WarningTime := (Delay - TimerRestartThreshold) * 1000
SetMyTimer("TimerWarning1", TimerWarning1, WarningTime) ;Start/Restart timer to sound warning alarm 5 seconds before above timer
PlaySound(GetIni("Timer1", "SoundStart")) ;Play sound when timer starts
;}
;else
;{
;What to do if hotkey is pressed but more than 5 seconds have passed?
;}
return
HandleHotkey2:
GuiControlGet, Delay, , EditDelay2
ElapsedTime := GetMyTimer("Timer2", 2)
;if (ElapsedTime < TimerRestartThreshold * 1000)
;{
SetMyTimer("Timer2", Timer2, Delay * 1000) ;Start/Restart timer
WarningTime := (Delay - TimerRestartThreshold) * 1000
SetMyTimer("TimerWarning2", TimerWarning2, WarningTime) ;Start/Restart timer to sound warning alarm 5 seconds before above timer
PlaySound(GetIni("Timer2", "SoundStart")) ;Play sound when timer starts
;}
;else
;{
;What to do if hotkey is pressed but more than 5 seconds have passed?
;}
return
HandleHotkey3:
GuiControlGet, Delay, , EditDelay3
ElapsedTime := GetMyTimer("Timer3", 2)
;if (ElapsedTime < TimerRestartThreshold * 1000)
;{
SetMyTimer("Timer3", Timer3, Delay * 1000) ;Start/Restart timer
WarningTime := (Delay - TimerRestartThreshold) * 1000
SetMyTimer("TimerWarning3", TimerWarning3, WarningTime) ;Start/Restart timer to sound warning alarm 5 seconds before above timer
PlaySound(GetIni("Timer3", "SoundStart")) ;Play sound when timer starts
;}
;else
;{
;What to do if hotkey is pressed but more than 5 seconds have passed?
;}
return
Timer0:
SetTimer, Timer0, Off
PlaySound(GetIni("Timer0", "SoundStop"))
return
TimerWarning0:
SetTimer, TimerWarning0, Off
PlaySound(GetIni("Timer0", "SoundWarning"))
return
Timer1:
SetTimer, Timer1, Off
PlaySound(GetIni("Timer1", "SoundStop"))
return
TimerWarning1:
SetTimer, TimerWarning1, Off
PlaySound(GetIni("Timer1", "SoundWarning"))
return
Timer2:
SetTimer, Timer2, Off
PlaySound(GetIni("Timer2", "SoundStop"))
return
TimerWarning2:
SetTimer, TimerWarning2, Off
PlaySound(GetIni("Timer2", "SoundWarning"))
return
Timer3:
SetTimer, Timer3, Off
PlaySound(GetIni("Timer3", "SoundStop"))
return
TimerWarning3:
SetTimer, TimerWarning3, Off
PlaySound(GetIni("Timer3", "SoundWarning"))
return
ShowGui:
Gui, Show, w700 h300, %ProgramName%
return
ActivateHotkeys:
If HK0
Hotkey, %HK0%, Off
If HK1
Hotkey, %HK1%, Off
If HK2
Hotkey, %HK2%, Off
If HK3
Hotkey, %HK3%, Off
gui, submit, nohide
if GetIni("General", "HotkeysAreGlobal")
{
Hotkey, IfWinActive
Hotkey, %HK0%, HandleHotkey0, On
Hotkey, %HK1%, HandleHotkey1, On
Hotkey, %HK2%, HandleHotkey2, On
Hotkey, %HK3%, HandleHotkey3, On
}
else
{
gui, +LastFoundExist
GuiId := WinExist()
Hotkey, IfWinActive, ahk_id %GuiId%
Hotkey, %HK0%, HandleHotkey0, On
Hotkey, %HK1%, HandleHotkey1, On
Hotkey, %HK2%, HandleHotkey2, On
Hotkey, %HK3%, HandleHotkey3, On
}
return
Exit:
GuiClose:
exitapp
return
GuiSize:
if A_EventInfo = 1
{
gui, show, hide
}
return
SetIni(Section, Key, Value)
{
global IniPath
IniWrite, %Value%, %IniPath%, %Section%, %Key%
return %errorlevel%
}
GetControl(ControlID)
{
GuiControlGet, Value, , %ControlID%
return %Value%
}
GetIni(Section, Key)
{
global IniPath
IniRead, Value, %IniPath%, %Section%, %Key%
return Value
}
SetMyTimer(label, byref TimerArray, Period = 250, Priority = 0)
{
;http://www.autohotkey.com/forum/viewtopic.php?p=282254#282254
;msgbox, Label: %Label%`nTimerArray: %TimerArray%
SetTimer, %Label%, %Period%, %Priority%
TimerArray = %A_TickCount%|%Period%
}
GetMyTimer(TimerArray, Mode = 3)
{
;http://www.autohotkey.com/forum/viewtopic.php?p=282254#282254
;Modes: 1 = Return total time, 2 = Return elapsed time, 3 = Return remaining time
StringSplit, TimerArray, TimerArray, |
if (TimerArray1 = "Off")
{
TimerArray2 := ""
ElapsedTime := ""
RemainingTime := ""
}
else
{
ElapsedTime := A_TickCount - TimerArray1
RemainingTime := TimerArray2 - ElapsedTime
}
StringLower, mode, mode
if mode = 1
return TimerArray2
else if mode = 2
return ElapsedTime
else if mode = 3
return RemainingTime
else
return 1 ;Error. Unexpected value for mode
}
PlaySound(FileName)
{
;Trubbleguy http://www.autohotkey.com/forum/viewtopic.php?p=231332#231332
global SoundPath
run, %A_ScriptDir%\PlaySound.exe "%SoundPath%\%Filename%"
}
PlaySound.ahkCode:
#NoTrayIcon
SoundPlay,%1%,wait
exitapp
Settings.iniCode:
[General]
ProgramName=TimeTrainer
ProgramIcon=trayicon.ico
ProgramLogo=Logo.bmp
Version=1.0
WarningSeconds=5
HotkeysAreGlobal=1
[Timer0]
Title=Timer1
Hotkey=^D
TimerSeconds=10
SoundStart=Timer0Start.wav
SoundStop=Timer0Stop.wav
SoundWarning=Timer0Warning.wav
Picture=Timer0.bmp
[Timer1]
Title=Timer2
Hotkey=^F
TimerSeconds=20
SoundStart=Timer1Start.wav
SoundStop=Timer1Stop.wav
SoundWarning=Timer1Warning.wav
Picture=Timer1.bmp
[Timer2]
Title=Timer3
Hotkey=^G
TimerSeconds=30
SoundStart=Timer2Start.wav
SoundStop=Timer2Stop.wav
SoundWarning=Timer2Warning.wav
Picture=Timer2.bmp
[Timer3]
Title=Timer4
Hotkey=^H
TimerSeconds=40
SoundStart=Timer3Start.wav
SoundStop=Timer3Stop.wav
SoundWarning=Timer3Warning.wav
Picture=Timer3.bmp