Tag Archives: gettickcount

Counters/Timers for the Visual Basic and VB.NET programmer

Click Star to Rate Post
1 Star2 Stars3 Stars4 Stars5 Stars (6 votes, average: 4.50 out of 5)
 

This article can be applied to all versions of VB including 6.0. Any code that may be posted here is originally set up for the .NET, but codes should be compatible with VB 6.0 by changing the variables and the declares to the right type and format. Example: If something is set to type Integer for .NET, the equivalent in VB 6.0 is Long. Otherwise, most of the .NET code should work fine in 6.0. The only trouble you may have is using 64 Bit Integers, which Classic VB doesn’t quite support. A work-around it using the Currency type (Which is technically a 64 Bit type) and converting it to a string while removing the decimal point. Check out this page for how to use the 64-bit Currency type in VB 6.0


Timers/Counters Info

This question on what timers are available using Visual Basic has a somewhat simple answer. Well, depending on the resolution you need to have.

GetTickCount – The “GetTickCount” function has a resolution of about 15-16(ms). IT returns the amount of milli-seconds that has elasped since your Windows OS has started.

    '
    'Provides about a 16(ms) resolution.
    '
    Private Declare Function getTickCount Lib "kernel32" Alias "GetTickCount" () As Integer

timeGetTime – If you need better accuracy, then you can try the multi-media timer: “timeGetTime” function, which can have a resolution of about 1(ms). It likewise returns the number of milli-seconds that has elasped since your Windows OS was started. But is has a much better resolution compared to the tick count function.

    '
    'Provides a resolution of 1(ms).
    '
    Private Declare Function timeGetTime Lib "winmm.dll" () As Integer

QueryPerformanceCounter – But, what if you need even better accuracy/resolution? The next option would be to use the computers high “Performance Timers”. (To check if the target computer actually supports this hardware timer, you would call either of the performance functions and look at its Return Value. If the return value is “0”(Zero), then the computer doesn’t support the hardware counter/timer feature. Not much more to say about this except you won’t be able to use this option.)

These functions are: ‘QueryPerformanceCounter’ and ‘QueryPerformanceFrequency’. With these functions its possible to get Sub-Millisecond accuracy/resolution. These timers could use a very small chip on your computers motherboard, which usually has a frequency of about: 3.6 Mhz. In some probably rare accurances these functions will actually use the RDTSC timestamp of your computers Processor. This would obviously have the highest resolution of all the timers in the computer. You can measure time in actual CPU Cycles. But i’ve rarely had this timer use that processor feature. In fact, I only witnessed it one time using my CPUs ReaDTimeStampCounter register. This would vary from computer to computer though. Microsoft says these functions could use either of these counters. * To determine which feature this counter/timer is using, you can use the function: QueryPerformanceFrequency function. This function returns the TickPerSeconds for the Performance Counter. Probably the most common value would be: 3579545. Which means that every second, this timer ticks 3,579,545 times, or around 3.6 million cycles per second. IF you have a 2ghz cpu/processor, and it is using your cpu’s rdtsc register, then the return value would be around the clockspeed of your processor.

    '
    'Gives you the current tick counts for the cpu since the computer has been running.
    'You could get very high resolutions in the Sub-Millisecond range with this counter/timer.
    Private Declare Function QueryPerformanceCounter Lib "kernel32" (ByRef counts As Long) As Integer
    '
    'Returns the frequency of the performanceCounter in counts-per-second.
    Private Declare Function QueryPerformanceFrequency Lib "kernel32" (ByRef frequency As Long) As Integer

RDTSC Register – This is a feature of all modern AMD/Intel CPUs/Processors since the original Pentium 1 was released. This timer ‘Ticks’ every time your Processor completes a ‘Cycle’. As you can probably discern, you can have some major high resolution timing available. But the big problem for getting to this timer if that its pretty much not possible to access this register on the CPU with the high level languages of Visual Basic and C#. But, if you can do a somewhat simple C++ DLL application, you can access this register and create a function in the .dll that will return the value of that timer when Visual Basic calls that .dll function. This is actually what I did with my: csRDTSC.dll I made with C++. IF you would like to use this .dll, just goto my main: http://www.vbcodesource.com webpage and under either the Classic or DotNET controls section page you can download and use it. The zip file includes the actual .DLL and a text file with the available functions.


Reference Information

Here is some reference links here that are related to these timer functions that would be more helpful.

QueryPerformanceCounter Reference…

Overview: QueryPerformanceCounter Function

How To: Time Managed Code Using QueryPerformanceCounter and QueryPerformanceFrequency


timeGetTime Reference

Multimedia Timer Reference – Overview of the timeGetTime related timers as msdn.com.
timeGetTime – The timeGetTime function retrieves the system time, in milliseconds. The system time is the time elapsed since Windows was started.


GetTickCount Reference…

GetTickCount Function

GetTickCount64 Function

How To – Retrieve Elapsed Time Since Windows Started


Conclusion

I really do hope you can get something useful from this small and brief article. I have many examples on my main webpage at: http://www.vbcodesource.com which shows how to use these timers. I even have a VB.NET – Example that compares the 3x most common timers that I outlined above. I also have a example for all of the Visual Basic versions (including Visual Basic.NET) that shows how to use my csRDTSC.DLL to get the time stamp value from the cpu and to calculate your processors clockspeed. Anyways, have fun 🙂

Jason

Minor Revision: 2015

Detecting if the User is Active or Idle – SystemWide using VB 6.0 and VB.NET

Click Star to Rate Post
1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5.00 out of 5)
 

There are times when you want to know not only if your user is interacting with your application but actually interacting anywhere on the computer. Especially if you are waiting for somekind of user Input. Microsoft thankfully made it easy as I found a API call on MSDN.com and I converted it from C++ to work with Visual Basic (Works for .NET, VB 2008/2010, VB 2013, and 2015). I actually have a VB 6.0 Example for doing this at my www.vbcodesource.com website. Below is the little API call…

Visual Basic 6.0

    '
    'The actual API call to use.
    Private Declare Function GetLastInputInfo Lib "user32.dll" (ByRef inputStructure As inputInfo) As Boolean
    '
    Private Type inputInfo

        structSize As Long

        tickCount As Long

    End Type

Visual Basic.NET Version…

    '
    'The actual API call to use.
    Private Declare Function GetLastInputInfo Lib "user32.dll" (ByRef inputStructure As inputInfo) As Boolean
    '
    Private Structure inputInfo

        Dim structSize As Int32

        Dim tickCount As Int32

    End Structure

Now that the APIs are out of the way, you only need to setup and use the codes. The code below will work for ALL VBs with just some minor changes…


Visual Basic 6.0

        '
        'The variable that will be passed to the API call and receive the activity report.
        Private info As inputInfo
        '
        'Visual Basic 5.0/6.0…
        Dim firstTick As Long
        Dim lastTick As Long

Visual Basic.NET…

        '
        'The variable that will be passed to the API call and receive the activity report.
        Private info As inputInfo
        '
        'Visual Basic.NET…
        '
        Dim firstTick As Int32
        '
        Dim lastTick As Int32

All I did next was use the code in a Timer control and set the Interval to 1000ms (1 Second) which will update the lblTime Label Control the Last time of day the user was active. The InputInfo structure will actually give you the tickcount for when the user was last active if you want to use that. I decided to simply get the actual time they were last active

        '
        'This timer will fire every 1000ms(One Second) or so displaying the last time the user was active.
        '
        'The size of the structure for the API call.
        info.structSize = Len(info)
        '
        'Call the API.
        GetLastInputInfo(info)
        '
        'Compare the tickcount values to determine if activity has occurred or not.
        If firstTick <> info.tickCount Then
            '
            'Display the current time of the users last activity.
            '
            'Change lblTime.Caption to lblTime.Text if using .NET and likewise change Time
            'to Now instead.
            lblTime.Caption = "Last Active: " & Time
            '
            'Get the new tick value.
            firstTick = info.tickCount

        End If

The example program wth the code in action


As I mentioned already, I put that code above in a Timer control, then I set to enable and disable the timer in Two Button controls.

Now your application will know when the user was last active on the computer. But remember, just because it says they are Not active doesn’t mean that they are not reading a document, a website, or some other task that doesn’t require user input. Have fun!

          Jason

Revised: 2015