Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Displaying Stopwatch on Label

Posted on 1999-01-06
20
Medium Priority
?
237 Views
Last Modified: 2010-05-03
I need to create a stopwatch that will show the time elapsing (not elapsed) in a label.caption. The resolution must be accurate to the half-second.

The format should be displayed, for example for one hour, 12 minutes, 23 seconds as 01:12:23
0
Comment
Question by:zrick
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 5
  • 3
  • +2
20 Comments
 
LVL 1

Expert Comment

by:bear454
ID: 1454354
Implement a timer control, set a perscribed interval, in this a half second, and in the timer event of the timer control, increment a variable by the time increment of the timer, and spit it our with formats & and a little math, as follows:

Public Runtime as double

Private Sub tmrStats_Timer()
    Runtime = Runtime + .5
    lblRuntime.Caption = "Elapsed time: " & Format((Runtime \ 3600), "00") & ":" & Format(((Runtime Mod 3600) \ 60), "00") & ":" & Format((Runtime Mod 60), "00.0")
End Sub

0
 

Author Comment

by:zrick
ID: 1454355
The code you provided works, but I need a more accurate timekeeper.
The stopwatch code runs quickly for two seconds then slows for two, then quick for two, etc...., Over a minute it is not accurate compared to the system clock. What I really need is for the system clock to be as closely matched as possible. When I begin the stopwatch, it should be like setting the systemtime back to midnight 00:00:00, each second of the system clock should advance the stopwatch by a second.

The reason this is important is that I am collecting physiologic data that is referenced to the system clock. I need to display the actual system clock (which is easy) and the time elapsed from when I begin recording. The time elapsed is calculated by the physiologic program based on the system clock, but it is not displayed on screen where I need it.
0
 
LVL 3

Expert Comment

by:myqlG
ID: 1454356
Try this.. the timer event itself takes like 22ms or some such
but this works pretty good:
(its for hours mins and seconds.but Ithink it could be changed for your needs)

Private Sub Timer1_Timer()
diffTime = DateDiff("s", xtime, Now)
mytime = CInt(diffTime \ 600) & ":" & CInt(diffTime \ 60) & ":" & CInt(diffTime Mod 60)
timervalue.Caption = Format(mytime, "hh:mm:ss")
End Sub

0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 3

Expert Comment

by:myqlG
ID: 1454357
You can also go here:
www.leahcim.com
click on VB
and there is a timer example using
API
0
 

Author Comment

by:zrick
ID: 1454358
myqlg, I tried both your examples. The first code gave me a runtime error 6 (overflow). When I went into Debug, this occured on the line mytime = ... I use VB 6.0, could that account for that? The api code from www.leahcim.com ran fine but was inaccurate compared to the system clock. When running it loses 6 seconds each minute compared with the system clock (I ran this both compiled and not compiled). I really need the time accurate to the system clock. Any ideas about that overflow error?
0
 
LVL 1

Expert Comment

by:bear454
ID: 1454359
The key is to crunch the math of the date data type. left of the decimal is the number of days, to the right is the time. For example 1/24 or ~0.04166666667 is 1 hour, or 1/86400 or ~0.00001157407 is 1 second.

Public StartTime as date
Timer1.interval = 250 'run every quarter-second

Timer1_Timer()
    Label1.Caption = Format(((Now - StartTime) \(1/24)),"00") & _
      ":" & Format(((Now - Starttime) \ (1/1440)),"00" & _
      ":" & Fomtat(((Now-Starttime) \(1/86400)),"00"
End Sub

0
 

Author Comment

by:zrick
ID: 1454360
Bear have you tried that code you sent me using the date? I can't get it to work. Divide by zero errors. I tried also with out dividing by the reciprocal, but that doesn't work well either. I need the counter to be continually updating like a stopwatch, this code doesn't seem to do that. Did it work for you?
0
 
LVL 1

Expert Comment

by:bear454
ID: 1454361
Sorry zrick - I wrote it off the top of my head.  Here's a working copy - save it as Stopwatch.frm I'm also submitting as an answer for "monitoring keystrokes...", just watch the keyboard buffer instead of a start button.

VERSION 5.00
Begin VB.Form Form1
   Caption         =   "StopWatch"
   ClientHeight    =   1110
   ClientLeft      =   60
   ClientTop       =   345
   ClientWidth     =   4470
   LinkTopic       =   "Form1"
   ScaleHeight     =   1110
   ScaleWidth      =   4470
   StartUpPosition =   3  'Windows Default
   Begin VB.CommandButton Command2
      Caption         =   "Stop"
      Height          =   495
      Left            =   3840
      TabIndex        =   7
      Top             =   600
      Width           =   615
   End
   Begin VB.CommandButton Command1
      Caption         =   "Start"
      Height          =   495
      Left            =   3840
      TabIndex        =   3
      Top             =   120
      Width           =   615
   End
   Begin VB.Timer Timer1
      Interval        =   250
      Left            =   4080
      Top             =   0
   End
   Begin VB.Label Label6
      Alignment       =   1  'Right Justify
      BorderStyle     =   1  'Fixed Single
      Caption         =   "Elapsed"
      Height          =   255
      Left            =   0
      TabIndex        =   6
      Top             =   840
      Width           =   735
   End
   Begin VB.Label Label5
      Alignment       =   1  'Right Justify
      BorderStyle     =   1  'Fixed Single
      Caption         =   "Now"
      Height          =   255
      Left            =   0
      TabIndex        =   5
      Top             =   480
      Width           =   735
   End
   Begin VB.Label Label4
      Alignment       =   1  'Right Justify
      BorderStyle     =   1  'Fixed Single
      Caption         =   "Start"
      Height          =   255
      Left            =   0
      TabIndex        =   4
      Top             =   120
      Width           =   735
   End
   Begin VB.Label Label3
      BorderStyle     =   1  'Fixed Single
      Caption         =   "hh:mm:ss"
      Height          =   255
      Left            =   840
      TabIndex        =   2
      Top             =   840
      Width           =   2895
   End
   Begin VB.Label Label2
      BorderStyle     =   1  'Fixed Single
      Caption         =   "hh:mm:ss"
      Height          =   255
      Left            =   840
      TabIndex        =   1
      Top             =   480
      Width           =   2895
   End
   Begin VB.Label Label1
      BorderStyle     =   1  'Fixed Single
      Caption         =   "hh:mm:ss"
      Height          =   255
      Left            =   840
      TabIndex        =   0
      Top             =   120
      Width           =   2895
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Private Run As Boolean
Private StartTime As Date

Private Sub Command1_Click()
    StartTime = Now
    Run = True
    Label1.Caption = Format(Now, "hh:mm:ss")
End Sub

Private Sub Command2_Click()
    Run = False
End Sub

Private Sub Timer1_Timer()
    Label2.Caption = Format(Now, "hh:mm:ss")
    If Run Then
        Label3.Caption = Format(((Now - StartTime) / (1 / 24)), "00") & _
          ":" & Format(((Now - StartTime) / (1 / 1440)), "00") & _
          ":" & Format(((Now - StartTime) / (1 / 86400)), "00")
    End If
End Sub

0
 

Author Comment

by:zrick
ID: 1454362
Bear, It is getting much closer. The second intervals are directly parallel to the seconds of the system clock (of course - good thinking), however, the stopwatch seems to think that there are 30 seconds in the first minute, and the second minute comes around 1 minute 90 seconds (as displayed), then the seconds start being displayed in the hundreds. 00:03:116 (something like that indicating 3 minutes and 116 seconds)

Also, VB-6 did not understand how to interpret these lines, but it ran okay with them rem-ed out

Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False

VB6 also didn't like the Begin statements, such as
Begin VB.Label Label3
But it accepted the values fine when I entered them manually into the Properties box


0
 

Author Comment

by:zrick
ID: 1454363
Adjusted points to 55
0
 

Expert Comment

by:edunc
ID: 1454364
use whatever code worked before but make the timer interval 50.
0
 

Author Comment

by:zrick
ID: 1454365
Edunc, setting the interval to 50 does not correct the problem. Were you responding to the 1/2 second part of this question, then it would be 500. The question that was raised was about trying to get bear's code working. At 30 seconds, his code which is actually quite elegant otherwise, registers  1 minute (see my reply to bear).
Rick
0
 

Author Comment

by:zrick
ID: 1454366
Adjusted points to 75
0
 

Author Comment

by:zrick
ID: 1454367
On the code provided by Bear, the stopwatch seems to think that there are 30 seconds in the first minute, and the second minute comes around 1 minute 90 seconds (as displayed), then the seconds start being displayed in the hundreds. 00:03:116 (something like that indicating 3 minutes and 116 seconds)  

Anybody know how to fix this?
0
 
LVL 1

Expert Comment

by:muffinthedog
ID: 1454368
You might try something real simple like
Simply call SetAlarm (should pass the control and set it to a private member) to start the timer and EndTimer to end the timer...

Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long

Private Timer As Long
Sub SetAlarm()
    Timer = SetTimer(0, 0, 1000, AddressOf TimerProc)
End Sub
Sub EndAlarm()
    KillTimer Timer
End Sub
Sub TimerProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal dwTime As Long)
Static Ticks As Long
Dim Hours As Long, Minutes As Long, Seconds As Long
Ticks = Ticks + 1
Seconds = Ticks Mod 60
Minutes = Ticks \ 60
Hours = Minutes \ 60
Minutes = Minutes Mod 60

Form1.Label1.Caption = Format(Hours, "00") & ":" & Format(Minutes, "00") & ":" & Format(Seconds, "00")
End Sub

0
 
LVL 1

Expert Comment

by:muffinthedog
ID: 1454369
My block copy dint pick up the Declaration for SetTimer.... sorry

Declare Function SetTimer Lib "user32" Alias "SetTimer" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long

0
 
LVL 1

Expert Comment

by:muffinthedog
ID: 1454370
Also the call to the KillTimer should be KillTimer 0, Timer... sorry again...
0
 
LVL 1

Expert Comment

by:bear454
ID: 1454371
This is starting to piss me off. You better accept my next answer. ={
0
 
LVL 1

Accepted Solution

by:
bear454 earned 400 total points
ID: 1454372
Use my previous code, but substitute this Procedure - I can't believe I didn't find these gems before!

Private Sub Timer1_Timer()
    Label2.Caption = Format(Now, "hh:mm:ss")
    If Run Then
        Label3.Caption = Format(Hour(Now - StartTime), "00") & _
          ":" & Format(Minute(Now - StartTime), "00") & _
          ":" & Format(Second(Now - StartTime), "00")
    End If
End Sub

PS - I expect an 'A'
0
 

Author Comment

by:zrick
ID: 1454373
Bear, You're latest code worked well. I ran the compiled version for 2 hours without a problem. Thank you for taking the time to work on this code until it performed without errors. I increased the points to 105, which is the full amount I have available, and of course I gave you a well deserved "A."

My next step is to see if I can trigger this stopwatch when I begin the physiological recording in another program. I am going see if the stopwatch program can monitor for the next mouse click occuring in another program and then begin the timer.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
Suggested Courses

618 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question