Hi HemSA,
ja, genau dafür ist AddWindowTimer() gemacht.
Die Procedure "CheckStartTime(()" in meinen Beispielen ist so zu sagen die Auswertefunktion.
Windows hat diese Grenzen bei der elapsed Time, das wird dann wohl auch für AddWindowTimer() für die Timeout Zeit gelten.
Code: Alles auswählen
; #USER_TIMER_MINIMUM == $0000000A == 10
; #USER_TIMER_MAXIMUM == $7FFFFFFF == 2147483647
Absolut, ich denke das man als "Programmierer" nie auslernt - das ist ja gerade das coole... (für mich zumindest)
TIPP: Ich versuche immer so zu coden, dass ich in vielen Jahren noch einfach verstehe was der Code macht. Und wenn die Konstanten, Variablen und Proceduren entsprechende Namen haben, dann braucht es (eigentlich) auch nicht mehr so viel Kommentare.....
BTW: Ich würde dein Program so bauen.... (Es fehlen noch die Shutdown-Teile, stattdessen gibt es eine InfoBox())
Zum Thema Shutdown gibt es im englischen Forum
diesen Beitrag.
Code: Alles auswählen
;Version 1.2
EnableExplicit ; always recommended to find typos
; Retrieves the number of milliseconds that have elapsed since the system was started.
Import ""
GetTickCount64()
EndImport
; --- Define UI constants ---
Enumeration EWindow ; Windows .. I like named enums this way
#WINDOW_Main
EndEnumeration
Enumeration EGadget ; Gadgets
#GADGET_txtInfo1
#GADGET_txtInfo2
#GADGET_txtInfo3
#GADGET_btnRestart
EndEnumeration
Enumeration ETimer ; Timer
#TIMER_CheckInterval
#TIMER_MinimizeWindowDelay
EndEnumeration
; --- constants ---
#Caption$ = "Restart Monitor"
#MainCaption$ = #Caption$ + " 0." + #PB_Editor_CompileCount
;
#TIME_OneHourInSeconds = 3600 ; 1 hour * 60 min * 60 sec
;
CompilerIf #PB_Compiler_Debugger
#INTERVAL_CheckInterval = 10000 ; for test reasons 10 s
CompilerElse
#INTERVAL_CheckInterval = #TIME_OneHourInSeconds * 1000 ; every hour in runtime version
CompilerEndIf
#INTERVAL_MinimizeWindowDelay = 3000 ; == 3 s
; --- sweet little helpers ---
Macro InfoBox(Message)
MessageRequester(#Caption$, Message, #PB_MessageRequester_Info | #PB_MessageRequester_Ok)
EndMacro
Macro AskYNBox(Question)
Bool(MessageRequester(#Caption$, Question, #PB_MessageRequester_Info | #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes)
EndMacro
; ---
Procedure.i CheckStartTime(MaxRunningHours) ;
Protected tickcount.q, dt, hours, days, text$
tickcount = GetTickCount64() / 1000 ; tickcount in seconds
; update UI
hours = tickcount / #TIME_OneHourInSeconds
SetGadgetText(#GADGET_txtInfo1, "PC is running " + hours + " hour(s).")
; converted to days and hours
days = hours / 24
hours % 24
SetGadgetText(#GADGET_txtInfo2, "that are " + days + " day(s) and " + hours + " hour(s)." )
; computer start time
dt = Date() - tickcount ; we need seconds here
SetGadgetText(#GADGET_txtInfo3, "Computer Starttime = " + FormatDate("%YYYY.%MM.%DD %HH:%II:%SS", dt))
; check on ... what ever
If tickcount > MaxRunningHours * #TIME_OneHourInSeconds
SetWindowState(#WINDOW_Main, #PB_Window_Normal)
InfoBox("Okay. Here we want to force a new start of the computer ....... ")
DisableGadget(#GADGET_btnRestart, 0) ; Enable Button
EndIf
ProcedureReturn #False ; keep program running
EndProcedure
; --- UI Window Main ---
Procedure OpenWindowMain()
If OpenWindow(#WINDOW_Main, 0, 0, 400, 128, #MainCaption$, #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
StickyWindow(#WINDOW_Main, 1) ; always on top
TextGadget(#GADGET_txtInfo1, 40, 16, 360, 20, "")
TextGadget(#GADGET_txtInfo2, 40, 40, 360, 20, "")
TextGadget(#GADGET_txtInfo3, 40, 64, 360, 20, "")
;
ButtonGadget(#GADGET_btnRestart, 80, 96, 240, 24, "Restart")
DisableGadget(#GADGET_btnRestart, 1) ; keep Button Disabled
ProcedureReturn #True ; success
EndIf
ProcedureReturn #False ; failure
EndProcedure
; ---
Procedure main()
Protected MaxRunningHours, tmp
MaxRunningHours = 25 ; hours (as default)
;
; you can forward the value as a parameter (e.g. in the startup link)
If CountProgramParameters()
tmp = Val(ProgramParameter(0))
If tmp > 10 And tmp < 1000 ; check some limits (I dont know?)
MaxRunningHours = tmp :Debug "MaxRunningHours set to " + MaxRunningHours
EndIf
EndIf
If OpenWindowMain()
; minimize the window 'Seconds' after program start
AddWindowTimer(#WINDOW_Main, #TIMER_MinimizeWindowDelay, #INTERVAL_MinimizeWindowDelay)
; call check procedure
AddWindowTimer(#WINDOW_Main, #TIMER_CheckInterval, #INTERVAL_CheckInterval) ; check every 60 s
; call it here to update UI
CheckStartTime(MaxRunningHours)
Repeat ; main loop
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break ; leave the main loop
; If AskYNBox("Are you sure you want to end the program now?")
; Break ; leave the main loop
; EndIf
Case #PB_Event_RestoreWindow :Debug "Restore Window"
; show window for 'Seconds' only, minimize again
; --> remove the comment char in the next line (and see what happend)
; AddWindowTimer(#WINDOW_Main, #TIMER_MinimizeWindowDelay, #INTERVAL_MinimizeWindowDelay)
Case #PB_Event_Timer ; on Timer event
Select EventTimer() ; look which timer event occured
Case #TIMER_MinimizeWindowDelay
SetWindowState(#WINDOW_Main, #PB_Window_Minimize)
;
; only a single shot, we remove the timer here ...
RemoveWindowTimer(#WINDOW_Main, #TIMER_MinimizeWindowDelay)
Case #TIMER_CheckInterval
If CheckStartTime(MaxRunningHours) ; <> ZERO -> leave the main loop
Break
EndIf
EndSelect
Case #PB_Event_Gadget ; on Gadget Event
Select EventGadget()
Case #GADGET_btnRestart
If AskYNBox("Are you sure you want to restart your computer now?")
;
; space for improvement
;
EndIf
Debug "Restart the system now or later or never ..."
EndSelect
EndSelect
ForEver
RemoveWindowTimer(#WINDOW_Main, #TIMER_CheckInterval)
EndIf
ProcedureReturn 0 ; default
EndProcedure
End main()