Results 1 to 13 of 13

Thread: Can I extract seconds from Tick Count?

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Can I extract seconds from Tick Count?

    Exactly what is a tick count? Can a tick count be converted to seconds?

    In a application a certain event takes place and at the point in time it occurs I save the current tick count. Now later another event takes place. At the point in time of the second event I get the current tick count. What I need to be able to resolve is how many seconds elapsed from the first event to the second event and the only thing I have are the two tick counts. Using Time doesn't work for this situation.

  2. #2
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Can I extract seconds from Tick Count?

    By tick count I trust you mean the return from GetTickCount Api
    Code:
    Declare Function GetTickCount Lib "kernel32" Alias "GetTickCount" () As Long
    It returns the number of milliseconds that the computers been running (unless it has already looped). I think it returns an unsigned long so it's good for 24.8 days in VB (not tested).


    (EndTick - StartTick) / 1000
    '<--- should give the number of seconds.

    Edit: VB's own Timer function (contrary to popular belief) works to exactly the same accuracy as GetTickCount (~1/64th of a second) it's just a little slower to access.
    Last edited by Milk; Jan 17th, 2008 at 08:01 PM.

  3. #3
    Former Admin/Moderator MartinLiss's Avatar
    Join Date
    Sep 1999
    Location
    San Jose, CA
    Posts
    33,431

    Re: Can I extract seconds from Tick Count?

    Quote Originally Posted by Milk
    ...Edit: VB's own Timer function (contrary to popular belief) works to exactly the same accuracy as GetTickCount (~1/64th of a second) it's just a little slower to access.
    I don't want to start a lengthy discussion here but the Timer is affected by other events and hence is only accurate to +/- 40 ms.

  4. #4
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Can I extract seconds from Tick Count?

    ok lets not, but GetTickCount is not accurate to milliseconds (as it's return suggests) it only updates every 1/64th of a second. Perhaps closer to the 1/64th mark than timer, but there's not much in it.
    Agreed?

    Edit: This test shows them both to be very very similar
    Code:
    Option Explicit
    Private Declare Function GetTickCount Lib "kernel32" () As Long
    
    Private Sub Form_Load()
    Dim i As Long
    
      For i = 1 To 3000
        List1.AddItem Timer & " : " & GetTickCount
      Next i
    
    End Sub
    If you run down the list you see that they update at the same time.

    Timer does take longer to call than GetTickCount, so the Api wins there.
    Last edited by Milk; Jan 17th, 2008 at 09:20 PM.

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: Can I extract seconds from Tick Count?

    Milk,

    Are you sure it's divide by 1000? Things just arn't computing out right.

  6. #6
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: Can I extract seconds from Tick Count?

    A more accurate method would be to use the QueryPerformanceCounter and QueryPerformanceFrequency APIs, if your computer supports the High Resolution Counter:
    eg
    Code:
    Private Declare Function QueryPerformanceCounter Lib "kernel32" _
                    (lpPerformanceCount As Currency) As Long
                    
    Private Declare Function QueryPerformanceFrequency Lib "kernel32" _
                    (lpFrequency As Currency) As Long
                    
    Private curFreq As Currency
    
    Private Sub Command1_Click()
    Dim curThen As Currency
    Dim curNow As Currency
    Dim lngReturn As Long
    Dim lngI As Long
    Dim sngTime As Single
    lngReturn = QueryPerformanceCounter(curThen)
    For lngI = 0 To 1000000
        a = 10
    Next lngI
    lngReturn = QueryPerformanceCounter(curNow)
    sngTime = (curNow - curThen) * 1000 / curFreq
    MsgBox "1 million assignments took " & Format(sngTime, "###0.000") & " milliseconds"
    End Sub
    
    Private Sub Form_Load()
    Dim lngReturn As Long
    lngReturn = QueryPerformanceFrequency(curFreq)
    If lngReturn = 0 Then
        MsgBox "This Computer does not support the High Resolution Performance Counter"
    End If
    End Sub

  7. #7
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Can I extract seconds from Tick Count?

    Quote Originally Posted by jmsrickland
    Milk,

    Are you sure it's divide by 1000? Things just arn't computing out right.
    I'm sure . How do you mean not right? If your getting a return of 0 it means whatever your measuring is quicker than Gettickcount updates. Unless of course the ticks you are talking about are not the return from GetTickCount.

    As Doogle says, use QueryPerformanceCounter for measuring small intervals. It should be noted that QueryPerformanceCounter is not so good for measuring longer periods, can't win 'em all i guess
    Last edited by Milk; Jan 18th, 2008 at 04:49 AM.

  8. #8

    Thread Starter
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: Can I extract seconds from Tick Count?

    Well here is what I am doing.

    I have a Timer Control that is fired every 60 seconds. In the Timer event I increment a counter and when the counter equal 5 ( 5 * 60 = 300 = 5 minutes) I call the following API function

    GetLastInputInfo

    This function returns the tick count of the last time a user did some activity, if any at all, and I compare that tick count with a previous tick count to see if any activity has taken place in the last 5 minutes. So I use the following If clause....
    Code:
      '
      '
    Private Sub Timer1_Timer()
      '
      ' 
      '
     If StartTick <> info.tickCount Then
       '
       ' Here if some activity took place
       '
       If (info.tickCount - StartTick) \ 1000 < 300 Then
         Activity = True
       Else
         Activity = False
       End If
       
       '
       ' Get the new tick value.
       '
       StartTick = info.tickCount
     Else
       '
       ' Here if no activity took place
       '
       Activity = False
     End If
      '
      '
      '
    End Sub
    Now, let's say the user did something and so the API captures the tick count at the point in time the user did something. In the Timer Event I calculate the number of seconds that has elapsed since the last time the Timer event counter equaled 5 to the tick count when the user did something. So, I would think that the results of the above calculation should never be greater than 300. But my tests show that at times the results are far greater than 300 and as a result causes the variable Activity to be set to False when in fact it should have been set to True.

  9. #9
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Can I extract seconds from Tick Count?

    Well not being familiar with the API, and not being able to find the VB6 declare anywhere I've had a go with the C#/C++ declare from MSDN.

    It seems to be working. Because I'm impatient I've set idle limit to 3 seconds. Which should mean it waits between 3 and 3 + timer.interval to flag Not Active
    Code:
    Option Explicit
    
    Private Type LASTINPUTINFO
        cbSize As Long
        dwTime As Long
    End Type
    
    Private Declare Function GetTickCount Lib "kernel32" () As Long
    Private Declare Function GetLastInputInfo Lib "user32.dll" (ByRef plii As LASTINPUTINFO) As Long
    
    Private Const MAXIDLE As Long = 3 'Seconds
    Private mLastActive As LASTINPUTINFO
    Private mNotActive As Boolean
    
    Private Sub Form_Load()
        mLastActive.cbSize = 8
        Timer1.Interval = 1000
    End Sub
    
    Private Sub Timer1_Timer()
        GetLastInputInfo mLastActive
        mNotActive = GetTickCount - mLastActive.dwTime > MAXIDLE * 1000
        If mNotActive Then 
            Label1.Caption = "Oi! Bum!"
        else
            Label1.Caption = "Active"
        End if
    End Sub

  10. #10

    Thread Starter
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: Can I extract seconds from Tick Count?

    OK, here is the code that I am using....
    Code:
    Private Declare Function GetLastInputInfo Lib "user32.dll" (inputStructure As inputInfo) As Boolean
    
    Private Type inputInfo
      structSize As Long
      tickCount As Long
    End Type
    
    ' The variable that will be passed to the API call and receive the activity report.
    
    Private info As inputInfo
    
    Dim FirstTick As Long
    Dim LastTick As Long
    
    Dim TimeCounter As Integer
    
    Const FiveMinutes = 300
    
    Private Sub Timer1_Timer()
     Caption = "Elapsed Minutes = " & TimeCounter
    
     If TimeCounter = 5 Then
       If Activity Then
         Text1.Text = Text1.Text & "User had activity in last 5 minutes" & vbCrLf
       Else
         Text1.Text = Text1.Text & "No Activity in last 5 minutes" & vbCrLf
       End If
       TimeCounter = 1
     Else
       TimeCounter = TimeCounter + 1
     End If
    End Sub
    
    Private Function Activity() As Boolean
     Activity = False
     info.structSize = Len(info)
    
     GetLastInputInfo info
       
     Text1.Text = Text1.Text & "Current Time = " & Time & ", FirstTick = " & FirstTick & ", Last Tick = " & info.tickCount & ", Tick Difference In Seconds  = " & (info.tickCount - FirstTick) \ 1000 & vbCrLf
    
     l = (info.tickCount - FirstTick) \ 1000
    
     If FirstTick <> info.tickCount Then
       If (info.tickCount - FirstTick) \ 1000 < FiveMinutes Then
         Activity = True
       Else
         Activity = False
       End If
    
       LastActivityTime = Time
       
       '
       ' Get the new tick value.
       '
       FirstTick = info.tickCount
     Else
       Activity = False
     End If
    End Function
    
    Private Sub Form_Load()
     TimeCounter = 1
     
     info.structSize = Len(info)
    
     GetLastInputInfo info
    
     FirstTick = info.tickCount
     
     Text1.Text = "Application Started at " & Time & ", First Tick Count = " & FirstTick & vbCrLf
    End Sub

    EDIT:

    BTW: I too was able to get it to work down at 3 seconds, even 10 but not five minutes. Maybe 5 minutes is too big of a tick count, I don't know
    Last edited by jmsrickland; Jan 18th, 2008 at 04:23 PM.

  11. #11
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Can I extract seconds from Tick Count?

    Don't you think the way I've done this is a bit simpler?
    Set MAXIDLE to 300 and set the Timer.interval to 10000 and you've got a guaranteed Flag at 300 to 310 seconds of inactivity.

    Not that we're checking it but the Api should be declared as Long as it's declared as BOOL at MSDN. BOOL is not the same as Boolean. Change it to Long but treat it as Boolean and it will work as it should.
    Last edited by Milk; May 15th, 2008 at 08:39 PM. Reason: spelling

  12. #12

    Thread Starter
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: Can I extract seconds from Tick Count?

    Milk,

    Yes I do. I think your way is totally better. So, if you don't mind I want to use your method. Also, I want to post your example in another thread where I was trying to help someone with this same problem but I will give you the credit for the code.

  13. #13
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Can I extract seconds from Tick Count?

    No problems at all

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width