Timer Support for Non-Window Classes

Recently I had to create a proprietary communication protocol stack to provide a link to custom hardware. During this task Ive encoutered a problem. I needed a timer. Windows provides you timers through SetTimer() function or through CWnd::SetTimer() function. In both cases, your class must be a window to use the timer. I did not have the luxury, so I created my own class that provides timer support to non- window objects. I use VC++ with MFC.

All you have to do is to derive your class from CtimerSupport class and then you can use CtimerSupport::SetTimer() and CtimerSupport::KillTimer() functions. And you have to override virtual function OnTimer(UINT nTimerID);

You will also have to override handler for WM_TIMER message in your main window. Sample handler will look like:

/**********************************************************
 * Module:    Handler to process WM_TIMER message
 *
 * Parameters:  nIDEvent  - Timer that expired
 * Returns:   none
 * Globals:   none
 *  
 **********************************************************
 */

void CMainFrame::OnTimer(UINT nIDEvent) 
{
 // Call appropriate handler
 ((STimerInfo *)nIDEvent)->pObject->OnTimer(nIDEvent);
  
 CFrameWnd::OnTimer(nIDEvent);
}

The idea behind the CtimerSupport class is to use main window as a mechanism to manipulate timers, but hide it from the rest of the code.

To start a timer in your code use SetTimer (UINT nTimerEvent, UINT nElapse), where nTimerEvent is user-defined event serving to identify the timer if multiple timers are used. NElapse is timer duration in ms.

SetTimer() returns 32-bit timer ID. This must be stored for future referencing to the timer.

Use KillTimer(UINT nTimerID) to stop the timer. nTimerID is the value returned by SetTimer().

OnTimer(UINT nTimerID) is called when timer expires. NTimerID is the value returned by the SetTimer(). You can get user-defined event out of timer ID by calling GetTimerEvent (UINT nTimerID). Thus, timers are differentiated by their Ids and/or by the user-defined event.

Notes

  1. Timers are continuous. If timer is not stopped by KillTimer() it will continue to generate calls to OnTimer(). If you want one-shot timer, call KillTimer() in the OnTimer() routine.
  2. Timer events are stacked. If timer expiration was not processed before timer expires again, two consecutive calls to OnTimer() will be made. Killing the timer does not clear the message queue, so any outstanding timer events will be processed, even if timer is stopped.

Downloads

Download source - 3 Kb


Comments

  • a over solution is to declare a CDialog, but not uses it

    Posted by Legacy on 10/31/2002 12:00am

    Originally posted by: Gausi Eric

    CDialog dlg;
    
    m_pMainWnd = &dlg;

    WORD lwId = SetTimer( m_pMainWnd->m_hWnd, (unsigned int) this, ldwWait, TimerProc);

    Reply
  • A timer that guarantees a minimum ET...

    Posted by Legacy on 08/21/2002 12:00am

    Originally posted by: Keith Doyle

    What can you do if you need a timer that will be guaranteed
    that at least the timer period has elapsed since the last
    call to the OnTimer function? Implied by the original article, if a timer event is delayed by the OS, the next event may come early (relative to the occurance of the previous event). I need a timer that can arrive later, but can't arrive sooner than the selected time relative to the last OnTimer call...


    Keith Doyle

    Reply
  • Timer Support For Non Window Classes

    Posted by Legacy on 07/18/2002 12:00am

    Originally posted by: Nigel Merritt

    There is some extra information needed to make this useable...
    
    The STimerInfo has been left out of the code. It is just a data class, used to hold a pointer to the class derived from STimerSupport. I have created one (called CTimerData, but call it what you want):

    #include "Timer.h"

    class CTimerData
    {
    public:
    CTimerData();
    virtual ~CTimerData();

    UINT timer_id;
    CTimerSupport* target_object;
    };

    I don't think it actually needs the timer_id, as this is returned by the main window class.

    A class is derived from the CTimerSupport that can then create these timers. An example is...

    #include "timer.h"

    class CTimerClass : public CTimerSupport
    {
    public:
    virtual void myFunction();
    CTimerClass();
    virtual ~CTimerClass();

    // Override the OnTimer method.
    virtual void OnTimer (UINT nTimerID);
    private:
    UINT m_timerId;
    bool m_timerRunning;
    UINT m_Delay;
    };

    This timer uses a conversion (from address to UINT) to create the timer id.

    Reply
  • STimerInfo

    Posted by Legacy on 04/09/2002 12:00am

    Originally posted by: Sameer Maggon

    What is STimerInfo.. During comppilation..
    Its is giving errors

    Sameer

    Reply
  • One problem with this code

    Posted by Legacy on 02/23/2002 12:00am

    Originally posted by: Girish Chavan

    U must have definately encountered this. After calling settimer the object gets destroyed, so by the time OnTimer is called in the main window, the ptr. to the object in the handler is invalid, result, Illegal Op.Reason to this is Timer operation is overlapped, hence object continues execution after setting timer, eventually being destroyed.

    How do i overcome this?????

    Reply
  • I understand what's your idea.

    Posted by Legacy on 01/30/2002 12:00am

    Originally posted by: shocklet


    I think you use uEventID to save the pointer to user-specific data.

    generally, pointer values are unique when it's not cross referenced.

    so, you using this well.

    Reply
  • Timer support For non-window classes

    Posted by Legacy on 10/31/2001 12:00am

    Originally posted by: Braam

    What is STimerInfo!!!

    Reply
  • SetTimer

    Posted by Legacy on 03/19/2001 12:00am

    Originally posted by: kacciv

    What is STimerinfo ?

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: December 18, 2014 The Internet of Things (IoT) incorporates physical devices into business processes using predictive analytics. While it relies heavily on existing Internet technologies, it differs by including physical devices, specialized protocols, physical analytics, and a unique partner network. To capture the real business value of IoT, the industry must move beyond customized projects to general patterns and platforms. Check out this webcast and join industry experts as …

  • Learn How A Global Entertainment Company Saw a 448% ROI Every business today uses software to manage systems, deliver products, and empower employees to do their jobs. But software inevitably breaks, and when it does, businesses lose money -- in the form of dissatisfied customers, missed SLAs or lost productivity. PagerDuty, an operations performance platform, solves this problem by helping operations engineers and developers more effectively manage and resolve incidents across a company's global operations. …

Most Popular Programming Stories

More for Developers

RSS Feeds