News:

MyKidsDiary.in :: Capture your kids magical moment and create your Online Private Diary for your kids

Main Menu

Alarm application in Visual C++/MFC

Started by thiruvasagamani, Sep 01, 2008, 03:39 PM

Previous topic - Next topic

thiruvasagamani

This project shows the development of a class that is useful as a reminder or to perform
some tasks at a given time or time interval. The class is developed using Visual C++ MFC and won?t work in an application that does not use MFC.

   There are two classes. The main class is called CSchedule and the helper class is CAlarm. The schedule-class holds a collection of alarms and starts each one whenever needed.

Multi threaded Alarm proc:

   This is a pointer to a function (void function (void)) that will be executed when the alarm
is fired. You need to write this function and give it as a parameter when adding an alarm to the schedule.

Alarm IDs:

   When you add an alarm to the list you will add it with an ID of you desire. Be careful not to add two alarms with same IDs! The ID is used to get an alarm. The IDs do not need to be subsequent numbers. You can use just any integer value.

Schedule loop:

   This loop needs to be started in order for the alarms to be fired. Only when you start the loop, the schedule class will check which alarms to fire.

   So here are the methods of CSchedule and their use:

    void addSingleAlarm(int ID, const CTime& start_time, CAlarm::alarm_proc proc);
       Adds an alarm that will only be started once, at the time shown by start_time.

    void addMultiAlarm(int ID, const CTimeSpan& tspan, const CTime& since, CAlarm::
    alarm_proc proc);
       Adds an alarm that will be started in equal intervals shown by tspan, but only after the
    time shown by since.

    void removeAlarm(int ID);
       Removes the alarm with given ID.

    const CAlarm* alarm(int ID) const;
    CAlarm* alarm(int ID);
       Give the alarm with given ID.

    void startLoop();
       Starts the main schedule loop.


    void stopLoop();
       Stops the main schedule loop.


    bool isRunning();
       Shows if the main schedule loop is running.

    And here are the methods of CAlarm that you might want to use:

    void setTime(const CTime& time)
       Sets the time in which to fire the alarm or before which multi-alarms wont be started.

    const CTime& getTime() const
       Retrieves the time when the alarm is supposed to be fired

    const CTimeSpan& getTimeSpan() const
       Retrieves the time-interval of two multi-alarms.

    bool isSignle() const
       Shows if the alarm is single-alarm or multi-alarm

    bool isEnabled() const
       Shows if the alarm is enabled

    void fire() const
       Fires the alarm (Executers the alarm proc)

    void disable()
       Disables the alarm.

    void enable()

       Enables the alarm. By default alarms are enabled.

   The CSchedule class holds a collection of CAlarm objects in a CMap collection. We did this so the user can add alarms with different ids without having to make sure they are subsequent. The map is good when you need fast indexing and adding/removing.

   The actual job of the scheduler is actually done in the startLoop function. There a new
windows thread is started in which the alarms are checked and fired.

   The new thread is defined in the function UINT ScheduleThreadProc( LPVOID pParam ) that takes as a parameter a CSchedule class pointer. So the startLoop function looks like this:

    void CSchedule::startLoop()
    {
    if(m_bIsRunning) return;
    m_bIsRunning = true;
    AfxBeginThread(ScheduleThreadProc, this);
    }


   Check if the loop is tuning if it is don?t start it again if not start it and give you as a
parameter.The ScheduleThreadProc repeatedly iterates all the items in the map-member of the class and if some needs to be started it starts it.

   So it first gets the current time, and then compares it to the time plus time span of the
alarm. The time span of a single alarm should be zero so it won?t affect the result. If the
new result is bigger or equal to the current time that means that the alarm needs to be
fired. We check if it?s enabled and if yes we fire it. Then we change the alarm?s time to
the alarm?s current time plus the time span so the multiple-alarm is started again the next time. If the alarm is single it shouldn?t be started again so we can remove it from the map.

   That?s what this function does. And here it is with code:

    UINT ScheduleThreadProc( LPVOID pParam )
    {
    CSchedule* pSchedule = (CSchedule*)pParam;

    POSITION pos;
    int ID;
    CAlarm* pAlarm;
    CTime curTime;

    while(pSchedule->isRunning()) {
    if(pSchedule->m_mapAlarms.IsEmpty())
    continue;
    curTime = CTime::GetCurrentTime();
    pos = pSchedule->m_mapAlarms.GetStartPosition();
    while(pos!=NULL) {
    pSchedule->m_mapAlarms.GetNextAssoc(pos, ID, pAlarm);
    // pAlarm->getTimeSpan() should be 0 in single alarms
    if(pAlarm->getTime() + pAlarm->getTimeSpan() <= curTime) {
    if(pAlarm->isEnabled())
    pAlarm->fire();
    pAlarm->setTime(pAlarm->getTime() + pAlarm->getTimeSpan());
    if(pAlarm->isSignle()) {
    delete pAlarm;
    pSchedule->m_mapAlarms.RemoveKey(ID);
    }
    }
    }
    }

    return 0;
    }


   In this particular sample project we set a time for a single alarm, which is added to the
schedule-class. The alarm proc plays a short ? sound and pops a message box.

Thiruvasakamani Karnan


nandagopal



will this code work in real time

anybody tested this code in real time please tell me