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


