Add a timer programmatically

Posted on 2001-08-03
Last Modified: 2008-02-01
How to adda timer control to a project (module)programmatically...

Of course I would also need to assign events from the 'timer' to a routine that I already have within the module

Question by:mcoop
  • 6
  • 3
  • 2
  • +4
LVL 43

Expert Comment

ID: 6348677
You cannot handle events within a standard module, you have to add it to an object module such as a form. Now there are alternatives, if you go to and download the ccrp timer you can use this in a class module but still not a standard module.

Expert Comment

ID: 6348681
Do you mean at run time or design time?

Expert Comment

ID: 6348704
in the module(*.bas) you need to use timer api functions and vb callback functions.

I can post some code.
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.


Expert Comment

ID: 6348713
Can we ask why you wnat to do this? I'm sure that there'll be a better way to acheive what you want.
LVL 16

Expert Comment

ID: 6349539
There is aclass you could use:
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
Attribute VB_Name = "CFormlessTimer"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
Option Explicit
Private Declare Function SetTimer Lib "user32" _
            (ByVal hwnd As Long, _
            ByVal nIDEvent As Long, _
            ByVal uElapse As Long, _
            ByVal lpTimerFunc As Long) As Long

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

' Member vars:
Private m_Enabled As Boolean
Private m_MilliSeconds As Long
Private m_TimerNumber As Long

Public Event Timer()

Public Sub StopTimer()
If m_TimerNumber <> 0 Then
    KillTimer 0, m_TimerNumber
End If
End Sub

Public Sub StartTimer()
If m_MilliSeconds > 0 Then
    m_TimerNumber = SetTimer(0, 0, m_MilliSeconds, AddressOf TimerProc)
End If
End Sub

Public Property Get Interval() As Long
Interval = m_MilliSeconds
End Property

Public Property Let Interval(ByVal MilliSeconds As Long)
m_MilliSeconds = MilliSeconds
End Property

Public Function TimerEvnt()
Attribute TimerEvnt.VB_MemberFlags = "40"
RaiseEvent Timer
End Function

Private Sub Class_Initialize()
Set modTmrProc.cls = Me
End Sub

Private Sub Class_Terminate()
Call StopTimer
End Sub

Author Comment

ID: 6350405
To answer the earlier questiosn - and perhaps solve my problem...

The code as noted is in a formless application.
... Hence the timer should be created at runtime (i.e. no form to contain the standard timer control)

rkot2 - I thought a module was the answer - but Richie_Simonetti  has suiggested a class - which is a much better idea as it contains all the methods and properties in a 'standard' VB manner...

...but being a class neophyte...


 - your suggestion looks like what I am after...

I've created the class, but how do I expose the timer object inside my (formless) application ?


I named the class 'FormlessTimer'

How to make this work... (startup is Sub main)

sub main()
   FormlessTimer.Interval = 5000
end sub

public sub FormlessTimer_Timer()
  msgbox "formless timer event"
end sub

.. some sample code please ?

I get method or data member not found (at the .Interval=5000) line

Expert Comment

ID: 6350566
LVL 16

Expert Comment

ID: 6350596
You need to create an object variable for that class to work:

' in your mmain module
dim tmr as Formlesstimer

sub main
set tmr = new Formlesstimer

' Don't forget to set that class to nothing when finishes the work

Expert Comment

ID: 6350880

If you want to create a 'timer' with no form, you may want to try this:

Use the sleep API, then add the code:

While Not ExitLoop = True
Sleep 30000 /or whatever values you prefer
'Execute code

That's it!

glass cookie : )

PS. Please pardon me if the VB syntax is wrong as I've been using lots of c++ codes recently.

Author Comment

ID: 6350899

I'm with you all the way so far - but how do I declare  the 'timer' event in my module...  how i the CformlessTimer bound back to _my_ timer_event 'code' ??

glass_cookie - thanks for the sleep() command but it suspends the thread whereas a timer allows foregrond processing in the task until the timer_event triggers.
LVL 16

Expert Comment

ID: 6350916
I am so sorry! i forgot to post the module that comes with this class. I haven't it right now....!!! it is at my office!
LVL 16

Expert Comment

ID: 6350925
LVL 16

Expert Comment

ID: 6350927

Visual Basic Q&A "How-To" Pages
By Bob Butler


Using a Timer Without a Form {28-May-1999}

The Timer control in VB must be situated on a form in order to be part of
the project. In some cases, notably ActiveX servers, there may not be
any form to act as a host. Although in many cases a form can be loaded
and simply not shown, it is also possible to use a system timer via API
calls without using a control.

Start a new project and place the following code in a module:
Option Explicit
Private Declare Function KillTimer Lib "user32" (ByVal hWnd As Long, _
  ByVal nIDEvent As Long) As Long
Private Declare Function SetTimer Lib "user32" (ByVal hWnd As Long, _
  ByVal nIDEvent As Long, ByVal uElapse As Long, _
  ByVal lpTimerFunc As Long) As Long
Private Declare Function GetDesktopWindow Lib "user32" () As Long

Public Function TimerEnable(ByVal hWnd As Long, _
  ByVal TimerID As Long, ByVal mSecs As Long) As Long
TimerEnable = SetTimer(hWnd, TimerID, mSecs, _
  AddressOf TimerFired)
End Function

Public Function TimerDisable(ByVal hWnd As Long, _
  ByVal TimerID As Long) As Long
TimerDisable = KillTimer(hWnd, TimerID)
End Function

Private Sub TimerFired(ByVal hWnd As Long, _
  ByVal TimerID As Long, ByVal IDEvent As Long, _
  ByVal dwTime As Long)
Debug.Print "Fired "; hWnd; TimerID; IDEvent; dwTime
End Sub

Then place this code in a form (just for testing) after creating two
command buttons named cmdStart and cmdStop:
Option Explicit
Private mlTimer1 As Long
Private mlTimer2 As Long

Private Sub cmdStart_Click()
mlTimer1 = TimerEnable(0, 1, 3000)
mlTimer2 = TimerEnable(0, 2, 5000)
Debug.Print "Start 1: "; mlTimer1
Debug.Print "Start 2: "; mlTimer2
End Sub

Private Sub cmdStop_Click()
Debug.Print "Stop: "; TimerDisable(0, mlTimer1)
Debug.Print "Stop: "; TimerDisable(0, mlTimer2)
End Sub

When you run the application you should be able to click the START button
and watch the timer events occurring in the debug window. Clicking STOP
will terminate the timers. There are a few things to watch out for:
1. ALWAYS be sure to stop the timers before stopping the program. If you
don't then the timers will continue to run and your app may appear in the
tasklist after terminating.
2. The return value from the SetTimer call will be the IDEvent value in
the function run when it fires. You can test this value to determine
which timer fired if more than one is started.
3. The function MUST be in a BAS module in VB5 due to restrictions in the
AddressOf operator. If you need to reference it in multiple class or other
modules then your function must know how to re-direct the event to the
appropriate place. An alternative is using a different function for each
SetTimer call.

Special thanks to James Belleau for pointing out a rather serious bug in the
original version of this page.

LVL 16

Accepted Solution

Richie_Simonetti earned 100 total points
ID: 6350930

Author Comment

ID: 6538155
Thanks - sorry for the delay, EE has been sick, and I have been busy.

Ended up using your links for a solution.


Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

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…
Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

828 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