Add a timer programmatically

Posted on 2001-08-03
Medium Priority
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 http://www.mvps.org/ccrp 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.
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.


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 400 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: 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.

Question has a verified solution.

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

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
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…
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…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…
Suggested Courses
Course of the Month9 days, 15 hours left to enroll

571 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