Click here to Skip to main content
15,881,600 members
Articles / Desktop Programming / MFC
Article

Simple Events System

Rate me:
Please Sign up or sign in to vote.
4.00/5 (6 votes)
2 Dec 20021 min read 70.1K   1.8K   36   5
This code is based on Jeffry Ritcher "Applicate .NET Framework"

Introduction

Microsoft introduced an events system in VC++ 7 using keywords (event_source, event_receiver, __event, __raise, __hook, __unhook), expanding the language with a great tool. This cool feature is not provided in VC++ 6.0 language.

My code provides users of VC++ 6.0 (could be used in other C++ systems) a simple events system, made in VC++ 6.0 and STL, with a small amount of code needed in order to use it.

Using the code

The first thing to do is define the events provider, the events list and a struct that contains the events arguments.

The code is something like this:

1. Defining the events argument's list struct (inherited from EventArgs).

MC++
//**** Source Event Arguments
struct SourceEventArgs : EventArgs {
	// Only have a int argument, but the 
	// structure could be more complex
	int nRetCode;
	// ... Others arguments needed for any Source class event 
};

2. Declaring a class capable of "firing" the events (inherited from SourceEvents).

MC++
// Generate events
class Source : public SourceEvents {
	...
};

3. Construct the "events" map

MC++
// Generate events
class Source : public SourceEvents {
protected:
	//Events provided for this class
	_BEGIN_EVENTS_HANDLER
		_EVENT_HANDLER( Close )
		_EVENT_HANDLER( Idle  )
	_END_EVENTS_HANDLER
	...

4. Define methods to "fire" the events

MC++
// Generate events
class Source : public SourceEvents {
protected:
	//Events provided for this class
	_BEGIN_EVENTS_HANDLER
		_EVENT_HANDLER( Close )
		_EVENT_HANDLER( Idle  )
	_END_EVENTS_HANDLER

   // Any name is acceptable but the standar is OnEventName
	void OnIdle();

   // this is a normal method that is calling for your code
   // so any signature is correct ( Ex. int OnClose(int) ).
   int OnClose(int);	
			

	...

//Implementation file
void Source::OnIdle() { 
	//_raise 
	SourceEventArgs e;
	e.nRetCode = 0;
	_raise(Idle, &e); // <-- this is the event launch
}

int Source::OnClose(int nRetCode) { 
	//_raise 
	SourceEventArgs e;
	e.nRetCode = nRetCode;
	_raise(Idle, &e); // <-- this is the event launch
	return e.nRetCode;
}

Ok, now the we have the class Source, it can launch Close and Idle events for any number of event listener. And now we need a class capable of listening to the events generated.

The code is simple

MC++
// Events Listener
class Target {
	int m_code;
public:
	Target(int i) : m_code(i) { }
	//A normal way for declare this function is under protected and
	//call this internally when the event have to be generated.
	//Use the source object is not necesary but can help you
	//for do some task.
	void OnIdle(Source* pObj, SourceEventArgs* e) {
		cout << "Target" << m_code <<
                                " el valor actual de e = " << e->nRetCode++;
		cout << " " << pObj->Name() << endl;
	}
	// Return event value is allowed by use of structure
	void OnClose(Source* /*pObj*/, SourceEventArgs* e) {
		cout << "Target" << m_code <<
                                 " el valor actual de e = "<< e->nRetCode << endl;
		e->nRetCode = 4;
	}

	// Subscription function (Source is the class name for events
	//generator class).
	_DECLARE_HOOK_LIST( Source ) // <-- this is the declaration of listener.
};

// implementation file
// this define the hooks for each events catch for this class
// Source class name of events generator
// Target class name of events listener
// SourceEventArgs struct name of events arguments struct
_BEGIN_HOOK_LIST(Source, Target, SourceEventArgs)
	_HOOK(Idle , OnIdle ) // Idle the name of event
	_HOOK(Close, OnClose) // OnIdle the name of function how process the event
_END_HOOK_LIST

The last step is joining the object to listening events.

MC++
// Creating objects
Source s;
Target t(1);

// Joining listener for listening (t) events generated by Sourcer (s)
t.JoinTo(&s);

// launch events directly you may call this methods internally.
s.Idle();
s.Close();

//UnJoin
t.UnJoinTo(&s); // can use t.JoinTo(&s, false);

Remember that it is important to call the unjoin method before erasing the objects

Comment

Ok this it's my first one article and I expect that be of great aid. Please let me know and good look.

Edit History

27 Nov 2002 - Initial Edit

3 Dec 2002 - updated downloads

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Colombia Colombia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralGood code Pin
flyingdonkey25-Dec-05 16:14
flyingdonkey25-Dec-05 16:14 
QuestionIs this event system asynchronous? Pin
Member 130650928-Sep-04 20:30
Member 130650928-Sep-04 20:30 
GeneralNice... Pin
M.Khadem6-Nov-03 17:35
M.Khadem6-Nov-03 17:35 
would you like to make a win GUI demo with this way?Blush | :O
(I can help you!;) )
tanks
GeneralRe: Nice... Pin
mgomez7-Nov-03 9:15
mgomez7-Nov-03 9:15 
GeneralSource Code Pin
mgomez3-Dec-02 2:35
mgomez3-Dec-02 2:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.