Just to add a simple clock [SOLVED]

Just starting out? Need help? Post your questions and find answers here.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Just to add a simple clock [SOLVED]

Post by Rook Zimbabwe »

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
Last edited by Rook Zimbabwe on Wed Feb 07, 2007 9:30 pm, edited 1 time in total.
r_hyde
Enthusiast
Enthusiast
Posts: 155
Joined: Wed Jul 05, 2006 12:40 am

Post by r_hyde »

I think you need to change your event loop to WaitWindowEvent(1)
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

Create a procedure to handle the drawing of your clock:

Code: Select all

Procedure UpdateTime()
    Now.l = Date()
    SetGadgetText(#TEXT_GADGET, FormatDate("%hh:%ii:%ss", Now))
EndProcedure
then create a timer (outside of your main loop) to call this procedure once every second to update the time display. (Uses WinAPI)

Code: Select all

SetTimer_(WindowID(#WINDOW), 0, 1000, @UpdateTime())
(Untested (written from memory))
--Kale

Image
User avatar
Joakim Christiansen
Addict
Addict
Posts: 2452
Joined: Wed Dec 22, 2004 4:12 pm
Location: Norway
Contact:

Post by Joakim Christiansen »

r_hyde wrote:I think you need to change your event loop to WaitWindowEvent(1)
You're right, but I think a bigger delay may be appropriate, 100 maybe.
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.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

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:

Code: Select all

Repeat
  EventID = WaitWindowEvent(500)
  If EventID = 0
    SetGadgetText( ClockGadget, Clock$ )
  EndIf
;.....
Until EXIT
Clock& is the string you'll get from Date or whereever....
oh... and have a nice day.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

I think you are all correct. I had a function created exactly that way to update the clock... I was still not aware I could set the timeout to 500 (check every 1/2 second) 8)
Baldrick
Addict
Addict
Posts: 860
Joined: Fri Jul 02, 2004 6:49 pm
Location: Australia

Post by Baldrick »

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()

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 
Not yet fully tested through the entire 24 hr day range, but at this stage seems to be working in my project very nicely. :)
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

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
;==============================================================================

--Kale

Image
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

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
;==============================================================================

--Kale

Image
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

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
;==============================================================================

--Kale

Image
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

Nice examples.

Thanks Kale - include those in next revision :)

cheers
Post Reply