### Setting Time Intervals

A timer controls when certain events will occur based on a specified timed basis. You can use the ITimer class objects to set time-interval-based operations. The Open Class Class Library uses timers in fly-over help and with IAnimatedButton. The Open Class Class Library provides the following classes to create timer objects:

ITimer
  This class creates objects representing operating system timers. An object of this class calls a specified function in your class when the timer expires. The timer continues to call the function each time the specified time limit expires.
ITimerFn
  An abstract timer function class. An instance of this class is passed into ITimer when you start it. You can then delete the ITimer object, and the timer will continue to run.
ITimerMemberFn
  Template class for the timer member function. This class inherits from ITimerFn.
ITimerMemberFn0
  Another template class for the timer member function. This class does not accept any parameters.

#### Creating Timers

Use the ITimer class objects to define and set time-interval-based operations for your current program. You can also use ITimer objects to create additional time-interval-based operations by instantiating new ITimer objects and starting them. You start a timer using the ITimer::start member function.

The following is an example of starting a new timer to execute a member function:

    ITimer timer
    timer.start( new ITimerMemberFn< MyClass >( *this, foo ) );

You construct instances of this class in one of the following ways:

- Using the default constructor. Use this to build an ITimer that is started using the ITimer::start member function.
- With specification of code to run. This form of the constructor is used to construct a new ITimer and immediately start it. It is equivalent to constructing using the default constructor and then using ITimer::start. You can specify a time-interval to be used (in thousandths of a second) with this constructor. A time-interval of one second is the default.
- From the timer ID of a currently started ITimer object.

Note: | ITimer has a virtual destructor that deallocates resources. This destructor, however, does not stop the timer. The timer continues to run until you call ITimer::stop. The reference to the class that is passed into the constructor must be dynamically allocated. Otherwise, it results in an exception when the timer is stopped. Furthermore, stopping the timer deletes the allocation of the object making any previous pointers to it illegal.

Timer identifiers are limited to the value 0x7FFF to allow portability to OS/2 where this limit is imposed by the operating system.

The ITimerFn class is an abstract timer function class. Objects of this class represent events dispatched when an active timer expires. These objects are reference-counted to manage their destruction after the timer has stopped. This reference to an ITimerFn is then passed to ITimer::start. The timerExpired function is called when the timer expires.

The ITimerMemberFn template class is an ITimerFn-derived class for dispatching C++ member functions against an object when a timer expires.

You can use instances of this class to dispatch C++ member functions when a timer expires. The template argument is the class of the object for which the member functions are called. The constructor for such objects requires a reference to the object the member function is to be applied to and a pointer to the member function.

This member function must return a void and accept a timer reference argument.

Note: | This class overrides the inherited function, timerExpired.

To create a timer, do the following:

1. Write a function for what you want to do on a timed basis.
2. Create an ITimerMemberFn or ITimerMemberFn0 object. For a function that will be repeating an action on a timed basis, use ITimerMemberFn0.

   Use ITimerMemberFn if you need to know the timer ID and use ITimerMemberFn0 if you do not need the timer ID. If you need the timer ID, then you must define a function that takes an unsigned long and provide this function on the ITimerMemberFn constructor. The timer ID is passed to you when the timer pops. For ITimerMemberFn0, you define a function that takes no parameters and you do not get the timer ID.

   An example would be if you wanted a window to refresh itself every 30 minutes. If you wanted a window displayed for five seconds and then have it disappear, you would use ITimerMemberFn because the action only occurs once. You would then use ITimer::stop to delete the timer.

Note: | If you call setInterval with any value, the timer is stopped and restarted with the new interval. Restarting the timer with a value of zero causes the timer to timeout immediately and results in a call to your timer member function. If you call ITimer::start without stopping the timer, you will get an IInvalidRequest exception.

The following is an example of a timer created to run the public member job in MyClass:

    class MyClass {
    public:
    void job ( unsigned long timerId )
      {
      // Code to run.
      }
    };
    //...
    MyClass myObj;
    ITimer  timer;
    timer.start( new ITimerMemberFn<MyClass>( myObj, MyClass::job ) );

In the preceding example, we used ITimerMemberFn because the job member function returns void and accepts an unsigned long parameter, timerId. When parameters are not accepted by the member function, you can use ITimerMemberFn0.

#### Timer Example

The Hellow World Version 6 sample in the `\samples\ioc\hello6` directory uses the ITimerFn class which has a handler that gets called each time the timer expires.

In aerthw6.hpp file, we define our timer function that is called after the timer expires and we define our ITimer object.

    ITimer twinkleTimer;

    /**************************************************************************
    * Class ATwinkleTimeHandler - Time Handler class the processes time ticks *
    *   for AEarthWindow.                                                     *
    **************************************************************************/
    class ATwinkleTimeHandler : public ITimerFn
    {
      public:
    /*---------------------------- Constructor -------------------------------|
    | Constructs the object with                                              |
    | 1) A pointer to the earth window                                        |
    -------------------------------------------------------------------------*/
        ATwinkleTimeHandler (AEarthWindow *a) : aew(a) {}

    /*------------------------ Overridden Functions---------------------------|
    | timerExpired function is called each time the ITimer expires.           |
    -------------------------------------------------------------------------*/
        virtual void
          timerExpired (unsigned long);

      private:
        AEarthWindow
         *aew;
    };

    In the .cpp file we do the following:

    Define our time intercal for our timer.

      twinkleTimer.setInterval(500);

    Declare our timer function to be called when the timer
    expires.

    /*------------------------------------------------------------------------|
    | Tell the timer to stop twinkling.                                       |
    -------------------------------------------------------------------------*/
      if (twinkleTimer.isStarted())
         twinkleTimer.stop();

        Create the command handler that turns the timer on and off.

    /**************************************************************************
    * Class AEarthWindow :: enableTwinkle - Make the stars twinkle            *
    **************************************************************************/
    AEarthWindow
      &AEarthWindow :: enableTwinkle(bool turningOn)
    {
      if (turningOn && !twinkling)
      {
        twinkling=true;
        twinkleTimer.start(new ATwinkleTimeHandler(this));
        twinkleStars();
      }
      else if (!turningOn && twinkling)
      {
        twinkling=false;
        twinkleTimer.stop();
        addObjectsToGroup();
      }
      return (*this);
    } /* end AEarthWindow :: enableTwinkle (...) */

     Providing Help Information

     Adding Events and Event Handlers

     Hello World Version 6: Adding a
    Font Dialog, Pop-up Menus, Notebooks, and Graphics

    IFlyOverHelpHandler

    IFlyText

    ITimer

    ITimerFn