1 (изменено: serzh82saratov, 2017-11-30 22:43:40)

Тема: AHK: Часы, таймер, секундомер

Класс позволяет добавлять контролы в виде табло часов. Встроены таймеры для часов, таймера и секундомера. Также с помощью контрола пользователь может выставить нужное ему время.

Ввод времени - LButton, RButton, WheelUp, WheelDown, MButton - сброс на 00, нижнее табло в Demo.

Тема для обсуждения.

+ Demo.

#SingleInstance Force
#Persistent
#NoEnv
ListLines Off
SetBatchLines -1

Gui, +HWNDhMain -DPIScale
Gui, Color, F9D886

Timer := New ClockGui(hMain, "Sec|Name MyTimer|w 400|h 120|ds 1|db 16|bckgmain F9D886|Font s80|Colon")
Timer.Show(10, 10, "10:00:04")
Timer.StartTimer("")

Watch := New ClockGui(hMain, "Sec|Name MyWatch|w 400|h 120|ds 1|db 10|bckgmain F9D886|bckgitem FFFFFF|coloritem F9D886|Font s80")
Watch.Show(10, 140, "23:59:56")
Watch.StartWatch("", 1)

Clock := New ClockGui(hMain, "w 400|h 120|db 20|bckgitem C0C0C0|coloritem 5671BD|Font s90|FontName Comic Sans MS|Colon Flash 100")
Clock.StartClock()
Clock.Show(10, 300)

Clock2 := New ClockGui(hMain, "Sec|w 60|h 30|db 6|bckgitem F9D886|coloritem 5671BD|Font Bold|Colon Flash")
Clock2.StartClock()
Clock2.Show(10, 425)

TestTimer := New ClockGui(hMain, "Sec|Name TestTimer|w 400|h 120|ds 1|db 14|bckgmain 444444|Font s80|Colon Flash 300")
TestTimer.Show(10, 460, "00:00:03")

Gui, Add, Button, xp60 y+10 gTimerStart, Запустить таймер
Gui, Add, Button, x+20 yp gTimerStop, Остановить
Gui, Add, Button, x+20 yp gTimerReset, Сбросить
Gui, Show
Return

TimerStart:
	TestTimer.StartTimer("EndTimer")
	Return

TimerStop:
	TestTimer.Stop(1)
	TestTimer.Block(0)
	Return

TimerReset:
	Gosub, TimerStop
	TestTimer.SetTime("00:00:03")
	Return

EndTimer(This) {
	MsgBox % This.Name "`nВремя вышло"
	(!This.Loop && This.Block(0))
}

GuiClose:
	ExitApp
+ Запуск секундомера и таймера относительно времени суток.

#SingleInstance Force
#NoEnv
ListLines Off
SetBatchLines -1

CheckTime := ClockGui.MathTime("", "+", "00:00:03")   ;	прибавляем к текущему времени три секунды. это будет стартовым временем суток таймера и секундомера

Gui, +HWNDhMain
Gui, Color, F9D886
TestTimer := New ClockGui(hMain, "Sec|Name Timer1|w 400|h 120|ds 1|db 10|bckgmain F9D886|Font s80")
TestTimer.Show(10, 10)
;	1 - указываем функцию обработчик при наступлении стартового времени. Можно оставить пустым - ""
;	2 - стартовое время. Если пусто, то текущее время. Если "User" то будет взято время установленное в TestTimer вручную
;	3 - если последний параметр правда, то при наступлении стартового времени отсчёт продолжается на следующие сутки
TestTimer.StartTimerDay("EndTimer" , CheckTime, 1)

Clock := New ClockGui(hMain, "Sec|w 400|h 120|db 20|bckgmain F9D886|bckgitem C0C0C0|coloritem 5671BD|Font s80|Colon Flash")
Clock.Show(10, 140)
Clock.StartClock()

Watch := New ClockGui(hMain, "Sec|Name Watch1|w 400|h 120|ds 1|db 10|bckgmain F9D886|bckgitem FFFFFF|coloritem F9D886|Font s80")
Watch.Show(10, 270 )
Watch.StartWatchDay("EndTimer", CheckTime, 1)

Gui, Show
Return

EndTimer(This) {
	MsgBox % This.Name " - контрольное время " This.CheckDate " достигнуто"
}

GuiClose:
	ExitApp
+ Выстывляем время суток, запускаем цикличный таймер до указанного времени.

#SingleInstance Force
#NoEnv
ListLines Off
SetBatchLines -1

Gui, +HWNDhMain
Gui, Color, F9D886

Clock := New ClockGui(hMain, "Sec|w 60|h 30|db 6|bckgitem F9D886|coloritem 5671BD|Font Bold|Colon Flash")
Clock.StartClock()
Clock.Show(340, 0)

Timer := New ClockGui(hMain, "Sec|Name Timer|w 400|h 120|ds 1|db 14|bckgmain 444444|Font s80|Colon Flash")
Timer.Show(10, 40, "00:00:00")

Gui, Add, Button, xp115 y+10 gTimerStart, Запустить таймер
Gui, Add, Button, x+20 yp gTimerReset, Сброс

Gui, Show
Return

TimerStart:
	Timer.StartTimerDay("EndTimer", "User", 1)
	Return
	
TimerReset:
	Timer.Reset()
	Timer.Block(0)
	Return
	
EndTimer(This) {
	MsgBox % This.Name " - контрольное время " This.CheckDate " достигнуто"
}

GuiClose:
	ExitApp

https://ic.pics.livejournal.com/the_bestseller/49384395/14996/14996_900.png

+ Таймер с мелодией:

#SingleInstance Force
#NoEnv
ListLines Off
SetBatchLines -1
OnMessage(0x404, "AHK_NOTIFYICON")

PlayFile = путь к файлу мелодии
TimeStart = 00:00:00
VolumeStart = 6
StartHide := 600  ;	0 - нескрывать после старта, или кол-во мс через которое скрывать

Menu, Tray, UseErrorLevel
Menu, Tray, Icon, Shell32.dll, 266
Menu, Tray, Click, 1
Menu, Tray, NoStandard
Menu, Tray, Add, Min/Max, MinMax
Menu, Tray, Default, Min/Max
Menu, Tray, Disable, Min/Max
Menu, Tray, Add, Close, Exit

Gui, +HWNDhMain +AlwaysOnTop +Owner -MinimizeBox -MaximizeBox
Gui, Color, F9D886
Gui, Margin, 10, 10
Gui, Font, s14
Timer := New ClockGui(hMain, "Sec|Timer|w 500|h 120|ds 1|db 20|bckgmain 444444|bckgitem 212121|coloritem FFFFFF|Font s90|Colon Flash")
Timer.Show(10, 10, TimeStart)
Gui, Add, Text, xp y+10 wp vInfo Center r2
Gui, Add, Button, xp y+10 gTimerStart, Запустить таймер
Gui, Add, Button, x+39 yp gTimerStop, Остановить
Gui, Add, Button, x+39 yp gTimerReset, Сбросить
Gui, Add, Checkbox, x10 y+20 vPlaySound gCheckbox Checked1, Проигрывать мелодию
Gui, Add, Slider, x+10 yp-10 w203 vVolumeSlider hwndhVolumeSlider gSlider Center AltSubmit, % VolumeStart
Gui, Add, Text, x+10 yp+8 vTextVolume w40 Center, % VolumeStart
Gui, Show, , Таймер
GuiControlGet, VolumeSlider
GuiControlGet, PlaySound
Return

#If Playing
Space::
	Gosub, MinMax
	GoSub, Stop
	Return

EndTimer(This) {
	Global
	This.Stop(1), This.Block(0)
	This.SetTime(Duration)
	GuiColor("E5684A")
	Playing := 1
	SetTimer, Playing, -1
	Gui, Show
	This.SetTime("00:00:00")
	This.StartWatch("", 1)
	TrayTip  ;	, % "Сработал таймер`n, прошло: " Duration, % " ", , 1
	GuiControl, , Info, % "сработал таймер`nпродолжительность: " Duration
	SetTimer, MinMax, Off
}

Playing:
	GuiControl, Disable, PlaySound
	If !PlaySound
		Return
	SoundGet, PrVolume
	SoundSet, %VolumeSlider%
	SoundPlay, %PlayFile%
	Return

SoundStop:
	SoundPlay, ::
	SoundSet, %PrVolume%
	Return

TimerStart:
	If Playing
		GoTo, Stop
	If !Timer.StartTimer("EndTimer")
		Return
	GuiColor("55C335")
	TrayTip, % "Запущен таймер`n, продолжительность: " , % (TimeAddStr(Duration := Timer.Get(), 2)), , 1
	; TrayTip, % "Запущен таймер`n, сработает через: " (Duration := Timer.Get()), % " ", , 1
	 
	GuiControl, , Info, % "запущен в: " A_Hour ":" A_Min ":" A_Sec "    сработает в: " Timer.MathTime("", "+", Timer.Get()) "`nпродолжительность: " TimeAddStr(Duration, 2)
	; GuiControl, , Info, % "запущен в: " A_Hour ":" A_Min ":" A_Sec "    сработает в: " Timer.MathTime("", "+", Timer.Get()) "`nпродолжительность: " Duration
	If StartHide
		SetTimer, MinMax, -%StartHide%
	Return

Stop:
	If (Playing && PlaySound)
		GoSub, SoundStop
	Playing := 0
	GuiColor("F9D886")
	Timer.Stop(1), Timer.Block(0)
	GuiControl, Enable, PlaySound
	SetTimer, MinMax, Off
	GuiControl, , Info
	Timer.SetTime(Duration)
	Return

TimerStop:
	GoSub, Stop
	Return

TimerReset:
	GoSub, Stop
	Timer.SetTime(TimeStart)
	Return

GuiEscape:
GuiClose:
	Gosub, MinMax
	If Playing
		GoSub, Stop
	Return

Exit:
	ExitApp
	Return

MinMax:
	Gui, Show, % !DllCall("IsWindowVisible", "Ptr", hMain) ? "" : "Hide"
	Return

Slider:
	GuiControlGet, VolumeSlider
	GuiControl, , TextVolume, % VolumeSlider
	If (Playing && PlaySound)
		SoundSet, %VolumeSlider%
	Return

Checkbox:
	GuiControlGet, PlaySound
	Return

AHK_NOTIFYICON(wParam,lParam,Msg,hwnd) {
	Global
	If (lParam = 0x200) ; move
		Menu, Tray, Tip, % "Таймер" (Playing || Timer.Stop() ? "" : "`nОсталось: " Timer.Get() " из " Duration)
}

GuiColor(Color) {
	Static prColor
	If (prColor = Color)
		Return
	Gui, Color, % (prColor := Color)
	GuiControl, Disable, VolumeSlider
	GuiControl, Enable, VolumeSlider
}

TimeAddStr(Time, Trim=0, d=" ") {
	Local k, v, r1, r2, r3
	Static m := [["час","часа","часов"],["минута","минуты","минут"],["секунда","секунды","секунд"]]
	, s := {1:1,2:2,3:2,4:2,5:3,6:3,7:3,8:3,9:3,0:3}
	For k, v in StrSplit(Time, ":") {
		(!v) && (Trim >= k || (k = 3 && r1 || r2)) 
		|| (v > 10 && v < 20) && (1, r%k% := v + 0 " " m[k][3] d)
		|| (r%k% := v + 0 " " m[k][s[SubStr(v, 0)]] d)
	} Return RTrim(r1 r2 r3, d)
}

https://ic.pics.livejournal.com/the_bestseller/49384395/15537/15537_900.png

+ Class ClockGui.

Class ClockGui {
	;  Автор - serzh82saratov
	;  Описание - http://forum.script-coding.com/viewtopic.php?id=12931
	Static WM_LBUTTONDOWN := 0x201, WM_LBUTTONDBLCLK := 0x203, WM_RBUTTONDOWN := 0x204
	, WM_RBUTTONDBLCLK := 0x206, WM_MOUSEWHEEL := 0x020A, WM_MBUTTONDOWN := 0x0207, Mem := {}

	__New(hParent, Option) {
		Local Font, FontName, Width, Height, Sec, Name, DB, DS, hH1, hH2, hM1, hM2, hS1, hS2, hF1, hF2, W, FlashTime, Flash
		, Colon, Colon_O, S_DefaultGui, S_FormatInteger, RealWidth, hWnd, ColorItem, BckgItem, BckgMain, Off, k, v, rm, rm1
		This.Initialize()
		S_FormatInteger := A_FormatInteger
		SetFormat, IntegerFast, D
		Option := "|" Option "|"
		Width := This.Option("W", Option, 0)
		Height := This.Option("H", Option, 0)
		DS := This.Option("DS", Option, 0)
		DB := This.Option("DB", Option, 0)
		BckgMain := This.Option("BckgMain", Option, "Default")
		BckgItem := This.Option("BckgItem", Option, "000000")
		ColorItem := This.Option("ColorItem", Option, "ffffff")
		Name := This.Option("Name", Option)
		Font := This.Option("Font", Option)
		FontName := This.Option("FontName", Option)
		Sec := !!RegExMatch(Option, "i)\|\s*Sec\s*\|")
		Colon := !!RegExMatch(Option, "i)\|\s*Colon\s*\|")

		If (Colon_O := This.Option("Colon", Option)) && (Colon := 1)
			InStr(Colon_O, "Flash") && (Flash := 1) && !RegExMatch(Colon_O, "\d+", FlashTime) && (FlashTime := 500)
		If FlashTime > 950
			Throw "FlashTime не может быть больше чем 950"
		W := (Width - (DS * (Sec ? 3 : 2) + DB * (Sec ? 2 : 1))) / (Sec ? 6 : 4)

		S_DefaultGui := A_DefaultGui
		Gui, New
		Gui, +HWNDhWnd -DPIScale -Caption +0x40000000 -0x80000000  ; Add WS_CHILD, remove WS_POPUP, setparent no deactivate main gui
		Gui, Color, %BckgItem%
		Gui, Margin, 0, 0
		Gui, Font, %Font%, %FontName%

		Gui, Add, Text, x0 y0 w%W% h%Height% +0x201 +0x100 c%ColorItem% HwndhH1
		Gui, Add, Progress, x+0 yp hp w%DS% Background%BckgMain%
		Gui, Add, Text, x+0 y0 w%W% hp +0x201 +0x100 c%ColorItem% HwndhH2

		If Colon
		{
			Off := (RegExMatch(Colon_O, "i)v(\d+)", rm) ? rm1 : Height / 6)
			Gui, Add, Progress, x+0 yp hp w%DS% Background%BckgMain%
			Gui, Add, Text, % "+0x201 x+0 yp-" Off " hp+" Off " w" (DB - DS * 2) " c" ColorItem " HwndhF1", :
			Gui, Add, Progress, x+0 y0 h%Height% w%DS% Background%BckgMain%
		}
		Else
			Gui, Add, Progress, x+0 yp hp w%DB% Background%BckgMain%

		Gui, Add, Text, x+0 y0 w%W% hp +0x201 +0x100 c%ColorItem% HwndhM1
		Gui, Add, Progress, x+0 yp hp w%DS% Background%BckgMain%
		Gui, Add, Text, x+0 y0 w%W% hp +0x201 +0x100 c%ColorItem% HwndhM2
		If Sec
		{
			If Colon
			{
				Gui, Add, Progress, x+0 yp hp w%DS% Background%BckgMain%
				Gui, Add, Text, % "+0x201 x+0 yp-" Off " hp+" Off " w" (DB - DS * 2) " c" ColorItem " HwndhF2", :
				Gui, Add, Progress, x+0 y0 h%Height% w%DS% Background%BckgMain%
			}
			Else
				Gui, Add, Progress, x+0 yp hp w%DB% Background%BckgMain%
			Gui, Add, Text, x+0 y0 w%W% hp +0x201 +0x100 c%ColorItem% HwndhS1
			Gui, Add, Progress, x+0 yp hp w%DS% Background%BckgMain%
			Gui, Add, Text, x+0 y0 w%W% hp +0x201 +0x100 c%ColorItem% HwndhS2
		}
		Gui, +Parent%hParent%
		Gui, Show, Hide NA AutoSize
		Gui, %S_DefaultGui%:Default
		WinGetPos, , , RealWidth, , ahk_id %hWnd%

		For, k, v in ["hWnd","Name","Sec","RealWidth","FlashTime","hParent"
		,"Height","Flash","hH1","hH2","hM1","hM2","hS1","hS2","hF1","hF2"]
			This[v] := %v%
		For k, v in ["H1","H2","M1","M2","S1","S2"]
			This.Mem.Ctrl[h%v%] := {Gui:hWnd, Name:v}
		This.Mem.Gui[hWnd] := This, This.Stop(1)
		SetFormat, IntegerFast, %S_FormatInteger%
	}
	Initialize() {
		Static Start
		Local Class
		If Start
			Return
		Class := This.__Class, Class := %Class%, Start := 1
		OnMessage(Class.WM_LBUTTONDOWN, ObjBindMethod(Class, "OnButtonDown"))
		OnMessage(Class.WM_LBUTTONDBLCLK, ObjBindMethod(Class, "OnButtonDown"))
		OnMessage(Class.WM_RBUTTONDOWN, ObjBindMethod(Class, "OnButtonDown"))
		OnMessage(Class.WM_RBUTTONDBLCLK, ObjBindMethod(Class, "OnButtonDown"))
		OnMessage(Class.WM_MOUSEWHEEL, ObjBindMethod(Class, "OnMouseWheel"))
		OnMessage(Class.WM_MBUTTONDOWN, ObjBindMethod(Class, "OnMbuttonDown"))
	}
	Show(x, y, time="") {
		Local hDummy
		If time
			This.SetTime(time)
		Else If This.Watch
			This.Set("00", "00", "00")
		Else
			This.Set(A_Hour, A_Min, A_Sec)
		x := Format("{:d}", x), y := Format("{:d}", y)
		Gui, % This.hParent ":Add", Text, % "Hidden HWNDhDummy x" x " y" y " w" This.RealWidth " h" This.Height
		DllCall("DestroyWindow", "Ptr", hDummy)
		Gui, % This.hWnd ":Show", NA x%x% y%y%
	}
	Hide() {
		Gui, % This.hWnd ":Hide"
	}
	Move(x, y) {
		x := Format("{:d}", x), y := Format("{:d}", y)
		Gui, % This.hWnd ":Show", NA x%x% y%y% 
	}
	Stop(Param = "") {
		If Param =
			Return This._Stop
		This._Stop := Param
		If !Param
			This.Block(1)
		If Param && This.InDay
			This.InDay := 0
		If Param && This.Flash
			This.ColonView()
	}
	Block(Param = "") {
		If Param !=
			This._Block := Param
		Return This._Block
	}
	Option(key, option, ret="") {
		Local Match, Match1
		RegExMatch(option, "iS)\|\s*" key "\s+(.*?)\s*\|", Match)
		Return ret != "" && Match1 = "" ? ret  : Match1
	}
	OnButtonDown(wp, lp, msg, hwnd) {
		If !This.Mem.Ctrl.HasKey(hwnd) || (This.Mem.Gui[A_Gui]).Block()
			Return
		If (msg = This.WM_LBUTTONDOWN || msg = This.WM_LBUTTONDBLCLK)
			This.Step(1, This.Mem.Ctrl[hwnd].Name, A_Gui)
		Else
			This.Step(0, This.Mem.Ctrl[hwnd].Name, A_Gui)
		Return 1
	}
	OnMouseWheel(wp, lp, Msg, hwnd) {
		Local hCtrl
		MouseGetPos, , , , hCtrl, 2
		If !This.Mem.Ctrl.HasKey(hCtrl) || (This.Mem.Gui[This.Mem.Ctrl[hCtrl].Gui]).Block()
			Return
		This.Step((wp >> 16) = 120 ? 1 : 0, This.Mem.Ctrl[hCtrl].Name, This.Mem.Ctrl[hCtrl].Gui)
		Return 1
	}
	OnMbuttonDown(wp, lp, Msg, hwnd) {
		Local o, l
		If !This.Mem.Ctrl.HasKey(hwnd) || (o := This.Mem.Gui[A_Gui]).Block()
			Return
		l := SubStr(This.Mem.Ctrl[hwnd].Name, 1, 1)
		GuiControl, % A_Gui ":", % o["h" l 1], % o[l 1] := "0"
		GuiControl, % A_Gui ":", % o["h" l 2], % o[l 2] := "0"
		Return 1
	}
	Step(add, c, hwnd, o="", b=0) {
		Static a := {H1:2,H2:9,M1:5,M2:9,S1:5,S2:9}
		o := This.Mem.Gui[hwnd]
		o[c] := Format("{:d}", add ? (o[c] = a[c] ? 0 : o[c] + 1) : (o[c] = 0 ? a[c] : o[c] - 1))
		If InStr(c, "h") && (o.H1 o.H2 > 23) && (1, b := c = "H2")
			GuiControl, % o.hwnd ":", % o["hH2"], % o.H2 := (c = "H1" || add ? "0" : "3")
		If !b
			GuiControl, % o.hwnd ":", % o["h" c], % o[c]
	}
	Set(h, m, s) {
		Local k, v, d
		For k, v in ["H1","H2","M1","M2","S1","S2"]
			If This[v] != (d := SubStr(h m s, k, 1))
				GuiControl, % This.hwnd ":", % This["h" v], % This[v] := Format("{:d}", d)
	}
	SetTime(Time) {
		Local o
		o := StrSplit(Time, ":")
		This.Set(o[1], o[2], o[3])
	}
	Get(obj=0) {
		Local Time
		Time := This.h1 This.h2 ":" This.m1 This.m2 ":" This.s1 This.s2
		Return obj ? StrSplit(Time, ":") : Time
	}
	StartClock() {
		Local obj
		If !This.Stop()
			Return 0
		This.Stop(0), This.Timer := 0, This.Watch := 0, This.InDay := 0, This.Loop := 0
		This.Set(A_Hour, A_Min, A_Sec)
		obj := ObjBindMethod(This, "TimerClock")
		SetTimer, % obj, % "-" (1000 - A_Msec) + 100
		Return 1
	}
	StartTimer(Func="") {
		Local TimerPeriod, obj
		If !This.Stop() || This.Get() = "00:00:00"
			Return 0
		This.Stop(0)
		TimerPeriod := This.HMSToMSec(This.h1 This.h2, This.m1 This.m2, This.s1 This.s2)
		If !TimerPeriod
			Return 0, This.Stop(1)
		This.TimerStart := A_TickCount + 1000, This.TimerStartMsec := A_Msec
		This.TimerPeriod := TimerPeriod, This.Func := Func, This.Timer := 1, This.Watch := 0, This.InDay := 0, This.Loop := 0
		obj := ObjBindMethod(This, "TimerTimer")
		SetTimer, % obj, % "-" 1100
		Return 1
	}
	StartWatch(Func="", Loop=0) {
		Local obj
		If !This.Stop()
			Return 0
		This.Stop(0)
		This.WatchStart := A_TickCount - This.HMSToMSec(This.h1 This.h2, This.m1 This.m2, This.s1 This.s2)
		This.WatchStartMsec := A_Msec, This.Func := Func, This.Timer := 0, This.Watch := 1, This.InDay := 0, This.Loop := Loop
		obj := ObjBindMethod(This, "TimerWatch")
		SetTimer, % obj, % "-" 1100
		Return 1
	}
	StartTimerDay(Func="", Date="", Loop=0) {
		Local TimerPeriod, obj
		If !This.Stop()
			Return 0
		If Date = User
			TimerPeriod := This.DifferenceTime((This.CheckDate := This.Get()), A_Hour ":" A_Min ":" A_Sec, 1) - A_Msec
		Else If Date
			TimerPeriod := This.DifferenceTime((This.CheckDate := Date), A_Hour ":" A_Min ":" A_Sec, 1) - A_Msec
		Else
			TimerPeriod := 86400000 - A_Msec, This.CheckDate := A_Hour ":" A_Min ":" A_Sec
		If !TimerPeriod
			Return 0, This.Stop(1)
		This.TimerStart := A_TickCount + 1000, This.TimerStartMsec := 0, This.TimerPeriod := TimerPeriod
		This.Timer := 1, This.Watch := 0, This.InDay := 1, This.Func := Func, This.Stop(0), This.Loop := Loop
		This.SetTime(This.FormatTime(TimerPeriod))
		obj := ObjBindMethod(This, "TimerTimer")
		SetTimer, % obj, % "-" 10
		Return 1
	}
	StartWatchDay(Func="", Date="", Loop=0) {
		Local obj
		If !This.Stop()
			Return 0
		If Date = User
			This.WatchStart := A_TickCount - (This.DifferenceTime(A_Hour ":" A_Min ":" A_Sec, (This.CheckDate := This.Get()), 1) + A_Msec)
		Else If Date
			This.WatchStart := A_TickCount - (This.DifferenceTime(A_Hour ":" A_Min ":" A_Sec, (This.CheckDate := Date), 1) + A_Msec)
		Else
			This.WatchStart := A_TickCount - A_Msec, This.CheckDate := A_Hour ":" A_Min ":" A_Sec
		This.Watch := 1, This.Timer := 0, This.InDay := 1, This.Loop := Loop
		This.WatchStartMsec := 0, This.Func := Func, This.Stop(0)
		obj := ObjBindMethod(This, "TimerWatch")
		SetTimer, % obj, % "-" 10
		Return 1
	}
	TimerTimer() {
		Local Time, obj, obj2, t
		If This.Stop()
			Return
		Time := This.FormatTime(This.TimerPeriod - (A_TickCount - This.TimerStart))
		This.SetTime(Time)
		This.CheckFlash()
		If Time = 00:00:00
		{
			If !This.Loop
				Return This.Stop(1), Func(This.Func).Call(This)
			This.TimerStart := A_TickCount + 1000
			TimerPeriod := This.DifferenceTime(This.CheckDate, A_Hour ":" A_Min ":" A_Sec, 1) - A_Msec
			This.TimerPeriod := TimerPeriod <= 0 ? 86400000 + TimerPeriod : TimerPeriod
			obj2 := Func(This.Func).Bind(This)
			Try SetTimer, % obj2, -50
		}
		If This.InDay
			t := (1000 - A_Msec)
		Else
			t := This.TimerStartMsec - A_Msec, t := (t < 0 ? 1000 + t : t)
		obj := ObjBindMethod(This, "TimerTimer")
		SetTimer, % obj, % "-" t + 100
	}
	TimerWatch() {
		Local Time, obj, obj2, t
		If This.Stop()
			Return
		If (t := A_TickCount - This.WatchStart) > 86399999
		{
			If !This.Loop
				Return This.Stop(1), This.SetTime("00:00:00"), Func(This.Func).Call(This)
			obj2 := Func(This.Func).Bind(This)
			Try SetTimer, % obj2, -50
			Time := "00:00:00", This.WatchStart += 86400000
		}
		Else
			Time := This.FormatTime(t)
		This.SetTime(Time)
		This.CheckFlash()
		If This.InDay
			t := (1000 - A_Msec)
		Else
			t := This.WatchStartMsec - A_Msec, t := (t < 0 ? 1000 + t : t)
		obj := ObjBindMethod(This, "TimerWatch")
		SetTimer, % obj, % "-" t + 100
	}
	Reset() {
		This.Stop(1)
		This.Set("00", "00", "00")
	}
	TimerClock() {
		Local obj
		If This.Stop()
			Return
		This.Set(A_Hour, A_Min, A_Sec)
		This.CheckFlash()
		obj := ObjBindMethod(This, "TimerClock")
		SetTimer, % obj, % "-" (1000 - A_Msec) + 100
	}
	CheckFlash() {
		Local obj
		If !This.Flash
			Return
		DllCall("ShowWindowAsync", "Ptr", This.hF1, "Int", 0)
		If This.Sec
			DllCall("ShowWindowAsync", "Ptr", This.hF2, "Int", 0)
		obj := ObjBindMethod(This, "ColonView")
		SetTimer, % obj, % "-" This.FlashTime
	}
	ColonView() {
		DllCall("ShowWindowAsync", "Ptr", This.hF1, "Int", 1)
		If This.Sec
			DllCall("ShowWindowAsync", "Ptr", This.hF2, "Int", 1)
	}
	Destroy() {
		Local k, v
		If !This
			Return
		This.Stop(1)
		Gui, % This.hWnd ":Destroy"
		For k, v in ["hS1","hM1","hH1","hS2","hM2","hH2"]
			This.Mem.Ctrl.Delete(This[v])
		This.Mem.Gui.Delete(This.hWnd)
		This.Delete(Chr(0), Chr(0x10FFFF))
		This.Delete(This.MinIndex(), This.MaxIndex())
		This.SetCapacity(0)
		This.Base := ""
	}
	MathTime(Time1, S, Time2) {
		Local T
		Time1 := Time1 = "" ? A_Hour ":" A_Min ":" A_Sec : Time1
		T := This.StrToMSec(Time1) + (S This.StrToMSec(Time2))
		T := Mod(T, 86400000)
		Return This.FormatTime(T < 0 ? 86400000 + T : T)
	}
	FormatTime(Time) {
		Local Rest, Hours, Min, Sec, MSec
		If Time < 0
			Return "00:00:00"
		Rest := Mod(Time, 3600000)
		Hours := Format("{:02d}", Time // 3600000)
		Min := Format("{:02d}", Rest // 60000)
		Sec := Format("{:02d}", Mod(Rest, 60000) // 1000)
		; MSec := Format("{:03d}", Mod(Rest, 1000))
		Return Hours ":" Min ":" Sec
	}
	StrToMSec(Time) {
		Local o
		o := StrSplit(Time, ":")
		Return This.HMSToMSec(o[1], o[2], o[3])
	}
	HMSToMSec(h, m, s=0) {
		Local sec
		sec := h * 3600
		sec += m * 60
		sec += s
		Return sec * 1000
	}
	DifferenceTime(Time1, Time2, Day=0) {
		Local T
		T := StrSplit(Time1, ":")
		Time1 := This.HMSToMSec(T[1], T[2], (T[3] ? T[3] : "00"))
		T := StrSplit(Time2, ":")
		Time2 := This.HMSToMSec(T[1], T[2], (T[3] ? T[3] : "00"))
		T := Time1 - Time2
		If !Day
			Return T
		T := Mod(T, 86400000)
		If T < 0
			Return 86400000 + T
		Return T
	}
}
+ Укороченный вариант класса с примером, только для вывода часов.

#SingleInstance Force
#NoEnv
ListLines Off
SetBatchLines -1

Gui, +HWNDhMain -DPIScale -Caption +AlwaysOnTop +E0x20
Gui, Margin, 0, 0
Gui, Color, F9D886
Clock := New ClockGui(hMain, "Sec|w 400|h 120|db 20|bckgitem F9D886|coloritem 5671BD|Font s80|FontName Comic Sans MS|Colon Flash 100 v6")
Clock.StartClock()
Clock.Show(0, 0)
Gui, Show, NA
WinSet, TransColor, F9D886 128, ahk_id %hMain%
Return

Class ClockGui {
	;  Автор - serzh82saratov
	;  Описание - http://forum.script-coding.com/viewtopic.php?id=12931
	__New(hParent, Option) {
		Local Font, FontName, Width, Height, Sec, Name, DB, DS, hH1, hH2, hM1, hM2, hS1, hS2, hF1, hF2, W, Flash
		, FlashTime, Colon, Colon_O, S_DefaultGui, RealWidth, hWnd, ColorItem, BckgItem, BckgMain, Off, k, v, rm, rm1

		Option := "|" Option "|"
		Width := this.Option("W", Option)
		Height := this.Option("H", Option)
		DS := this.Option("DS", Option, 0)
		DB := this.Option("DB", Option, 0)
		BckgMain := this.Option("BckgMain", Option, "Default")
		BckgItem := this.Option("BckgItem", Option, "000000")
		ColorItem := this.Option("ColorItem", Option, "ffffff")
		Name := this.Option("Name", Option)
		Font := this.Option("Font", Option)
		FontName := this.Option("FontName", Option)
		Sec := !!RegExMatch(Option, "i)\|\s*Sec\s*\|")
		Colon := !!RegExMatch(Option, "i)\|\s*Colon\s*\|")

		If (Colon_O := this.Option("Colon", Option)) && (Colon := 1)
			InStr(Colon_O, "Flash") && (Flash := 1) && !RegExMatch(Colon_O, "\d+", FlashTime) && (FlashTime := 500)
		If FlashTime > 950
			Throw "FlashTime не может быть больше чем 950"
		W := (Width - (DS * (Sec ? 3 : 2) + DB * (Sec ? 2 : 1))) / (Sec ? 6 : 4)

		S_DefaultGui := A_DefaultGui
		Gui, New
		Gui, +HWNDhWnd -DPIScale -Caption +0x40000000 -0x80000000  ; Add WS_CHILD, remove WS_POPUP, setarent no deactivate main gui
		Gui, Color, %BckgItem%
		Gui, Margin, 0, 0
		Gui, Font, %Font%, %FontName%

		Gui, Add, Text, x0 y0 w%W% h%Height% +0x201 +0x100 c%ColorItem% HwndhH1
		Gui, Add, Progress, x+0 yp hp w%DS% Background%BckgMain%
		Gui, Add, Text, x+0 y0 w%W% hp +0x201 +0x100 c%ColorItem% HwndhH2

		If Colon
		{
			Off := (RegExMatch(Colon_O, "i)v(\d+)", rm) ? rm1 : Height / 6)
			Gui, Add, Progress, x+0 yp hp w%DS% Background%BckgMain%
			Gui, Add, Text, % "+0x201 x+0 yp-" Off " hp+" Off " w" (DB - DS * 2) " c" ColorItem " HwndhF1", :
			Gui, Add, Progress, x+0 y0 h%Height% w%DS% Background%BckgMain%
		}
		Else
			Gui, Add, Progress, x+0 yp hp w%DB% Background%BckgMain%

		Gui, Add, Text, x+0 y0 w%W% hp +0x201 +0x100 c%ColorItem% HwndhM1
		Gui, Add, Progress, x+0 yp hp w%DS% Background%BckgMain%
		Gui, Add, Text, x+0 y0 w%W% hp +0x201 +0x100 c%ColorItem% HwndhM2
		If Sec
		{
			If Colon
			{
				Gui, Add, Progress, x+0 yp hp w%DS% Background%BckgMain%
				Gui, Add, Text, % "+0x201 x+0 yp-" Off " hp+" Off " w" (DB - DS * 2) " c" ColorItem " HwndhF2", :
				Gui, Add, Progress, x+0 y0 h%Height% w%DS% Background%BckgMain%
			}
			Else
				Gui, Add, Progress, x+0 yp hp w%DB% Background%BckgMain%
			Gui, Add, Text, x+0 y0 w%W% hp +0x201 +0x100 c%ColorItem% HwndhS1
			Gui, Add, Progress, x+0 yp hp w%DS% Background%BckgMain%
			Gui, Add, Text, x+0 y0 w%W% hp +0x201 +0x100 c%ColorItem% HwndhS2
		}
		Gui, +Parent%hParent%
		Gui, Show, Hide NA AutoSize
		Gui, %S_DefaultGui%:Default
		WinGetPos, , , RealWidth, , ahk_id %hWnd%

		For, k, v in ["hWnd","Name","Sec","RealWidth","FlashTime","hParent"
		,"Height","Flash","hH1","hH2","hM1","hM2","hS1","hS2","hF1","hF2"]
			this[v] := %v%
	}
	Show(x, y) {
		Local hDummy
		This.Set(A_Hour, A_Min, A_Sec)
		x := Format("{:d}", x), y := Format("{:d}", y)
		Gui, % This.hParent ":Add", Text, % "Hidden HWNDhDummy x" x " y" y " w" This.RealWidth " h" This.Height
		DllCall("DestroyWindow", "Ptr", hDummy)
		Gui, % This.hWnd ":Show", NA x%x% y%y%
	}
	Hide() {
		Gui, % This.hWnd ":Hide"
	}
	Move(x, y) {
		x := Format("{:d}", x), y := Format("{:d}", y)
		Gui, % This.hWnd ":Show", NA x%x% y%y%
	}
	Option(key, option, ret="") {
		Local Match, Match1
		RegExMatch(option, "iS)\|\s*" key "\s+(.*?)\s*\|", Match)
		Return ret != "" && Match1 = "" ? ret  : Match1
	}
	Set(h, m, s) {
		Local k, v, d
		For k, v in ["H1","H2","M1","M2","S1","S2"]
			If This[v] != (d := SubStr(h m s, k, 1))
				GuiControl, % This.hwnd ":", % This["h" v], % This[v] := Format("{:d}", d)
	}
	StartClock(Func="", Loop=0) {
		Local obj
		This.Set(A_Hour, A_Min, A_Sec)
		obj := ObjBindMethod(This, "TimerClock")
		SetTimer, % obj, % "-" (1000 - A_Msec) + 100
	}
	TimerClock() {
		Local obj
		If This.Stop()
			Return
		This.Set(A_Hour, A_Min, A_Sec)
		This.CheckFlash()
		obj := ObjBindMethod(This, "TimerClock")
		SetTimer, % obj, % "-" (1000 - A_Msec) + 100
	}
	CheckFlash() {
		Local obj
		If !This.Flash
			Return
		DllCall("ShowWindowAsync", "Ptr", This.hF1, "Int", 0)
		If This.Sec
			DllCall("ShowWindowAsync", "Ptr", This.hF2, "Int", 0)
		obj := ObjBindMethod(This, "ColonView")
		SetTimer, % obj, % "-" This.FlashTime
	}
	ColonView() {
		DllCall("ShowWindowAsync", "Ptr", This.hF1, "Int", 1)
		If This.Sec
			DllCall("ShowWindowAsync", "Ptr", This.hF2, "Int", 1)
	}
	Destroy() {
		Local k, v
		If !This
			Return
		This.Stop(1)
		Gui, % This.hWnd ":Destroy"
		This.Delete(Chr(0), Chr(0x10FFFF))
		This.Delete(This.MinIndex(), This.MaxIndex())
		This.SetCapacity(0)
		This.Base := ""
	}
} 
По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).