Well, heres the version I finished a few days ago
#NoTrayIcon
#SingleInstance, Force
;SetTimer, RealTime, 1000
Active = False
Count = 0
Gui, Add, Button, w100 h25 gStart vStartWp, Start
Gui, Add, Button, w100 h25 yp xp+102 gPause, Pause
Gui, Add, Button, w100 yp xp+102 h25 gStop, Stop
Gui, Add, Text, vCountWp x10 w300 , Current Number: %Count%
;Gui, Add, Text, vCountSWp x10 w300 , Actual Elapsed Seconds: 0
Gui, +AlwaysOnTop
Gui, Show
return
Stop:
!s::
BreakLoop = True
Count = 0
GuiControl,,CountWp,Current Number: 0 (Stopped)
GuiControl,,StartWp,Start
SoundBeep
Active = False
return
Pause:
!p::
BreakLoop = True
GuiControl,,StartWp,Resume
SoundBeep
Active = False
GuiControl,,CountWp,Current Number: %Count% (Paused)
return
Start:
GuiControl,,StartWp,Start
Active = True
BreakLoop = False
SetTimer, CountTime, 1000
return
CountTime:
If BreakLoop = True
{
SetTimer, CountTime, Off
Active = False
}
If Active = False
return
Count += 1
GuiControl,,CountWp,Current Number: %Count%
;return
;RealTime:
If Active = False
return
RealCount += 1
;GuiControl,,CountSWp,Actual Elapsed Seconds: %RealCount%
TTS(Count)
return
TTS(sSpeechText, dwFlags=0)
{
;For info on the dwFlags bitmask see the SAPI helpfile:
;http://download.microsoft.com/download/speechSDK/SDK/5.1/WXP/EN-US/sapi.chm
static TTSInitialized, ppSpVoice, pSpeak
wSpeechTextBufLen:=VarSetCapacity(wSpeechText, StrLen(sSpeechText)*2+2,0)
DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, "Str", sSpeechText, "Int", -1, "UInt", &wSpeechText, "Int", wSpeechTextBufLen/2)
if !TTSInitialized
{
ComInit := DllCall("ole32\CoInitialize", "Uint", 0)
if ComInit not in 0,1
return "CoInitialize() failed: " ComInit
sCLSID_SpVoice:="{96749377-3391-11D2-9EE3-00C04F797396}"
sIID_ISpeechVoice:="{269316D8-57BD-11D2-9EEE-00C04F797396}"
;Make space for unicode representations.
wCLSID_SpVoiceBufLen:=VarSetCapacity(wCLSID_SpVoice, StrLen(sCLSID_SpVoice)*2+2)
wIID_ISpeechVoiceBufLen:=VarSetCapacity(wIID_ISpeechVoice, StrLen(sIID_ISpeechVoice)*2+2)
;Convert to unicode
DllCall("MultiByteToWideChar", "UInt",0, "UInt",0, "Str",sCLSID_SpVoice, "Int",-1, "UInt",&wCLSID_SpVoice, "Int",wCLSID_SpVoiceBufLen/2)
DllCall("MultiByteToWideChar", "UInt",0, "UInt",0, "Str",sIID_ISpeechVoice, "Int",-1, "UInt",&wIID_ISpeechVoice, "Int",wIID_ISpeechVoiceBufLen/2)
;Convert string representations to originals.
VarSetCapacity(CLSID_SpVoice, 16)
VarSetCapacity(IID_ISpeechVoice, 16)
if ret:=DllCall("ole32\CLSIDFromString", "str", wCLSID_SpVoice, "str", CLSID_SpVoice)
{
DllCall("ole32\CoUninitialize")
return "CLSIDFromString() failed: " ret
}
if ret:=DllCall("ole32\IIDFromString", "str", wIID_ISpeechVoice, "str", IID_ISpeechVoice)
{
DllCall("ole32\CoUninitialize")
return "IIDFromString() failed: " ret
}
;Obtain ISpeechVoice Interface.
if ret:=DllCall("ole32\CoCreateInstance", "Uint", &CLSID_SpVoice, "Uint", 0, "Uint", 1, "Uint", &IID_ISpeechVoice, "UintP", ppSpVoice)
{
DllCall("ole32\CoUninitialize")
return "CoCreateInstance() failed: " ret
}
;Get pointer to interface.
DllCall("ntdll\RtlMoveMemory", "UintP", pSpVoice, "Uint", ppSpVoice, "Uint", 4)
;Get pointer to Speak().
DllCall("ntdll\RtlMoveMemory", "UintP", pSpeak, "Uint", pSpVoice + 4*28, "Uint", 4)
if ret:=DllCall(pSpeak, "Uint", ppSpVoice, "str" , wSpeechText, "Uint", dwFlags, "Uint", 0)
{
DllCall("ole32\CoUninitialize")
return "ISpeechVoice::Speak() failed: " ret
}
DllCall("ole32\CoUninitialize")
TTSInitialized = 1
return
}
if ret:=DllCall(pSpeak, "Uint", ppSpVoice, "str" , wSpeechText, "Uint", dwFlags, "Uint", 0)
return "ISpeechVoice::Speak() failed: " ret
}
Features:
- Press start to make it start counting. It will keep going forever just as long as the script doesn't close
- The pause key is now fully functional
- There is also a little counter at the bottom that displays the current number.
- And one more thing - hotkeys. Alt+P to pause counting, Alt+S to stop counting
Known Limitations:
- If the script is counting a very large number (ex. one trillion, ten billion, one million, ten thousand, three hundred and fifty four.

) the script will take a few seconds to pause/stop (it will first finish saying the current number)