Jump to content

Recommended Posts

Posted (edited)

TalkTock is a talking clock. It's configurable via the opening screen, an .ini file, or the command line. The .ini offers the widest range of options, including language preferences. The package includes sample .ini files for Italian- and Russian-language clocks.

Links:

Source:

#cs
--------------------------------------
TalkTock.au3 -- Talking Clock
CLD rev.2021-01-18-a (freeware -- no warranties expressed or implied)

Usages
(1) TalkTock [/I #] [/C 12|24] [/V #] [/R #] [/S ["]voice name["]|hint] [/U S|M|H|D|W|T|Y=#] [/Q|/QQ]
    /I = Interval between time announcements (in minutes)
    /C = Clock style (12- or 24-hour)
    /V = Volume (range 1 to 100)
    /R = speaking Rate (range -10 to 10)
    /S "voice name"|hint (hint = unique substring of voice name)
    /T = Say time only (no prefix or postfix)
    /U S|M|H|D|W|T|Y=# = clock stops after # Secs|Mins|Hrs|Days|Wks|monThs|Yrs
    /Q = Quiet (time displayed on screen, not spoken)
    /QQ = NOT Quiet (overrides Quiet=1 setting in TalkTock.ini)

User-selected values are saved in TalkTock.ini.
Language preferences and other settings can be changed by editing
  TalkTock.ini in any text editor.

(2) TalkTock /?|?H|/SayHelp|/Kill
     /?|/H = Display on-screen help
     /SayHelp = Speak the help screen
     /Kill = Kill ALL running TalkTock.exe processes

(3) TalkTock /L
    List available voices

(4) TalkTock /UseFile [d:\path\]INI_filename
    Take settings from a specified settings file
      (must have TalkTock.ini format)

(5) TalkTock /RESET
    Create new TalkTock.ini with default settings
      (existing TalkTock.ini is backed up to TalkTock.IN_)

(6) TalkTock /SOURCE
    View AutoIt source code
--------------------------------------
#ce

#include <AutoItConstants.au3>
#include <ButtonConstants.au3>
#include <FileConstants.au3>
#include <GUIConstants.au3>
#include <GUIConstantsEx.au3>
#include <Misc.au3>
#include <MsgBoxConstants.au3>
#include <StaticConstants.au3>
#include <TrayConstants.au3>
#include <WindowsConstants.au3>

Opt("MustDeclareVars", 1)
Opt("TrayAutoPause", 0)
Opt("TrayMenuMode", 1)
Opt("TrayOnEventMode", 1)

; Icon by Ampeross (free for non-commercial use)
; http://www.iconarchive.com/show/qetto-2-icons-by-ampeross/timer-icon.html
FileInstall("X:\Ampeross-Qetto-2-Timer.ico", @TempDir, 1)
FileInstall("X:\ausource.txt", @TempDir, 1)

Global $sCMline = $CmdLineRaw
Global $sCurWin = WinGetTitle("[active]")

; Warning on multiple TalkTock processes
If ProcessList(@ScriptName)[0][0] > 1 Then
    If $CmdLine[0] = 0 Or ( StringInStr($sCMline, "kill") + StringInStr($sCMline, "reset") + StringInStr($sCMline, "source") + StringInStr($sCMline, "/?") + StringInStr($sCMline, "-?") + StringInStr($sCMline, "/h") + StringInStr($sCMline, "-h") + StringInStr($sCMline, "/L") + StringInStr($sCMline, "-L") = 0  ) Then ReStartTT()
EndIf

; Default interval, 12|24, volume, talk rate settings, etc.
Global $idFreq = 15     ; Default interval every 15 minutes
Global $vdT12or24 = 12  ; 12- or 24-hour time (Clock style)
Global $sdVoice = ""    ; TTS voice (""=use default voice)
Global $idVol = 80      ; Volume (range 0 to 100)
Global $idRate = 0      ; Speaking rate (range -10 to 10)
Global $idStop = 0      ; Clock stops = 0 (Never)
Global $sdUnits = "H"   ; Stop clock units (default = H = hours)
Global $bdQuiet = 0      ; Quiet operation (time shown on screen)
Global $idDisplay = 2   ; Duration of on-screen time display in secs.
;                      ;  (has effect only if $bQuiet = 1)
; ---------------------------------------------------------------
Global $bCanned = 1     ; "Canned" or custom interval
Global $bdTimeOnly = 0  ; Say time only (no prefix|postfix)
Global $bArgs = 0       ; If args, do not update .INI
;
; Default phrases
Global $sdHi = "Welcome to TalkTock, the Talking Clock"
Global $sdPause = "TalkTock paused"
Global $sdResume = "TalkTock resumed"
Global $sdStopSay = "Goodbye"
Global $sdIntro = "The time will be announced every"
Global $sdPrefix = "It's"
Global $sdPrefix1 = ""
Global $bdSayAMPM = 1
Global $sdHowFreq1 = "minnit" ; spelling altered to aid pronunciation
Global $sdHowFreq5 = "5 minutes at the 5-minute mark"
Global $sdHowFreq10 = "10 minutes at the 10-minute mark"
Global $sdHowFreq15 = "15 minutes on the quarter hour"
Global $sdHowFreq30 = "30 minutes on the half hour"
Global $sdHowFreq60 = "'our on the hour"; pronunciation
Global $sdHowFreqCustom = "minutes"
Global $sdMidnight = "midnight"
Global $sdMidday = "noon"
Global $sdBye = "Goodbye"

#cs
; Default phrases
Global $sdHi = ""
Global $sdPause = ""
Global $sdResume = ""
Global $sdStopSay = ""
Global $sdIntro = ""
Global $sdPrefix = ""
Global $sdPrefix1 = ""
Global $bdSayAMPM = 1
Global $sdHowFreq1 = ""
Global $sdHowFreq5 = ""
Global $sdHowFreq10 = ""
Global $sdHowFreq15 = ""
Global $sdHowFreq30 = ""
Global $sdHowFreq60 = ""
Global $sdHowFreqCustom = ""
Global $sdBye = ""
#ce

; Default GUI labels
Global $sgdTitle = "TalkTock - Talking Clock"
Global $sgdTop = "Say the time every"
Global $sgdMinute = "minute"
Global $sgdMinutes = "minutes"
Global $sgdQuarterHour = "quarter hour"
Global $sgdHalfHour = "half hour"
Global $sgdHour = "hour"
Global $sgdHours = "hours"
Global $sgdCustom = "Custom"
Global $sgdClock = "Clock style"
Global $sgd12hr_Label = "12-hour"
Global $sgd24hr_label = "24-hour"
Global $sgdQuiet_label = "Time is: "
Global $sgdSpeak_label = "spoken"
Global $sgdDisplay_label = "displayed"
Global $sgdExpires = "Clock stops "
Global $sgdExpNever = " Never"
Global $sgdExpAfter = " After "
Global $sgdExpSecs = "secs"
Global $sgdExpMins = "mins"
Global $sgdExpHours = "hours"
Global $sgdExpDays = "days"
Global $sgdExpWeeks = "weeks"
Global $sgdExpMons = "months"
Global $sgdExpYears = "years"
Global $sgdVolume_label = "Volume"
Global $sgdStart_button = "Start"
Global $sgdCancel_button = "Cancel"
Global $sgdPause = "Pause"
Global $sgdResume = "Resume"
Global $sgdExit = "Stop"

; Failsafe assignments
Global $sVoice = $sdVoice
Global $iFreq = $idFreq
Global $vT12or24 = $vdT12or24
If $vT12or24 <> 24 Then $vT12or24 = 12
Global $iVol = $idVol
Global $iRate = $idRate
Global $bQuiet = $bdQuiet
Global $iDisplay = $idDisplay
Global $iStop = $idStop
Global $iIter = -1
Global $sUnits = $sdUnits
Global $sStopFn = ""
Global $sHi = $sdHi
Global $sPause = $sdPause
Global $sResume = $sdResume
Global $sStopSay = $sdStopSay
Global $sIntro = $sdIntro
Global $sPrefix = $sdPrefix
Global $sPrefix1 = $sdPrefix1
Global $bSayAMPM = $bdSayAMPM
If $vT12or24 = 24 Then $bSayAMPM = 0
Global $sHowFreq1 = $sdHowFreq1
Global $sHowFreq5 = $sdHowFreq5
Global $sHowFreq10 = $sdHowFreq10
Global $sHowFreq15 = $sdHowFreq15
Global $sHowFreq30 = $sdHowFreq30
Global $sHowFreq60 = $sdHowFreq60
Global $sHowFreqCustom = $sdHowFreqCustom
Global $sMidnight = $sdMidnight
Global $sMidday = $sdMidday
Global $sBye = $sdBye

; GUI Labels
Global $sgPause = $sgdPause
Global $sgResume = $sgdResume
Global $sgExit = $sgdExit
Global $sgTitle = $sgdTitle
Global $sgTop = $sgdTop
Global $sgMinute = $sgdMinute
Global $sgMinutes = $sgdMinutes
Global $sgQuarterHour = $sgdQuarterHour
Global $sgHalfHour = $sgdHalfHour
Global $sgHour = $sgdHour
Global $sgHours = $sgdHours
Global $sgCustom = $sgdCustom
Global $sgClock = $sgdClock
Global $sg12hr_label = $sgd12hr_Label
Global $sg24hr_label = $sgd24hr_label
Global $sgQuiet_label = $sgdQuiet_label
Global $sgSpeak_label = $sgdSpeak_label
Global $sgDisplay_label = $sgdDisplay_label
Global $sgExpires = $sgdExpires
Global $sgExpNever = $sgdExpNever
Global $sgExpAfter = $sgdExpAfter
Global $sgExpSecs = $sgdExpSecs
Global $sgExpMins = $sgdExpMins
Global $sgExpHours = $sgdExpHours
Global $sgExpDays = $sgdExpDays
Global $sgExpWeeks = $sgdExpWeeks
Global $sgExpMons = $sgdExpMons
Global $sgExpYears = $sgdExpYears
Global $sgVolume_label = $sgdVolume_label
Global $sgStart_button = $sgdStart_button
Global $sgCancel_button = $sgdCancel_button

Global $sPad = "    "; | & $sPad |
Global $sHelp = "TalkTock -- The Talking Clock" & @CRLF & "CLD rev.2021-01-18 (freeware -- no warranties expressed or implied)" & @CRLF & @CRLF & "Usage:" & @CRLF & "(1) TalkTock.exe" & @CRLF & $sPad & "Choose options, then click ""Start""" & @CRLF & @CRLF & "(2) TalkTock.exe [/I #] [/C 12|24] [/V #]] [/R #] [/S [""]voice name[""]|hint] [/U S|M|H|D|W|T|Y=#] [/Q|/QQ]" & @CRLF & $sPad & "/I = Interval between time announcements (in minutes)" & @CRLF & $sPad & "/C = Clock style (12- or 24-hour)" & @CRLF & $sPad & "/V = Volume (range 1 to 100)" & @CRLF & $sPad & "/R = speaking Rate (range -10 to 10)" & @CRLF & $sPad & "/S ""voice name""|hint (hint = unique substring of voice name)" & @CRLF & $sPad & "/T = Say time only, no prefix or postfix (instant compatibility with any language)" & @CRLF & $sPad & "/U S|M|H|D|W|T|Y=# = clock stops after # Secs|Mins|Hrs|Days|Wks|monThs|Yrs" & @CRLF & $sPad & "/Q = Quiet (time displayed on screen, not spoken)" & @CRLF & $sPad & "/QQ = NOT Quiet (overrides Quiet=1 setting in TalkTock.ini)" & @CRLF & @CRLF & "User-selected values are saved in TalkTock.ini." & @CRLF & "Language preferences and other settings can be changed by editing" & @CRLF & "  TalkTock.ini in any text editor." & @CRLF & "" & @CRLF & "(3) TalkTock /?|/H|/SayHelp|/Kill" & @CRLF & $sPad & "/?|/H = Display on-screen help" & @CRLF & $sPad & "/SayHelp = Spoken command-line usage" & @CRLF & $sPad & "/Kill = Kill ALL running TalkTock.exe processes" & @CRLF & @CRLF & "(4) TalkTock /L" & @CRLF & $sPad & "List available voices" & @CRLF & @CRLF & "(5) TalkTock /UseFile [d:\path\]INI_filename" & @CRLF & $sPad & "Take settings from a specified settings file" & @CRLF & $sPad & "(must have TalkTock.ini format)" & @CRLF & @CRLF & "(6) TalkTock /RESET" & @CRLF & $sPad & "Create new TalkTock.ini with default settings" & @CRLF & $sPad & "(existing TalkTock.ini is backed up to TalkTock.IN_)" & @CRLF & @CRLF & "(7) TalkTock /SOURCE" & @CRLF & $sPad & "View AutoIt source code" & @CRLF

; Create TalkTock.ini (if not already present)
Global $sFini = @ScriptName
Global $sFini2 = ""; alternate .INI file
If StringInStr($sFini, ".") Then $sFini = StringTrimRight($sFini, StringLen($sFini) - StringInStr($sFini, ".", 0, -1) + 1)
$sFini = @ScriptDir & "\" & $sFini & ".ini"

;Create new (default) TalkTock.ini
If $CmdLine[0] = 1 Then
    If StringInStr(StringUpper($CmdLine[1]), "RESET") Then
        If FileExists($sFini) Then
            FileCopy($sFini, @ScriptDir & "\TalkTock.IN_", $FC_OVERWRITE)
            FileDelete($sFini)
        EndIf
    EndIf
EndIf

; Take settings from file not TalkTock.ini
If $CmdLine[0] = 2 Then
    If StringUpper($CmdLine[1]) = "/USEFILE" Or StringUpper($CmdLine[1]) = "-USEFILE" Then
        $sFini2 = $CmdLine[2]
        If FileExists($sFini2) Then $sFini = $sFini2
    EndIf
EndIf

If Not FileExists($sFini) Then
    Global $hIni = FileOpen($sFini, $FO_OVERWRITE + $FO_UTF8)
    If $hIni > -1 Then

        Global $sIniC = "Settings file for TalkTock.exe, Talking Clock" & @CRLF & ";" & @CRLF & "[TalkTock]" & @CRLF & ";; Interval between time announcements, in minutes" & @CRLF & "Interval=" & $idFreq & @CRLF & ";; 12- or 24-hour clock" & @CRLF & "ClockStyle=" & $vdT12or24 & @CRLF& ";; Say AM/PM? 1=Yes 0=No; applies to 12-hour clock only" & @CRLF & "SayAMPM=" & $bdSayAMPM & @CRLF& ";; TTS voice" & @CRLF & "Voice=default" & @CRLF & ";Voice=Microsoft George" & @CRLF& ";; Volume, range 1 to 100" & @CRLF & "Volume=" & $idVol & @CRLF& ";; Speaking rate, range -10 to 10" & @CRLF & "TalkRate=" & $idRate & @CRLF & ";; Clock stop timer units" & @CRLF & ";; S=secs M=mins H=hours D=days W=weeks T=months Y=years" & @CRLF & "ClockTimerUnits=" & $sdUnits & @CRLF& ";; Clock stops after how many timer units? (0 = clock never stops)" & @CRLF & "ClockStops=0" & @CRLF & ";; Quiet operation, time shown on screen (1=yes 0=no)" & @CRLF & "Quiet=0" & @CRLF & ";; Duration, in seconds, of on-screen time display" & @CRLF & ";; Fractional (decimal) values are allowed (e.g., Display=3.5)" & @CRLF & "Display=2.5" & @CRLF & @CRLF

        $sIniC &= "[Language]" & @CRLF & ";; Translate the phrases and labels below into your chosen language." & @CRLF & ";; Any language with a TTS function (a ""Voice"") in its language pack" & @CRLF & ";; should work. To use other languages, edit TalkTock.ini using the" & @CRLF & ";; UTF-8 character set" & @CRLF & ";" & @CRLF & ";; TimeOnly: 1=Yes (phrases set below will NOT be spoken); 0=No" & @CRLF & "TimeOnly=0" & @CRLF & ";" & @CRLF & "; Welcome and Intro messages" & @CRLF & ";; Comment out (prepend "";"") to suppress these messages" & @CRLF & "onStart=" & $sdHI & @CRLF & "Intro=" & $sdIntro & @CRLF & ";" & @CRLF & "; Interval descriptions" & @CRLF & "Freq1=" & $sdHowFreq1 & @CRLF & "Freq5=" & $sdHowFreq5 & @CRLF & "Freq10=" & $sdHowFreq10 & @CRLF & "Freq15=" & $sdHowFreq15 & @CRLF & "Freq30=" & $sdHowFreq30 & @CRLF & "Freq60=" & $sdHowFreq60 & @CRLF & "FreqCustom=" & $sdHowFreqCustom & @CRLF & ";; Spoken prefix" & @CRLF & "Prefix=" & $sdPrefix & @CRLF & ";; No prefix (just announce the time):" & @CRLF & ";Prefix=" & @CRLF & ";Prefix=It's" & @CRLF & ";Prefix=It's now" & @CRLF & ";Prefix=The time is" & @CRLF & ";; Singular prefix: Prefix1 defines the singular inflection" & @CRLF & ";; for ""one o'clock"" in applicable languages, e.g., Italian" & @CRLF & ";Prefix1=" & @CRLF & ";; Postfix at midnight (0000 hours) and midday (1200 hours)" & @CRLF & ";;  See also Postfix pairs, below" & @CRLF & "At0000Say=" & $sdMidnight & @CRLF & "At1200Say=" & $sdMidday & @CRLF & ";" & @CRLF

        $sIniC &= ";; Postfix pairs (optional)" & @CRLF & ";; ------------------------" & @CRLF & ";; Alternatives to saying ""AM/PM"" (or equivalent) after the time" & @CRLF & ";; If time falls within Range, TalkTock says" & @CRLF & ";;   Phrase after saying the time" & @CRLF & ";; You can set as many, or as few, of these pairs as you like" & @CRLF & ";; Note: Range# settings must have content (a time range hhmm-hhmm)" & @CRLF & ";;       Phrase# settings can be a phrase or empty (say nothing)" & @CRLF & ";Range1=0000-0000" & @CRLF & ";Phrase1=Midnight" & @CRLF& ";Range2=0001-0329" & @CRLF & ";Phrase2=A.M." & @CRLF& ";Range3=0330-1159" & @CRLF & ";Phrase3=in the morning" & @CRLF& ";Range4=1200-1200" & @CRLF & ";Phrase4=Noon" & @CRLF& ";Range5=1201-1659" & @CRLF & ";Phrase5=in the afternoon" & @CRLF& ";Range6=1700-1959" & @CRLF & ";Phrase6=in the evening" & @CRLF &  ";Range7=2000-2359" & @CRLF & ";Phrase7=at night" & @CRLF & ";; ------------------------" & @CRLF & ";" & @CRLF & "; Pause/Resume/Stop" & @CRLF & ";; Comment out (prepend "";"") to suppress these messages" & @CRLF & "onPause=" & $sdPause & @CRLF & "onResume=" & $sdResume & @CRLF & "onStop=" & $sdBye & @CRLF & @CRLF

        $sIniC &= "[GUI_Labels]" & @CRLF & "Title=" & $sgdTitle & @CRLF & "Top=" & $sgdTop & @CRLF & "Minute=" & $sgdMinute & @CRLF & "Minutes=" & $sgdMinutes & @CRLF & "QuarterHour=" & $sgdQuarterHour & @CRLF & "HalfHour=" & $sgdHalfHour & @CRLF & "Hour=" & $sgdHour & @CRLF & "Hours=" & $sgdHours & @CRLF & "CustomLabel=" & $sgdCustom & @CRLF & "ClockStyle=" & $sgdClock & @CRLF & "12-hour_Label=" & $sgd12hr_Label & @CRLF & "24-hour_Label=" & $sgd24hr_label & @CRLF & "Quiet_label=" & $sgdQuiet_label & @CRLF & "Speak_label=" & $sgdSpeak_label & @CRLF & "Display_label=" & $sgdDisplay_label & @CRLF & "ClockStop_Label=" & $sgdExpires & @CRLF & "ClockStopsNever_Label=" & $sgdExpNever & @CRLF & "ClockStopsAfter_Label=" & $sgdExpAfter & @CRLF & "ClockStopsAfterSecs_Label=" & $sgExpSecs & @CRLF & "ClockStopsAfterMins_Label=" & $sgExpMins & @CRLF & "ClockStopsAfterHours_Label=" & $sgExpHours & @CRLF & "ClockStopsAfterDays_Label=" & $sgdExpDays & @CRLF & "ClockStopsAfterWeeks_Label=" & $sgdExpWeeks & @CRLF & "ClockStopsAfterMons_Label=" & $sgdExpMons & @CRLF & "ClockStopsAfterYears_Label=" & $sgdExpYears & @CRLF & "Volume_Label=" & $sgdVolume_label & @CRLF & "ClockStop_Label=Clock stops" & @CRLF & "ClockStopsAfter_Label=After" & @CRLF & "ClockStopsHours_Label=hours" & @CRLF & "ClockStopsNever_Label=Never" & @CRLF & "Start_button=Start" & @CRLF & "Cancel_button=Cancel" & @CRLF & "Tray_pause=Pause" & @CRLF & "Tray_resume=Resume" & @CRLF & "Tray_exit=Stop" & @CRLF

        If Not FileWrite($hIni, $sIniC) Then MsgBox($MB_ICONWARNING, @ScriptName, "Error writing " & $sFini, 3)
        FileClose($hIni)
    EndIf
EndIf

Global $sFiniV = _IniFileReadFile($sFini)
If Not $sFiniV Then _ExitErr("Error reading " & $sFini)

; Read values from TalkTock.ini/alternate .ini
$iFreq = _IniFileRead("sFiniV", "TalkTock", "Interval", $idFreq)
$vT12or24 = _IniFileRead("sFiniV", "TalkTock", "ClockStyle", $vdT12or24)
$bSayAMPM = _IniFileRead("sFiniV", "TalkTock", "SayAMPM", $bdSayAMPM)
$sVoice = _IniFileRead("sFiniV", "TalkTock", "Voice", $sdVoice)
If StringUpper($sVoice) = "DEFAULT" Then $sVoice = ""
$iVol = _IniFileRead("sFiniV", "TalkTock", "Volume", $idVol)
$iRate = _IniFileRead("sFiniV", "TalkTock", "TalkRate", $idRate)
$iStop = _IniFileRead("sFiniV", "TalkTock", "ClockStops", $idStop)
$sUnits = _IniFileRead("sFiniV", "TalkTock", "ClockTimerUnits", $sdUnits)
$bQuiet = _IniFileRead("sFiniV", "TalkTock", "Quiet", $bdQuiet)
$iDisplay = _IniFileRead("sFiniV", "TalkTock", "Display", $idDisplay)

Global $bTimeOnly = _IniFileRead("sFiniV", "Language", "onStart", $bdTimeOnly)
$sHi = _IniFileRead("sFiniV", "Language", "onStart", "")
$sIntro = _IniFileRead("sFiniV", "Language", "Intro", "")
$sHowFreq1 = _IniFileRead("sFiniV", "Language", "Freq1", $sdHowFreq1)
$sHowFreq5 = _IniFileRead("sFiniV", "Language", "Freq5", $sdHowFreq5)
$sHowFreq10 = _IniFileRead("sFiniV", "Language", "Freq10", $sdHowFreq10)
$sHowFreq15 = _IniFileRead("sFiniV", "Language", "Freq15", $sdHowFreq15)
$sHowFreq30 = _IniFileRead("sFiniV", "Language", "Freq30", $sdHowFreq30)
$sHowFreq60 = _IniFileRead("sFiniV", "Language", "Freq60", $sdHowFreq60)
$sHowFreqCustom = _IniFileRead("sFiniV", "Language", "FreqCustom", $sdHowFreqCustom)
$sPrefix = _IniFileRead("sFiniV", "Language", "Prefix", "")
$sPrefix1 = _IniFileRead("sFiniV", "Language", "Prefix1", $sdPrefix1)
$sPause = _IniFileRead("sFiniV", "Language", "onPause", "")
$sResume = _IniFileRead("sFiniV", "Language", "onResume", "")
$sStopSay = _IniFileRead("sFiniV", "Language", "onStop", "")
$sBye = _IniFileRead("sFiniV", "Language", "onStop", "")

; GUI_Labels
$sgTitle = _IniFileRead("sFiniV", "GUI_Labels", "Title", $sgdTitle)
$sgTop = _IniFileRead("sFiniV", "GUI_Labels", "Top", $sgdTop)
$sgMinute = _IniFileRead("sFiniV", "GUI_Labels", "Minute", $sgdMinute)
$sgMinutes = _IniFileRead("sFiniV", "GUI_Labels", "Minutes", $sgdMinutes)
$sgQuarterHour = _IniFileRead("sFiniV", "GUI_Labels", "QuarterHour", $sgdHour)
$sgHalfHour = _IniFileRead("sFiniV", "GUI_Labels", "HalfHour", $sgdHours)
$sgHour = _IniFileRead("sFiniV", "GUI_Labels", "Hour", $sgdHour)
$sgHours = _IniFileRead("sFiniV", "GUI_Labels", "Hours", $sgdHours)
$sgCustom = _IniFileRead("sFiniV", "GUI_Labels", "CustomLabel", $sgdCustom)
$sgClock = _IniFileRead("sFiniV", "GUI_Labels", "ClockStyle", $sgdClock)
$sg12hr_label = _IniFileRead("sFiniV", "GUI_Labels", "12-hour_Label", $sgd12hr_Label)
$sg24hr_label = _IniFileRead("sFiniV", "GUI_Labels", "24-hour_Label", $sgd24hr_label)
$sgQuiet_label = _IniFileRead("sFiniV", "GUI_Labels", "Quiet_label", $sgdQuiet_label)
$sgSpeak_label = _IniFileRead("sFiniV", "GUI_Labels", "Speak_label", $sgdSpeak_label)
$sgDisplay_label = _IniFileRead("sFiniV", "GUI_Labels", "Display_label", $sgdDisplay_label)
;
$sgExpires = _IniFileRead("sFiniV", "GUI_Labels", "ClockStop_Label", $sgdExpires)
$sgExpNever = _IniFileRead("sFiniV", "GUI_Labels", "ClockStopsNever_Label", $sgdExpNever)
$sgExpAfter = _IniFileRead("sFiniV", "GUI_Labels", "ClockStopsAfter_Label", $sgdExpAfter)
$sgExpSecs = _IniFileRead("sFiniV", "GUI_Labels", "ClockStopsAfterSecs_Label", $sgdExpSecs)
$sgExpMins = _IniFileRead("sFiniV", "GUI_Labels", "ClockStopsAfterMins_Label", $sgdExpMins)
$sgExpHours = _IniFileRead("sFiniV", "GUI_Labels", "ClockStopsAfterHours_Label", $sgdExpHours)
$sgExpDays = _IniFileRead("sFiniV", "GUI_Labels", "ClockStopsAfterDays_Label", $sgdExpDays)
$sgExpWeeks = _IniFileRead("sFiniV", "GUI_Labels", "ClockStopsAfterWeeks_Label", $sgdExpWeeks)
$sgExpMons = _IniFileRead("sFiniV", "GUI_Labels", "ClockStopsAfterMons_Label", $sgdExpMons)
$sgExpYears = _IniFileRead("sFiniV", "GUI_Labels", "ClockStopsAfterYears_Label", $sgdExpYears)
;
Global $sgVolume = _IniFileRead("sFiniV", "GUI_Labels", "Volume_Label", $sgdVolume_label)
$sgStart_button = _IniFileRead("sFiniV", "GUI_Labels", "Start_button", $sgdStart_button)
$sgCancel_button = _IniFileRead("sFiniV", "GUI_Labels", "Cancel_button", $sgdCancel_button)
$sgPause = _IniFileRead("sFiniV", "GUI_Labels", "Tray_pause", $sgdPause)
$sgResume = _IniFileRead("sFiniV", "GUI_Labels", "Tray_resume", $sgdResume)
$sgExit = _IniFileRead("sFiniV", "GUI_Labels", "Tray_exit", $sgdExit)
;
Global $hTrayPA = TrayCreateItem($sgPause, -1, 0)
Global $hTrayEX = TrayCreateItem($sgExit, -1, 1)
TraySetClick(1)
TraySetState($TRAY_ICONSTATE_SHOW)
TrayItemSetOnEvent($hTrayPA, "_TrayPause")
TrayItemSetOnEvent($hTrayEX, "_TrayExit")

; Postfix pairs: get values
Global $aParts[100][2], $aFParts[100][2]
$aParts[0][0] = 0
If $bTimeOnly = 0 Then $aParts = PostfixPairsRead()

$sFiniV = ""
Global $oVox = ObjCreate("SAPI.spVoice")
If @error Then _ExitErr("SAPI error")
$oVox.Volume = $iVol
$oVox.Rate = $iRate

; Args so skip the GUI (except if arg = RESET)
If $CmdLine[0] > 0 Then
    $bArgs = 1
    If StringInStr($sCMline, "/s") Then $sVoice = _GetArgValue("/s")
    If StringInStr($sCMline, "-s") Then $sVoice = _GetArgValue("-s")
    Global $oVoices
    If $sVoice Then
        $oVoices = $oVox.GetVoices()
        For $vName in $oVoices
            If StringInStr($vName.GetDescription(), $sVoice) Then
                $oVox.Voice = $vName
                ExitLoop
            EndIf
        Next
    EndIf
    If StringInStr(StringUpper($CmdLine[1]), "RESET") Then
        Exit MsgBox($MB_OK, @ScriptName, "Default settings restored in " & $sFini)
    Else
        Exit MAIN()
    EndIf
EndIf

; GUI interface
; -------------
Global $hgTT = GUICreate($sgTitle, 638, 365, -1, -1, $WS_EX_APPWINDOW)
GUISetState(@SW_SHOW, $hgTT)
;#Region ### START Koda GUI section ### Form=TT1.kxf
;$GroupBox1 = GUICtrlCreateGroup("", -8, -32, 526, 822)
GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
GUICtrlSetColor(-1, 0x000000)
GUICtrlSetBkColor(-1, 0xFFFFFF)

Global $Label1 = GUICtrlCreateLabel($sgTop & ":", 8, 16, 137, 24)
Global $hgA = GUICtrlCreateCheckbox($sgMinute, 16, 48, 113, 17)
If $iFreq = 1 Then
    GUICtrlSetState($hgA, $GUI_CHECKED)
Else
    GUICtrlSetState($hgA, $GUI_UNCHECKED)
EndIf

Global $hgB = GUICtrlCreateCheckbox("5 " & $sgMinutes, 16, 72, 113, 17)
If $iFreq = 5 Then
    GUICtrlSetState($hgB, $GUI_CHECKED)
Else
    GUICtrlSetState($hgB, $GUI_UNCHECKED)
EndIf

Global $hgC = GUICtrlCreateCheckbox("10 " & $sgMinutes, 16, 96, 113, 17)
If $iFreq = 10 Then
    GUICtrlSetState($hgC, $GUI_CHECKED)
Else
    GUICtrlSetState($hgC, $GUI_UNCHECKED)
EndIf

Global $hgD = GUICtrlCreateCheckbox($sgQuarterHour, 16, 120, 113, 17)
If $iFreq = 15 Then
    GUICtrlSetState($hgD, $GUI_CHECKED)
Else
    GUICtrlSetState($hgD, $GUI_UNCHECKED)
EndIf

Global $hgE = GUICtrlCreateCheckbox($sgHalfHour, 16, 144, 113, 17)
If $iFreq = 30 Then
    GUICtrlSetState($hgE, $GUI_CHECKED)
Else
    GUICtrlSetState($hgE, $GUI_UNCHECKED)
EndIf

Global $hgF = GUICtrlCreateCheckbox($sgHour, 16, 168, 113, 17)
If $iFreq = 60 Then
    GUICtrlSetState($hgF, $GUI_CHECKED)
Else
    GUICtrlSetState($hgF, $GUI_UNCHECKED)
EndIf

Global $hgX = GUICtrlCreateCheckbox($sgCustom & ":", 16, 192, 80, 17)
Global $hgXt = GUICtrlCreateInput("", 96, 192, 41, 28)
Global $Label2 = GUICtrlCreateLabel(" " & $sgMinutes, 144, 192, 60, 24)
If Not StringInStr("|1|5|10|15|30|60|", "|" & $iFreq & "|") Then
    GUICtrlSetState($hgX, $GUI_CHECKED)
    GUICtrlSetState($hgX, $GUI_ENABLE)
    GUICtrlSetState($hgXt, $GUI_ENABLE)
    GUICtrlSetData($hgXt, $iFreq)
Else
    GUICtrlSetState($hgX, $GUI_UNCHECKED)
    GUICtrlSetState($hgXt, $GUI_DISABLE)
EndIf

Global $Label3 = GUICtrlCreateLabel($sgClock & ":", 180, 16, 79, 24)
Global $hgK = GUICtrlCreateCheckbox($sg12hr_label, 182, 48, 97, 17)
If $vT12or24 = 12 Then
    GUICtrlSetState($hgK, $GUI_CHECKED)
Else
    GUICtrlSetState($hgK, $GUI_UNCHECKED)
    $bSayAMPM = 0
EndIf

Global $hgL = GUICtrlCreateCheckbox($sg24hr_label, 182, 72, 97, 17)
If $vT12or24 = 24 Then
    GUICtrlSetState($hgL, $GUI_CHECKED)
    $bSayAMPM = 0
Else
    GUICtrlSetState($hgL, $GUI_UNCHECKED)
EndIf

Global $Label4 = GUICtrlCreateLabel($sgQuiet_label, 182, 130)
Global $hgSpeak = GUICtrlCreateCheckbox($sgSpeak_label, 265, 130, 205, 17)
GUICtrlSetState($hgSpeak, $GUI_ENABLE)
Global $hgDisplay = GUICtrlCreateCheckbox($sgDisplay_label, 265, 155, 205, 17)
GUICtrlSetState($hgDisplay, $GUI_ENABLE)
If $bQuiet = 0 Then
    GUICtrlSetState($hgSpeak, $GUI_CHECKED)
    GUICtrlSetState($hgDisplay, $GUI_UNCHECKED)
Else
    GUICtrlSetState($hgSpeak, $GUI_UNCHECKED)
    GUICtrlSetState($hgDisplay, $GUI_CHECKED)
EndIf

; Clock stops
Global $Label5 = GUICtrlCreateLabel($sgExpires & ":", 390, 16, 90, 24)
Global $hgExpNever = GUICtrlCreateCheckbox($sgExpNever, 392, 48, 97, 17)
If $iStop = 0 Then
    GUICtrlSetState($hgExpNever, $GUI_CHECKED + $GUI_ENABLE)
Else
    GUICtrlSetState($hgExpNever, $GUI_UNCHECKED + $GUI_ENABLE)
EndIf

Global $hgExp = GUICtrlCreateCheckbox($sgExpAfter, 398, 72, 65, 17)
If $iStop > 0 Then
    GUICtrlSetState($hgExp, $GUI_CHECKED + $GUI_ENABLE)
Else
    GUICtrlSetState($hgExp, $GUI_UNCHECKED + $GUI_ENABLE)
EndIf
Global $hgExpAft = GUICtrlCreateInput("", 456, 64, 41, 28)
If $iStop > 0 Then
    GUICtrlSetState($hgExpAft, $GUI_ENABLE)
    GUICtrlSetData($hgExpAft, $iStop)
Else
    GUICtrlSetState($hgExpAft, $GUI_DISABLE)
EndIf

Global $hgExpUsecs = GUICtrlCreateRadio($sgExpSecs, 414, 96, 113, 17)
If $iStop > 0 And $sUnits = "S" Then
    GUICtrlSetState($hgExpUsecs, $GUI_CHECKED + $GUI_ENABLE)
Else
    GUICtrlSetState($hgExpUsecs, $GUI_UNCHECKED + $GUI_DISABLE)
EndIf

Global $hgExpUmins = GUICtrlCreateRadio($sgExpMins, 414, 120, 113, 17)
If $iStop > 0 And $sUnits = "M" Then
    GUICtrlSetState($hgExpUmins, $GUI_CHECKED + $GUI_ENABLE)
Else
    GUICtrlSetState($hgExpUmins, $GUI_UNCHECKED + $GUI_DISABLE)
EndIf

Global $hgExpUhours = GUICtrlCreateRadio($sgExpHours, 414, 144, 113, 17)
If $iStop > 0 And $sUnits = "H" Then
    GUICtrlSetState($hgExpUhours, $GUI_CHECKED + $GUI_ENABLE)
Else
    GUICtrlSetState($hgExpUhours, $GUI_UNCHECKED + $GUI_DISABLE)
EndIf

Global $hgExpUdays = GUICtrlCreateRadio($sgExpDays, 414, 168, 113, 17)
If $iStop > 0 And $sUnits = "D" Then
    GUICtrlSetState($hgExpUdays, $GUI_CHECKED + $GUI_ENABLE)
Else
    GUICtrlSetState($hgExpUdays, $GUI_UNCHECKED + $GUI_DISABLE)
EndIf

Global $hgExpUweeks = GUICtrlCreateRadio($sgExpWeeks, 414, 192, 113, 17)
If $iStop > 0 And $sUnits = "W" Then
    GUICtrlSetState($hgExpUweeks, $GUI_CHECKED + $GUI_ENABLE)
Else
    GUICtrlSetState($hgExpUweeks, $GUI_UNCHECKED + $GUI_DISABLE)
EndIf

Global $hgExpUmons = GUICtrlCreateRadio($sgExpMons, 414, 216, 113, 17)
If $iStop > 0 And $sUnits = "T" Then
    GUICtrlSetState($hgExpUmons, $GUI_CHECKED + $GUI_ENABLE)
Else
    GUICtrlSetState($hgExpUmons, $GUI_UNCHECKED + $GUI_DISABLE)
EndIf

Global $hgExpUyears = GUICtrlCreateRadio($sgExpYears, 414, 240, 113, 17)
If $iStop > 0 And $sUnits = "Y" Then
    GUICtrlSetState($hgExpUyears, $GUI_CHECKED + $GUI_ENABLE)
Else
    GUICtrlSetState($hgExpUyears, $GUI_UNCHECKED + $GUI_DISABLE)
EndIf

Global $iX = 8
GUICtrlCreateLabel($sgVolume_label, 8, 230+12)
Global $hgV = GUICtrlCreateSlider(8, 255+12, 360)
GUICtrlSetLimit($hgV, 100, 1)
GUICtrlSetData($hgV, $iVol)
GUICtrlSetState($hgV, $GUI_SHOW)
GUICtrlCreateLabel("0", $iX, 280, 360)
GUICtrlCreateLabel("20", $iX + 1*71, 280, 360)
GUICtrlCreateLabel("40", $iX + 2*70, 280, 360)
GUICtrlCreateLabel("60", $iX + 1 + 3*70, 280, 360)
GUICtrlCreateLabel("80", $iX - 2 + 4*69, 280, 360)
GUICtrlCreateLabel("100", $iX - 2 + 5*69, 280, 360)

GUICtrlCreateGroup("", -99, -99, 1, 1)
Global $hgStart = GUICtrlCreateButton($sgStart_button, 534, 22, 92, 30, $BS_DEFPUSHBUTTON)
GUICtrlSetState($hgStart, $GUI_FOCUS)

Global $hgCancel = GUICtrlCreateButton($sgCancel_button, 534, 62, 92, 31)
GUISetState(@SW_SHOW)
; #EndRegion ### END Koda GUI section ###

If $bQuiet = 0 Then
    If $sHi Then _SayTxt($sHi)
EndIf

WHILE 1

Switch GUIGetMsg()
    Case $hgA
        $iFreq = 1
        GUICtrlSetState($hgA, $GUI_CHECKED)
        GUICtrlSetState($hgB, $GUI_UNCHECKED)
        GUICtrlSetState($hgC, $GUI_UNCHECKED)
        GUICtrlSetState($hgD, $GUI_UNCHECKED)
        GUICtrlSetState($hgE, $GUI_UNCHECKED)
        GUICtrlSetState($hgF, $GUI_UNCHECKED)
        GUICtrlSetState($hgX, $GUI_UNCHECKED)
        GUICtrlSetState($hgXt, $GUI_DISABLE)

    Case $hgB
        $iFreq = 5
        GUICtrlSetState($hgA, $GUI_UNCHECKED)
        GUICtrlSetState($hgB, $GUI_CHECKED)
        GUICtrlSetState($hgC, $GUI_UNCHECKED)
        GUICtrlSetState($hgD, $GUI_UNCHECKED)
        GUICtrlSetState($hgE, $GUI_UNCHECKED)
        GUICtrlSetState($hgF, $GUI_UNCHECKED)
        GUICtrlSetState($hgX, $GUI_UNCHECKED)
        GUICtrlSetState($hgXt, $GUI_DISABLE)

    Case $hgC
        $iFreq = 10
        GUICtrlSetState($hgA, $GUI_UNCHECKED)
        GUICtrlSetState($hgB, $GUI_UNCHECKED)
        GUICtrlSetState($hgC, $GUI_CHECKED)
        GUICtrlSetState($hgD, $GUI_UNCHECKED)
        GUICtrlSetState($hgE, $GUI_UNCHECKED)
        GUICtrlSetState($hgF, $GUI_UNCHECKED)
        GUICtrlSetState($hgX, $GUI_UNCHECKED)
        GUICtrlSetState($hgXt, $GUI_DISABLE)

    Case $hgD
        $iFreq = 15
        GUICtrlSetState($hgA, $GUI_UNCHECKED)
        GUICtrlSetState($hgB, $GUI_UNCHECKED)
        GUICtrlSetState($hgC, $GUI_UNCHECKED)
        GUICtrlSetState($hgD, $GUI_CHECKED)
        GUICtrlSetState($hgE, $GUI_UNCHECKED)
        GUICtrlSetState($hgF, $GUI_UNCHECKED)
        GUICtrlSetState($hgX, $GUI_UNCHECKED)
        GUICtrlSetState($hgXt, $GUI_DISABLE)

    Case $hgE
        $iFreq = 30
        GUICtrlSetState($hgA, $GUI_UNCHECKED)
        GUICtrlSetState($hgB, $GUI_UNCHECKED)
        GUICtrlSetState($hgC, $GUI_UNCHECKED)
        GUICtrlSetState($hgD, $GUI_UNCHECKED)
        GUICtrlSetState($hgE, $GUI_CHECKED)
        GUICtrlSetState($hgF, $GUI_UNCHECKED)
        GUICtrlSetState($hgX, $GUI_UNCHECKED)
        GUICtrlSetState($hgXt, $GUI_DISABLE)

    Case $hgF
        $iFreq = 60
        GUICtrlSetState($hgA, $GUI_UNCHECKED)
        GUICtrlSetState($hgB, $GUI_UNCHECKED)
        GUICtrlSetState($hgC, $GUI_UNCHECKED)
        GUICtrlSetState($hgD, $GUI_UNCHECKED)
        GUICtrlSetState($hgE, $GUI_UNCHECKED)
        GUICtrlSetState($hgF, $GUI_CHECKED)
        GUICtrlSetState($hgX, $GUI_UNCHECKED)
        GUICtrlSetState($hgXt, $GUI_DISABLE)

    Case $hgX
        $bCanned = 0
        GUICtrlSetState($hgA, $GUI_UNCHECKED)
        GUICtrlSetState($hgB, $GUI_UNCHECKED)
        GUICtrlSetState($hgC, $GUI_UNCHECKED)
        GUICtrlSetState($hgD, $GUI_UNCHECKED)
        GUICtrlSetState($hgE, $GUI_UNCHECKED)
        GUICtrlSetState($hgF, $GUI_UNCHECKED)
        GUICtrlSetState($hgX, $GUI_CHECKED)
        GUICtrlSetState($hgXt, $GUI_ENABLE)

    Case $hgXt
        $bCanned = 0
        $iFreq = GUICtrlRead($hgXt)

    Case $hgK
        $vT12or24 = 12
        $bSayAMPM = 0
        GUICtrlSetState($hgK, $GUI_CHECKED)
        GUICtrlSetState($hgL, $GUI_UNCHECKED)

    Case $hgL
        $vT12or24 = 24
        $bSayAMPM = 0
        GUICtrlSetState($hgK, $GUI_UNCHECKED)
        GUICtrlSetState($hgL, $GUI_CHECKED)

    Case $hgDisplay
        $bQuiet = 1
        GUICtrlSetState($hgSpeak, $GUI_UNCHECKED)
        GUICtrlSetState($hgDisplay, $GUI_CHECKED)

    Case $hgSpeak
        $bQuiet = 0
        GUICtrlSetState($hgSpeak, $GUI_CHECKED)
        GUICtrlSetState($hgDisplay, $GUI_UNCHECKED)

    Case $hgV
        $iVol = GUICtrlRead($hgV)
        GUICtrlSetState($hgV, $GUI_ENABLE)
        Global $aCartesian = MouseGetPos()
        ToolTip($iVol, $aCartesian[0], $aCartesian[1], "", 0, 2)
        Sleep(500)
        ToolTip("")
        GUICtrlSetState($hgV, $GUI_CHECKED)

    Case $hgExp
        GUICtrlSetState($hgExp, $GUI_CHECKED)
        GUICtrlSetState($hgExpNever, $GUI_UNCHECKED)
        GUICtrlSetState($hgExpAft, $GUI_ENABLE)
        GUICtrlSetState($hgExpUsecs, $GUI_UNCHECKED + $GUI_ENABLE)
        GUICtrlSetState($hgExpUmins, $GUI_UNCHECKED + $GUI_ENABLE)
        GUICtrlSetState($hgExpUhours, $GUI_CHECKED + $GUI_ENABLE)
        GUICtrlSetState($hgExpUdays, $GUI_UNCHECKED + $GUI_ENABLE)
        GUICtrlSetState($hgExpUweeks, $GUI_UNCHECKED + $GUI_ENABLE)
        GUICtrlSetState($hgExpUmons, $GUI_UNCHECKED + $GUI_ENABLE)
        GUICtrlSetState($hgExpUyears, $GUI_UNCHECKED + $GUI_ENABLE)

    Case $hgExpAft
        $iStop = GUICtrlRead($hgExpAft)
        If Not StringIsDigit($iStop) Then $iStop = 0
        Case $hgExpUsecs
        $sUnits = "S"
        Case $hgExpUmins
        $sUnits = "M"
    Case $hgExpUhours
        $sUnits = "H"
    Case $hgExpUdays
        $sUnits = "D"
    Case $hgExpUweeks
        $sUnits = "W"
    Case $hgExpUmons
        $sUnits = "T"
    Case $hgExpUyears
        $sUnits = "Y"

    Case $hgExpNever
        $iStop = 0
        GUICtrlSetState($hgExpNever, $GUI_CHECKED)
        GUICtrlSetState($hgExp, $GUI_UNCHECKED)
        GUICtrlSetState($hgExpAft, $GUI_DISABLE)
        GUICtrlSetState($hgExpUsecs, $GUI_UNCHECKED + $GUI_DISABLE)
        GUICtrlSetState($hgExpUmins, $GUI_UNCHECKED + $GUI_DISABLE)
        GUICtrlSetState($hgExpUhours, $GUI_CHECKED + $GUI_DISABLE)
        GUICtrlSetState($hgExpUdays, $GUI_UNCHECKED + $GUI_DISABLE)
        GUICtrlSetState($hgExpUweeks, $GUI_UNCHECKED + $GUI_DISABLE)
        GUICtrlSetState($hgExpUmons, $GUI_UNCHECKED + $GUI_DISABLE)
        GUICtrlSetState($hgExpUyears, $GUI_UNCHECKED + $GUI_DISABLE)

    Case $hgStart
        GUISetState(@SW_HIDE, $hgTT)
        MAIN()

    Case $hgCancel
        ContinueCase

    Case $GUI_EVENT_CLOSE
        ; _SayTxt($sBye)
        If Not $sFini2 Then WriteTTini()
        Exit
EndSwitch

WEND

; Function definitions
; --------------------
Func MAIN() ; TalkTock

    If $sFini2 = "" And $CmdLine[0] > 0 Then
    ; ----------------------------------------
        If StringInStr($CmdLine[1], "/L") Then Exit MsgBox($MB_OK, @ScriptName, _ListVoices())
        If StringInStr($CmdLine[1], "/source") Then Exit _ShowSource("txt")
        If StringInStr($CmdLine[1], "/?") = 1 Or StringInStr($CmdLine[1], "-?") = 1 Or StringInStr($CmdLine[1], "/h") = 1 Or StringInStr($CmdLine[1], "-h") = 1 Then Exit _ShowHelp()
        If StringInStr($CmdLine[1], "sayhelp") Then Exit _SayHelp()
        If StringInStr($CmdLine[1], "kill") Then
            Local $aP = ProcessList(@ScriptName)
            Local $iP = $aP[0][0] - 1
            If $iP > 0 Then
;               Local $sT = "Killing " & $iP & @ScriptName
;               _Splash($sT & " process(es)")
                _Splash("Killing " & StringTrimRight(@ScriptName, 4))
                Sleep(1000)
                SplashOff()
                While ProcessClose(@ScriptName)
                    Sleep(100)
                WEnd
                Exit
            Else
                _ExitErr("No running " & StringTrimRight(@ScriptName, 4) & " processes")
            EndIf
        EndIf

        If StringInStr($sCMline, "/i") Then $iFreq = _GetArgValue("/i")
        If StringInStr($sCMline, "-i") Then $iFreq = _GetArgValue("-i")
        If StringInStr($sCMline, "/c") Then $vT12or24 = _GetArgValue("/c")
        If StringInStr($sCMline, "-c") Then $vT12or24 = _GetArgValue("-c")
        If StringInStr($sCMline, "/v") Then $iVol = _GetArgValue("/v")
        If StringInStr($sCMline, "-v") Then $iVol = _GetArgValue("-v")
        If StringInStr($sCMline, "/q") Or StringInStr($sCMline, "-q") Then $bQuiet = 1
        If StringInStr($sCMline, "/qq") Or StringInStr($sCMline, "-qq") Then $bQuiet = 0
        If StringInStr($sCMline, "/t") Or StringInStr($sCMline, "-t") Then
            $bTimeOnly = 1
            $bSayAMPM = 0
        EndIf
        If StringInStr($sCMline, "/r") Then $iRate = _GetArgValue("/r")
        If StringInStr($sCMline, "-r") Then $iRate = _GetArgValue("-r")
        Local $sU = "H"
        If StringInStr($sCMline, "/u ") Then $sU = _GetArgValue("/u")
        If StringInStr($sCMline, "-u ") Then $sU = _GetArgValue("-u")
        If StringInStr($sU, "=") Then
            Local $aU = StringSplit($sU, "=")
            $sUnits = $aU[1]
            If $aU[0] > 1 Then $iStop = $aU[2]
            If Not $iStop Then $iStop = 0
            Switch $sU
                Case "S"
                    $sUnits = "seconds"
                Case "M"
                    $sUnits = "minutes"
                Case "H"
                    $sUnits = "hours"
                Case "D"
                    $sUnits = "days"
                Case "W"
                    $sUnits = "weeks"
                Case "T"
                    $sUnits = "months"
                Case "Y"
                    $sUnits = "years"
            EndSwitch
        EndIf
        If StringInStr($sCMline, "/usefile") Then $sFini = _GetArgValue("/usefile")
        If StringInStr($sCMline, "-usefile") Then $sFini = _GetArgValue("-usefile")
    EndIf
; --------------------

If $bTimeOnly = 1 Then
    $sHi = ""
#cs
    $sIntro = ""
    $sHowFreq1 = ""
    $sHowFreq5 = ""
    $sHowFreq10 = ""
    $sHowFreq15 = ""
    $sHowFreq30 = ""
    $sHowFreq60 = ""
    $sHowFreqCustom = ""
#ce
    $sPrefix = ""
    $sPrefix1 = ""
    $sMidnight = ""
    $sMidday = ""
    $sPause = ""
    $sResume = ""
    $sStopSay = ""
    $sBye = ""
EndIf

#cs; debug
;Exit MsgBox(0,"", _
MsgBox(0,"", _
"$bTimeOnly = " & $bTimeOnly & @CRLF & _
"$iFreq = " & $iFreq & @CRLF & _
"$vT12or24 = " & $vT12or24 & @CRLF & _
"$sVoice = " & $sVoice & @CRLF & _
"$iVol = " & $iVol & @CRLF & _
"$iRate = " & $iRate & @CRLF & _
"$iStop = " & $iStop & @CRLF & _
"$sUnits = " & $sUnits & @CRLF & _
"$bQuiet = " & $bQuiet & @CRLF & _
"$iDisplay = " & $iDisplay & @CRLF)
#ce; debug

; Failsafe defaults
    If Not StringIsDigit(String($iFreq)) Then $iFreq = 15
    If Not $vT12or24 = "24" Then $vT12or24 = 12
    If Not StringIsDigit(String($iVol)) Then $iVol = 80
    If $iVol > 100 Then $iVol = 100
    If String(Abs($iRate)) <> String($iRate) Then $iRate = 0
    If $iRate < -10 Or $iRate > 10 Then $iRate = 0
    If Not StringIsDigit(String($iStop)) Then $iStop = 0
    If Not StringInStr("|S|M|H|D|W|T|Y|", ("|" & $sUnits & "|")) Then $sUnits = "H"

    Local $sAllFreqs = "|1|5|10|15|30|60|", $sHowFreq = ""
    If StringInStr($sAllFreqs, "|" & $iFreq & "|") < 1 Then $bCanned = 0
    If Not $bCanned Then
        If StringIsDigit(String($iFreq)) Then
            $iFreq = Int($iFreq)
            If $iFreq < 1 Then Exit _ShowHelp()
        Else
        EndIf
    EndIf

    If $bCanned Then
        Switch $iFreq
            Case 1
                $sHowFreq = $sHowFreq1
            Case 5
                $sHowFreq = $sHowFreq5
            Case 10
                $sHowFreq = $sHowFreq10
            Case 15
                $sHowFreq = $sHowFreq15
            Case 30
                $sHowFreq = $sHowFreq30
            Case 60
                $sHowFreq = $sHowFreq60
            EndSwitch
    Else
        $sHowFreq = $iFreq & " " & $sHowFreqCustom
    EndIf

    If Not $sFini2 Then
        If Not $bArgs Then WriteTTini()
    EndIf

    If $bQuiet = 0 Then
        If $sIntro Then _SayTxt($sIntro & " " & $sHowFreq)
    Else
        $sHowFreq = StringReplace($sHowFreq, "minnit", " minute")
        $sHowFreq = StringReplace($sHowFreq, "'", "h")
        If StringLen($sHowFreq) > 10 Then $sHowFreq = @CRLF & $sHowFreq
        If $sHowFreq Then
            If $sIntro Then _Splash($sIntro & " " & $sHowFreq)
        EndIf
        Sleep(2000)
        SplashOff()
    EndIf

    If $iStop > 0 Then $iIter = _SetTimer($iStop, $sUnits)

    If $bCanned Then
        While 1
            Do
                Sleep(200)
            Until @SEC = 00 And Mod(@MIN, $iFreq) = 0
            _SayTime($vT12or24)
            _CheckTimer()
            Sleep(45000)
        WEnd
    Else ; Custom interval
        Local $iMin, $iNext
        While 1
            $iMin = @MIN
            _CheckTimer()
            If $iFreq = 60 Then Sleep(60500)
            $iNext = StringFormat("%02i", Mod($iMin + $iFreq, 60))
            Do
                Sleep(100)
            Until Int(@MIN) = Int($iNext) And Int(@SEC) = 0
            _SayTime($vT12or24)
        WEnd
    EndIf

EndFunc   ;==>MAIN
; ---------------

Func _GetArgValue($sArg)
; Get value (if any) following /SWitch (arg)
    Local $sVal = ""
    If $CmdLine[0] > 1 Then
        For $i = 1 To $CmdLine[0]
            If $sArg = $CmdLine[$i] Then
                If $CmdLine[0] > $i Then
                    $sVal = StringStripWS($CmdLine[$i + 1], 1)
                    If StringInStr($sVal, "/") = 1 Or StringInStr($sVal, "-") = 1 Then
                        If StringInStr($sArg, "r") = 2 And StringInStr($sVal, "-") And StringIsDigit(StringTrimLeft($sVal, 1)) Then
                            Return $sVal
                        Else
                            Return ""
                        EndIf
                    EndIf
                EndIf
            EndIf
        Next
    EndIf
    Return $sVal
EndFunc  ;==>_GetArgValue

Func _SetTimer($iN, $sUnits = "H")
    If StringLen($sUnits) > 1 Then
        $sUnits = StringLeft($sUnits, 3)
        If $sUnits = "mon" Then $sUnits = "T"
        $sUnits = StringUpper(StringLeft($sUnits, 1))
    EndIf
    Local $iM = 0
    Switch $sUnits
        Case "S"
            $iM = 0.16
        Case "M"
            $iM = 1
        Case "H"
            $iM = 60
        Case "D"
            $iM = 1440
        Case "W"
            $iM = 10080
        Case "T"
            $iM = 43200
        Case "Y"
            $iM = 525600
    EndSwitch
    Return Ceiling(($iM * $iN) / $iFreq)
EndFunc   ;==>_SetTimer

Func _CheckTimer()
    If $iIter > -1 Then $iIter -= 1
    If $iIter = 0 Then Exit MsgBox($MB_OK, StringTrimRight(@ScriptName, 4), StringTrimRight(@ScriptName, 4) & " quitting...", 5)
    Return
EndFunc   ;==>_CheckTimer

Func _ExitErr($sMg, $iSecs = 0)
    Exit MsgBox($MB_OK + $MB_ICONERROR, @ScriptName, $sMg, $iSecs)
EndFunc   ;==>_ExitErr

Func _IniFileRead($sVarName, $sSection, $sKey, $sDefault)
#cs; -----------------------------------------------
     IniRead with default text encoding
     @error codes:
     1 = Variable $sVarName Not Declared
     2 = Error reading contents of $sVarName
     3 = Section not found
     4 = Key not found
     5 = Key not found in section
#ce; -----------------------------------------------
    If Not IsDeclared($sVarName) Then
        If $sDefault Then
            Return $sDefault
        Else
            Return SetError(1, "Variable " & $sVarName & " is not declared", "")
        EndIf
    EndIf
    Local $sFc = Eval($sVarName)
    If Not $sFc Then
        If $sDefault Then
            Return $sDefault
        Else
            Return SetError(2, "Error reading INI file contents", "")
        EndIf
    EndIf
    Local $sCrLf = @LF
    $sFc = StringReplace($sFc, @CRLF, $sCrLf)
    Local $iXsec = StringInStr(StringUpper($sFc), $sCrLf & "[" & StringUpper($sSection) & "]")
    If $iXsec < 1 Then
        If $sDefault Then
            Return $sDefault
        Else
            Return SetError(3, "Section not found", "")
        EndIf
    EndIf
    $iXsec += StringLen($sCrLf & "[" & StringUpper($sSection) & "]")
    Local $sSecC = $sCrLf & StringTrimLeft($sFc, $iXsec)
    If StringInStr($sSecC, $sCrLf & "[") And StringInStr($sSecC, "]" & $sCrLf) > StringInStr($sSecC, $sCrLf & "[") Then _
$sSecC = StringTrimRight($sSecC, StringLen($sSecC) - StringInStr($sSecC, $sCrLf & "["))
    If Not StringInStr(StringUpper($sSecC), StringUpper($sKey) & "=") Then
        If $sDefault Then
            Return $sDefault
        Else
            Return SetError(4, "Key not found", "")
        EndIf
    EndIf
    Local $sVal0 = StringTrimLeft($sSecC, StringInStr($sSecC, $sCrLf & $sKey & "="))
    $sVal0 = StringTrimRight($sVal0, 1 + StringLen($sVal0) - StringInStr($sVal0, String($sCrLf)))
    Local $sValue = StringTrimLeft($sVal0, StringInStr($sVal0, "="))
    If Not $sValue Then $sValue = $sDefault
    Return SetError(0, 0, $sValue)
EndFunc  ;==>_IniFileRead

Func _IniFileReadFile($sFn)
#cs; ------------------------------------------------
     Read INI file contents into a (string) variable
     @error codes:
     1 = $sVarName Is Not Declared
     2 = Error reading $sVarName
     3 = Section does not exit
     4 = Key does not exit
#ce; ------------------------------------------------
    If Not FileExists($sFn) Then Return SetError(1, 0, "")
    Local $h = FileOpen($sFn)
    If $h = -1 Then Return SetError(2, 0, "")
    Local $sFc = FileRead($h)
    If Not FileClose($h) Then Return SetError(3, 0, "")
    If StringRight($sFc, 1) = Chr(26) Then $sFc = StringTrimRight($sFc, 1)
    Return @CRLF & $sFc
EndFunc  ;==>_IniFileReadFile

Func _ListVoices()
    $oVox = ObjCreate("SAPI.spVoice")
    If @error Then Exit _ExitErr("Error creating SAPI object", 10)
    $oVoices = $oVox.GetVoices()
    Local $sVlist = ""
    For $vName in $oVoices
        $sVlist &= $vName.GetDescription() & @CRLF
    Next
    Return $sVlist
EndFunc  ;==>_ListVoices

Func _PauseVoice($iBeats = 1)
    If StringIsDigit(String($iBeats)) Then
        $iBeats = Int($iBeats)
        Sleep($iBeats * 100)
    EndIf
    Return
EndFunc   ;==>_PauseVoice

Func _SayHelp()
    _SayTxt("Welcome to TalkTock, The Talking Clock.")
    _PauseVoice(1)
    _SayTxt("To get started, command START, space, forward slash, M,I,N, space, TalkTock, Enter. Choose your settings, and click Start.")
    _PauseVoice(1)
    _SayTxt("For command-line help, command TalkTock, space, forward slash, question mark, and hit Enter.")
    _PauseVoice(1)
    _SayTxt("To view and customize all available TalkTock settings, open TalkTock dot I,N,I, in any text editor.")
    _PauseVoice(1)
    _SayTxt("I hope you enjoy TalkTock!")
    Return
EndFunc   ;==>_SayHelp

Func _SayTime($vTime12or24 = 12)
    Local $h = Int(@HOUR)
    Local $sAMPM = ""
    Local $sPostfix = PostfixPairsSet()
    If $vTime12or24 = "12" Then
        If $bSayAMPM Then
            Select
                Case $h = 0
                    If @MIN = "00" Then
                        $sAMPM = $sMidnight
                    Else
                        $sAMPM = "AM"
                    EndIf
                Case $h < 12
                    $sAMPM = "AM"
                Case $h = 12
                    If @MIN = "00" Then
                        $sAMPM = $sMidday
                    Else
                        $sAMPM = "PM"
                    EndIf
                Case Else
                    $sAMPM = "PM"
            EndSelect
        EndIf
        If $h > 11 Then $h = Mod($h, 12)
        If $h = 0 Then $h = 12
    EndIf
    If $sPrefix1 And Int($h) = 1 Then $sPrefix = $sPrefix1
    If Not $sPostfix Then $sPostfix = $sAMPM
    Local $sTime = $sPrefix & " " & $h & ":" & @MIN & " " & $sPostfix
    If $bQuiet > 0 Then
        _Splash($sTime)
        If $iDisplay < 1 Then $iDisplay = 1
        Sleep(Int(1000 * $iDisplay))
        SplashOff()
    Else
        _SayTxt($sTime)
    EndIf
    Return
EndFunc   ;==>_SayTime

Func _SayTxt($sIn)
; Text-to-Speech
    Local $iRC = -1
    If $sIn Then
        $oVox.Speak($sIn)
        $iRC = StringLen($sIn)
    EndIf
    Return $iRC
EndFunc   ;==>_SayTxt

Func _ShowHelp()
    MsgBox($MB_OK, @ScriptName & " - Talking Clock", $sHelp)
EndFunc   ;==>_ShowHelp

Func _ShowSource($postfx) ; Show source code
    Local $Ext
    If Not $postfx Then
        $Ext = "txt"
    Else
        $Ext = $postfx
    EndIf
    Local $TmpFile = @TempDir & "\ausource." & $Ext
    If FileExists($TmpFile) Then
        If FileGetAttrib($TmpFile) = "R" Then FileSetAttrib($TmpFile, "-R")
    EndIf
    Select
        Case $Ext = "txt"
            FileInstall("X:\ausource.txt", $TmpFile, 1)
        Case $Ext = "pdf"
        ;FileInstall("X:\ausource.pdf", $TmpFile, 1)
    EndSelect
    Sleep(50)
    ShellExecute($TmpFile, "", @TempDir, "open")
EndFunc   ;==>_ShowSource

Func _Splash($sTxt)
    SplashTextOn(@ScriptName, $sTxt, 650, 150, -1, -1, 32, "", 14, 600)
    Return
EndFunc   ;==>_Splash

Func _TmpFile($sDir = @TempDir, $sExt = "tmp", $iLen = 8, $sPre = "")
; Generate a non-existent 8.3 filename
; Returns null string on failure
    Local $aA = StringSplit("ABCDEFGHIJKLMNPQRSTUVWXYZ123456789", "")
    Local $sX = "nul", $itr = 0
    If $sPre Then $iLen -= StringLen($sPre)
    While FileExists($sX)
        $itr += 1
        $sX = $sPre
        For $i = 1 To $iLen
            $sX &= $aA[Random(1, $aA[0])]
        Next
        $sX = $sDir & "\" & $sX & "." & $sExt
        If $itr > 50 Then
            $sX = ""
            ExitLoop
        EndIf
    WEnd
    Return $sX
EndFunc   ;==>_TmpFile

Func _TrayPause()
    If TrayItemGetText($hTrayPA) = $sgPause Then
        TrayItemSetText($hTrayPA, $sgResume)
        If $bQuiet = 0 Then
            _SayTxt($sPause)
        Else
            _Splash($sPause)
            Sleep(1500)
            SplashOff()
        EndIf
    Else
        TrayItemSetText($hTrayPA, $sgPause)
        If $bQuiet = 0 Then
            _SayTxt($sResume)
        Else
            _Splash($sResume)
            Sleep(1500)
            SplashOff()
        EndIf
        Return
    EndIf
    Do
        Sleep(200)
    Until TrayItemGetState($hTrayPA) Or TrayItemGetState($hTrayEX)
EndFunc   ;==>_TrayPause

Func _TrayExit()
    If Not $sFini2 Then
        If Not $bArgs Then WriteTTini()
    EndIf
    If $bQuiet = 0 Then
        _SayTxt($sBye)
    Else
        _Splash($sBye)
        Sleep(1000)
        SplashOff()
    EndIf
    Exit
EndFunc   ;==>_TrayExit

Func PostfixPairsRead()
    $aFParts[0][0] = 0
    Local $sValPt = "", $sValSp = ""
    For $n = 1 To 99
        $sValPt = _IniFileRead("sFiniV", "Language", "Range" & $n, "")
        If $sValPt Then
            $sValSp = _IniFileRead("sFiniV", "Language", "Phrase" & $n, "")
            $aFParts[$n][0] = $sValPt
            $aFParts[$n][1] = $sValSp
        Else
            $aFParts[0][0] = $n - 1
            ExitLoop
        EndIf
    Next
    Return $aFParts
EndFunc   ;==>PostfixPairsRead

Func PostfixPairsSet()
    Local $vTime = String(@HOUR & @MIN)
    Local $sPostfix = "", $aPtt
    If $bTimeOnly = 0 And $aParts[0][0] > 0 Then
        For $z = 1 To $aParts[0][0]
            $aPtt = StringSplit($aParts[$z][0], "-")
            If $vTime >= $aPtt[1] And $vTime <= $aPtt[2] Then ExitLoop
        Next
        $sPostfix = $aParts[$z][1]
    EndIf
    Return $sPostfix
EndFunc   ;==>PostfixPairsSet

Func WriteTTini()
    IniWrite($sFini, "TalkTock", "Interval", $iFreq)
    IniWrite($sFini, "TalkTock", "ClockStyle", $vT12or24)
    IniWrite($sFini, "TalkTock", "SayAMPM", $bSayAMPM)
    If $sVoice = "" Then $sVoice = "default"
    IniWrite($sFini, "TalkTock", "Voice", $sVoice)
    IniWrite($sFini, "TalkTock", "Volume", $iVol)
    IniWrite($sFini, "TalkTock", "TalkRate", $iRate)
    IniWrite($sFini, "TalkTock", "ClockStops", $iStop)
    IniWrite($sFini, "TalkTock", "ClockTimerUnits", $sUnits)
    IniWrite($sFini, "TalkTock", "Quiet", $bQuiet)
    IniWrite($sFini, "TalkTock", "Display", $iDisplay)
EndFunc   ;==>WriteTTini

Func RestartTT()
    Local $hgRE = GUICreate(@ScriptName, 350, 150, -1, -1, $ES_CENTER)
    GUISetState(@SW_HIDE, $hgRE)
    GUICtrlCreateLabel(@ScriptName & " is running. What would you like to do?", 18, 22, 337, 24)
    Local $hgREStart = GUICtrlCreateButton("Restart", 20, 55, 70, -1, $BS_DEFPUSHBUTTON)
    Local $hgREQuit = GUICtrlCreateButton("Quit", 105, 55, 70, -1, -1)
    Local $hgRECancel = GUICtrlCreateButton("Cancel", 190, 55, 70, -1, -1)
;----------
    Local $aTTp = ProcessList(@ScriptName)
    Local $iThis = @AutoItPID
    GUISetState(@SW_SHOW, $hgRE)
    While 1
        Switch GUIGetMsg($hgRE)
            Case $hgREStart
                For $q = 1 To $aTTp[0][0]
                    If $aTTp[$q][1] <> $iThis Then ProcessClose($aTTp[$q][1])
                Next
                GUIDelete($hgRE)
                ExitLoop
            Case $hgREQuit
                For $q = 1 To $aTTp[0][0]
                    If $aTTp[$q][1] <> $iThis Then ProcessClose($aTTp[$q][1])
                Next
                ContinueCase
            Case $hgRECancel
                ContinueCase
            Case $GUI_EVENT_CLOSE
                Exit
        EndSwitch
    WEnd
;----------
EndFunc  ;==>ReStartTT

Settings file (TalkTock.ini):

Settings file for TalkTock.exe, Talking Clock
;
[TalkTock]
;; Interval between time announcements, in minutes
Interval=15
;; 12- or 24-hour clock
ClockStyle=12
;; Say AM/PM? 1=Yes 0=No; applies to 12-hour clock only
SayAMPM=1
;; TTS voice
Voice=default
;Voice=Microsoft George
;; Volume, range 1 to 100
Volume=80
;; Speaking rate, range -10 to 10
TalkRate=0
;; Clock stop timer units
;; S=secs M=mins H=hours D=days W=weeks T=months Y=years
ClockTimerUnits=H
;; Clock stops after how many timer units? (0 = clock never stops)
ClockStops=0
;; Quiet operation, time shown on screen (1=yes 0=no)
Quiet=0
;; Duration, in seconds, of on-screen time display
;; Fractional (decimal) values are allowed (e.g., Display=3.5)
Display=2.5

[Language]
;; Translate the phrases and labels below into your chosen language.
;; Any language with a TTS function (a "Voice") in its language pack
;; should work. To use other languages, edit TalkTock.ini using the
;; UTF-8 character set
;
;; TimeOnly: 1=Yes (phrases set below will NOT be spoken); 0=No
TimeOnly=0
;
; Welcome and Intro messages
;; Comment out (prepend ";") to suppress these messages
onStart=Welcome to TalkTock, the Talking Clock
Intro=The time will be announced every
;
; Interval descriptions
Freq1=minnit
Freq5=5 minutes at the 5-minute mark
Freq10=10 minutes at the 10-minute mark
Freq15=15 minutes on the quarter hour
Freq30=30 minutes on the half hour
Freq60='our on the hour
FreqCustom=minutes
;; Spoken prefix
Prefix=It's
;; No prefix (just announce the time):
;Prefix=
;Prefix=It's
;Prefix=It's now
;Prefix=The time is
;; Singular prefix: Prefix1 defines the singular inflection
;; for "one o'clock" in applicable languages, e.g., Italian
;Prefix1=
;; Postfix at midnight (0000 hours) and midday (1200 hours)
;;  See also Postfix pairs, below
At0000Say=midnight
At1200Say=noon
;
;; Postfix pairs (optional)
;; ------------------------
;; Alternatives to saying "AM/PM" (or equivalent) after the time
;; If time falls within Range, TalkTock says
;;   Phrase after saying the time
;; You can set as many, or as few, of these pairs as you like
;; Note: Range# settings must have content (a time range hhmm-hhmm)
;;       Phrase# settings can be a phrase or empty (say nothing)
;Range1=0000-0000
;Phrase1=Midnight
;Range2=0001-0329
;Phrase2=A.M.
;Range3=0330-1159
;Phrase3=in the morning
;Range4=1200-1200
;Phrase4=Noon
;Range5=1201-1659
;Phrase5=in the afternoon
;Range6=1700-1959
;Phrase6=in the evening
;Range7=2000-2359
;Phrase7=at night
;; ------------------------
;
; Pause/Resume/Stop
;; Comment out (prepend ";") to suppress these messages
onPause=TalkTock paused
onResume=TalkTock resumed
onStop=Goodbye

[GUI_Labels]
Title=TalkTock - Talking Clock
Top=Say the time every
Minute=minute
Minutes=minutes
QuarterHour=quarter hour
HalfHour=half hour
Hour=hour
Hours=hours
CustomLabel=Custom
ClockStyle=Clock style
12-hour_Label=12-hour
24-hour_Label=24-hour
Quiet_label=Time is: 
Speak_label=spoken
Display_label=displayed
ClockStop_Label=Clock stops 
ClockStopsNever_Label= Never
ClockStopsAfter_Label= After 
ClockStopsAfterSecs_Label=secs
ClockStopsAfterMins_Label=mins
ClockStopsAfterHours_Label=hours
ClockStopsAfterDays_Label=days
ClockStopsAfterWeeks_Label=weeks
ClockStopsAfterMons_Label=months
ClockStopsAfterYears_Label=years
Volume_Label=Volume
ClockStop_Label=Clock stops
ClockStopsAfter_Label=After
ClockStopsHours_Label=hours
ClockStopsNever_Label=Never
Start_button=Start
Cancel_button=Cancel
Tray_pause=Pause
Tray_resume=Resume
Tray_exit=Stop

Enjoy!

Edited by CarlD
Update
Posted (edited)
29 minutes ago, argumentum said:

I'd like to run it but the EXE is quite large and the source would not have what it needs to run as expected.
Would you modify the source and include all the files in a ZIP ?

Not sure what mods to the source file you need, but this ZIP should have everything. Please let me know if you need anything else.

Also, if there's a way to make the EXE smaller, I'd like to know about it. I'm already compiling with UPX. Thanks.

Edited by CarlD
Posted
7 minutes ago, argumentum said:

my compile is less than 900 kb, yours is over 2,000 kb. Maybe I'm missing "source.pdf" ?

You're right, argumentum. I sometimes include a pdf of my source that has syntax highlighting, but I didn't mean to include it here, precisely because it adds so much "weight". I've taken it out now and the compressed EXE is only 740 KB. Many thanks for pointing this out!

  • Moderators
Posted

Hi,

Someone reported this thread with no comments as to why they felt it was necessary to do so - and I can see no reason why a report was required. If you report a thread, please do give the Mods some idea of why you have done so - unless it is so obvious that even we can see it for ourselves!

Thanks for everyone's cooperation.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Posted (edited)

Added option to "splash" the time announcement to the screen (in addition to, not instead of, spoken time). It's best to delete TalkTock.ini before running the new version.

Edited by CarlD
Posted

Option to splash time to screen is now an alternative to spoken time -- i.e., silent operation. Please delete (or rename) TalkTock.ini before running the new version.

Posted

Today: Tidied up the source, fixed code-page issues relating to Italian-language examples; added a code window showing the default .INI file, to give a sense of the available options.

Posted

Latest revisions:

  • Reorganized GUI screen
  • Added option /L to list available voices
  • Added option /S "voice name" to select a voice (can also just edit "Voice=" setting in .INI)

Delete or rename TalkTock.ini before running the new version.

Posted

Latest revisions:

  • Added user-defined function _IniFileRead() to preserve character encoding of TalkTock.ini settings for Language and GUI Labels. (Func IniRead() imports all settings as Ascii.)
  • TalkTock.ini is English only. Added TockTock.it.ini and TockTock.ru.ini as sample Italian- and Russian-language settings files.

Delete or rename TalkTock.ini before running the new version.

Posted (edited)
  • Fixed error in _IniFileRead()
  • Added options to ListVoices utility. Command ListVoices.exe /? for info.
Edited by CarlD
Posted (edited)
  • Temp file creation error -- fixed
  • GUI screen errors -- fixed
  • Simplified .INI file

 

Edited by CarlD
Posted (edited)

Removed TalkTock.ru.ini (Russian-language settings) from TalkTock.zip. Russian-language clock has stopped working, for some mysterious reason.

Edited by CarlD

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...