Тема: AHK: Часы, таймер, секундомер
Класс позволяет добавлять контролы в виде табло часов. Встроены таймеры для часов, таймера и секундомера. Также с помощью контрола пользователь может выставить нужное ему время.
Ввод времени - LButton, RButton, WheelUp, WheelDown, MButton - сброс на 00, нижнее табло в 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
#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)
}
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.28.02 (Unicode 32-bit).