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


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
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
  • 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.
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


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

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

Question has a verified solution.

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

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
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…
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

604 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