How to Make an MFC Alarm Application
If you want an alarm application so that you can remember to perform a particular task at certain time, think about using Visual C++. Its alarm subsystem "alarm.h" is designed to handle alarms based on the operating system clock. The MFC alarm_proc function pointer can be wrapped inside member functions in a CAlarm class. Then a CSchedule class can manage CAlarm objects to make your application functional.
Instructions
-
-
1
Understand the alarm_proc function pointer that's at the heart of the program. It accepts as parameters the execution time of the alarm and an alarm ID or alarm handle value. Here is its prototype:
typedef void (*alarm_proc)(int time, int alarm_id);
-
2
Put alarm_proc into a class, CAlarm, to give it instructions. The member functions of CAlarm will represent simple tasks such as enable, disable, setting a time and more. Here's a suggestion on how you could implement CAlarm:
class CAlarm
{
public:
typedef void (*alarm_proc)();
//creates an alarm
CAlarm(const CTime& time, alarm_proc fire): mTime(time), mEnabled(true) {
mAlarm_proc = fire;
}
~CAlarm(){}
void setTime(const CTime& time) {
mTime = time;
}
const CTime& getTime() const {
return mTime;
}
bool isEnabled() const {
return mEnabled;
}
void fire() const {
mAlarm_proc();
}
void disable() {
mEnabled = false;
}
void enable() {
mEnabled = true;
}
protected:
bool mEnabled;
CTime mTime;
mutable alarm_proc mAlarm_proc;
};
-
-
3
Design a CScheduler class for manipulating CAlarm objects. At minimum, it should do what a typical stop watch does. That is, it should start a loop, stop a loop and reset, but also add an alarm, remove an alarm and so on. Following is a suggestion for a CScheduler class. Only the public member functions (class interfaces) are shown. Implementing each member function is left as an exercise for the programmer:
class CScheduler
{
public:
CScheduler();
~CScheduler();
void AddAlarm(int handle, const CTime& time, CAlarm::alarm_proc fire);
void RemoveAlarm(int handle);
const CAlarm* Alarm(int handle) const;
CAlarm* Alarm(int handle);
void StartLoop();
void StopLoop();
bool IsRunning() const;
void Reset();
private:
//
protected:
//
};
-
4
Use an MFC CMap class to store the CAlarm objects in the CScheduler class. A CMap array is excellent for fast indexing and add/delete operations. Put the CMap variable in the "protected" access identifier of the CScheduler class. Here's what it looks like:
class CScheduler {
public:
//
protected:
CMapmAlarms;
};
-
5
Create a function that continually iterates through the CMap objects (CAlarms) and, if one needs to be executed, executes it. Make it a friend and put it in "protected" in CScheduler, under mAlarms. Its simplified implementation can be as follows:
int Iterate( CSchedule* pSchedule ){
POSITION pos;
int ID;
CAlarm* pAlarm;
CTime time;
while(pSchedule->isRunning()){
if(pSchedule->mAlarms.IsEmpty())
continue;
time = CTime::GetCurrentTime();
pos = pSchedule->mAlarms.GetStartPosition();
while(pos!=NULL) {
pSchedule->mAlarms.GetNextAssoc(pos, ID, pAlarm);
if(pAlarm->getTime() <= time) {
if(pAlarm->isEnabled())
pAlarm->fire();
pAlarm->setTime(pAlarm->getTime());
delete pAlarm;
}
}
}
return 0;
}
-
6
Use the CScheduler class in an MFC application. It won't run elsewhere. Add the CScheduler and CAlarm cpp and h files to your project. Make an instance of the CSchedule class in your application. And, of course, don't forget to call Iterate().
-
1