Just to add a simple clock [SOLVED]
- Rook Zimbabwe
- Addict
- Posts: 4322
- Joined: Tue Jan 02, 2007 8:16 pm
- Location: Cypress TX
- Contact:
Just to add a simple clock [SOLVED]
I know this is possible... it just seems hard because I am missing something of the structure I need to know about...
How can I add a simple clock to my Application... It seems that the clock I have will not update unless the mouse is moving...
I can add the time update as a function... If I do this will the computer update the clock once each event loop of the REPEAT / UNTIL process?
EDIT:: NO it will not
How can I add a simple clock to my Application... It seems that the clock I have will not update unless the mouse is moving...
I can add the time update as a function... If I do this will the computer update the clock once each event loop of the REPEAT / UNTIL process?
EDIT:: NO it will not
Last edited by Rook Zimbabwe on Wed Feb 07, 2007 9:30 pm, edited 1 time in total.
Create a procedure to handle the drawing of your clock:
then create a timer (outside of your main loop) to call this procedure once every second to update the time display. (Uses WinAPI)
(Untested (written from memory))
Code: Select all
Procedure UpdateTime()
Now.l = Date()
SetGadgetText(#TEXT_GADGET, FormatDate("%hh:%ii:%ss", Now))
EndProcedure
Code: Select all
SetTimer_(WindowID(#WINDOW), 0, 1000, @UpdateTime())
- Joakim Christiansen
- Addict
- Posts: 2452
- Joined: Wed Dec 22, 2004 4:12 pm
- Location: Norway
- Contact:
You're right, but I think a bigger delay may be appropriate, 100 maybe.r_hyde wrote:I think you need to change your event loop to WaitWindowEvent(1)
Actually a clock only need to be updated once a second so actually 1000 could be enough.
Hey, nice trick Kale, guess I'll start using those timers!
I like logic, hence I dislike humans but love computers.
- Kaeru Gaman
- Addict
- Posts: 4826
- Joined: Sun Mar 19, 2006 1:57 pm
- Location: Germany
one thing to remember:
SetGadgetText and the other gadget-command create an event.
this means, you must only update the clock-gadget, when the
WaitWindowEvent timer is over, when no other event occured.
snippet:
Clock& is the string you'll get from Date or whereever....
SetGadgetText and the other gadget-command create an event.
this means, you must only update the clock-gadget, when the
WaitWindowEvent timer is over, when no other event occured.
snippet:
Code: Select all
Repeat
EventID = WaitWindowEvent(500)
If EventID = 0
SetGadgetText( ClockGadget, Clock$ )
EndIf
;.....
Until EXIT
oh... and have a nice day.
- Rook Zimbabwe
- Addict
- Posts: 4322
- Joined: Tue Jan 02, 2007 8:16 pm
- Location: Cypress TX
- Contact:
A bit late, but here is a sample I have cut down from 1 of my recent projects. ( It is using the same timer function as suggested by Kale )
It is using a shared structure which gives me hr, min, sec, etc values as bytes to allow easy access from the main loop to allow triggering of other parts of my program by simply passing these values into other control procedures.
This way avoids need to have any timeout on your waitwindowevent()
Not yet fully tested through the entire 24 hr day range, but at this stage seems to be working in my project very nicely. 
It is using a shared structure which gives me hr, min, sec, etc values as bytes to allow easy access from the main loop to allow triggering of other parts of my program by simply passing these values into other control procedures.
This way avoids need to have any timeout on your waitwindowevent()
Code: Select all
Structure tTimeInfo
tDisplay.s
tHr.b
tHr12f.b
tMin.b
tSec.b
tMeridian.b
tUpdate.b
EndStructure
Time.tTimeInfo
Procedure Clock()
Shared Time.tTimeInfo
Time$=FormatDate("%hh%ii%ss", Date())
Time\tHr=Val(Left(Time$,2))
Time\tMin=Val(Mid(Time$,3,2))
Time\tSec=Val(Right(Time$,2))
If Time\tHr>11
Time\tMeridian=#True
Meridian$=" pm"
Else
Time\tMeridian=#False
Meridian$=" am"
EndIf
If Time\tHr>12
Time\tHr12f=Time\tHr-12
Else
Time\tHr12f=Time\tHr
EndIf
If Time\tHr12f=0
tHr12f$="12"
Else
tHr12f$=Str(Time\tHr12f)
EndIf
Time\tDisplay= tHr12f$+":"+RSet(Str(Time\tMin),2,"0")+":"+RSet(Str(Time\tSec),2,"0")+Meridian$
Time\tUpdate=#True
EndProcedure
If OpenWindow(0,0,0,200,100,"Test",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
If CreateGadgetList(WindowID(0))
TextGadget(1,10,10,70,20,"")
EndIf
eClock=SetTimer_(WindowID(0),2,1000,@Clock())
EndIf
Repeat
If Time\tUpdate ;updates once per second as set by settimer elapse value
SetGadgetText(1,Time\tDisplay)
Time\tUpdate=#False
EndIf
Until WaitWindowEvent()=#PB_Event_CloseWindow
If eClock
KillTimer_(WindowID(0),eClock)
EndIf

Another version using a thread:
Code: Select all
;]=============================================================================
;-CONSTANTS
;[=============================================================================
#APP_NAME = "Name"
Enumeration
#WINDOW_ROOT
#TIME_TEXT
EndEnumeration
;]=============================================================================
;-PROCEDURES
;[=============================================================================
;Handle an error
Procedure HandleError(Result.l, Text.s)
If Result = 0
MessageRequester("Error", Text, #PB_MessageRequester_Ok)
End
EndIf
EndProcedure
;sort out the time and display it
Procedure SetTime()
currentDate = Date()
hours.b = Hour(currentDate)
minutes.b = Minute(currentDate)
seconds.b = Second(currentDate)
append.s = "am"
If hours >= 12
append.s = "pm"
EndIf
If hours = 0
hours = 12
EndIf
If hours > 12
hours = hours-12
EndIf
If minutes < 10
adjustedMinutes.s = "0"+Str(minutes)
Else
adjustedMinutes.s = Str(minutes)
EndIf
If seconds < 10
adjustedSeconds.s = "0"+Str(seconds)
Else
adjustedSeconds.s = Str(seconds)
EndIf
SetGadgetText(#TIME_TEXT, Str(hours)+":"+adjustedMinutes+":"+adjustedSeconds+" "+append)
Delay(1000)
SetTime()
EndProcedure
;]=============================================================================
;-GEOMETRY
;[=============================================================================
HandleError(OpenWindow(#WINDOW_ROOT, 0, 0, 400, 300, #APP_NAME, #PB_Window_SystemMenu | #PB_Window_ScreenCentered), "Main window could not be created.")
HandleError(CreateGadgetList(WindowID(#WINDOW_ROOT)), "Gadget list for the main window could not be created.")
TextGadget(#TIME_TEXT, 10, 10, 100, 25, "")
ThreadID = CreateThread(@SetTime(), #Null)
;]=============================================================================
;-MAIN LOOP
;[=============================================================================
Repeat
EventID.l = WaitWindowEvent()
Until EventID = #PB_Event_CloseWindow
KillThread(ThreadID)
End
;]=============================================================================
;-END
;==============================================================================
Using the Timer WinAPI function
Code: Select all
;]=============================================================================
;-CONSTANTS
;[=============================================================================
#APP_NAME = "Name"
Enumeration
#WINDOW_ROOT
#TIME_TEXT
EndEnumeration
;]=============================================================================
;-PROCEDURES
;[=============================================================================
;Handle an error
Procedure HandleError(Result.l, Text.s)
If Result = 0
MessageRequester("Error", Text, #PB_MessageRequester_Ok)
End
EndIf
EndProcedure
;sort out the time and display it
Procedure SetTime()
currentDate = Date()
hours.b = Hour(currentDate)
minutes.b = Minute(currentDate)
seconds.b = Second(currentDate)
append.s = "am"
If hours >= 12
append.s = "pm"
EndIf
If hours = 0
hours = 12
EndIf
If hours > 12
hours = hours-12
EndIf
If minutes < 10
adjustedMinutes.s = "0"+Str(minutes)
Else
adjustedMinutes.s = Str(minutes)
EndIf
If seconds < 10
adjustedSeconds.s = "0"+Str(seconds)
Else
adjustedSeconds.s = Str(seconds)
EndIf
SetGadgetText(#TIME_TEXT, Str(hours)+":"+adjustedMinutes+":"+adjustedSeconds+" "+append)
SetTimer_(WindowID(#WINDOW_ROOT), 1, 1000, @setTime()) ; generates a #WM_TIMER which can be caught by the event loop
EndProcedure
;]=============================================================================
;-GEOMETRY
;[=============================================================================
HandleError(OpenWindow(#WINDOW_ROOT, 0, 0, 400, 300, #APP_NAME, #PB_Window_SystemMenu | #PB_Window_ScreenCentered), "Main window could not be created.")
HandleError(CreateGadgetList(WindowID(#WINDOW_ROOT)), "Gadget list for the main window could not be created.")
TextGadget(#TIME_TEXT, 10, 10, 100, 25, "")
SetTime()
;]=============================================================================
;-MAIN LOOP
;[=============================================================================
Repeat
EventID.l = WaitWindowEvent()
Until EventID = #PB_Event_CloseWindow
End
;]=============================================================================
;-END
;==============================================================================
Another version using the ElapsedMilliseconds() command:
Code: Select all
;]=============================================================================
;-CONSTANTS
;[=============================================================================
#APP_NAME = "Name"
Enumeration
#WINDOW_ROOT
#TIME_TEXT
EndEnumeration
;]=============================================================================
;-PROCEDURES
;[=============================================================================
;Handle an error
Procedure HandleError(Result.l, Text.s)
If Result = 0
MessageRequester("Error", Text, #PB_MessageRequester_Ok)
End
EndIf
EndProcedure
;sort out the time and display it
Procedure SetTime()
currentDate = Date()
hours.b = Hour(currentDate)
minutes.b = Minute(currentDate)
seconds.b = Second(currentDate)
append.s = "am"
If hours >= 12
append.s = "pm"
EndIf
If hours = 0
hours = 12
EndIf
If hours > 12
hours = hours-12
EndIf
If minutes < 10
adjustedMinutes.s = "0"+Str(minutes)
Else
adjustedMinutes.s = Str(minutes)
EndIf
If seconds < 10
adjustedSeconds.s = "0"+Str(seconds)
Else
adjustedSeconds.s = Str(seconds)
EndIf
SetGadgetText(#TIME_TEXT, Str(hours)+":"+adjustedMinutes+":"+adjustedSeconds+" "+append)
EndProcedure
;]=============================================================================
;-GEOMETRY
;[=============================================================================
HandleError(OpenWindow(#WINDOW_ROOT, 0, 0, 400, 300, #APP_NAME, #PB_Window_SystemMenu | #PB_Window_ScreenCentered), "Main window could not be created.")
HandleError(CreateGadgetList(WindowID(#WINDOW_ROOT)), "Gadget list for the main window could not be created.")
TextGadget(#TIME_TEXT, 10, 10, 100, 25, "")
SetTime()
;]=============================================================================
;-MAIN LOOP
;[=============================================================================
StartTime = ElapsedMilliseconds()
Repeat
EventID.l = WindowEvent()
CurrentTime = ElapsedMilliseconds()
If CurrentTime > StartTime + 1000 ; 1 second
SetTime()
StartTime = ElapsedMilliseconds()
EndIf
If EventID = #Null
Delay(1)
EndIf
Until EventID = #PB_Event_CloseWindow
End
;]=============================================================================
;-END
;==============================================================================