Click here to Skip to main content
6,597,576 members and growing! (19,639 online)
Email Password   helpLost your password?
Languages » C / C++ Language » Delegates     Intermediate

Simple Events System

By Manuel Alejandro Gómez

This code is based on Jeffry Ritcher "Applicate .NET Framework"
VC6, VC7Win2K, WinXP, MFC, Dev
Posted:26 Nov 2002
Updated:2 Dec 2002
Views:50,983
Bookmarked:26 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
8 votes for this article.
Popularity: 3.61 Rating: 4.00 out of 5
1 vote, 16.7%
1

2

3
2 votes, 33.3%
4
3 votes, 50.0%
5

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).

//**** 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).

// Generate events

class Source : public SourceEvents {
	...
};

3. Construct the "events" map

// 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

// 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

// 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.

// 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

About the Author

Manuel Alejandro Gómez


Member

Location: Colombia Colombia

Other popular C / C++ Language articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 5 of 5 (Total in Forum: 5) (Refresh)FirstPrevNext
GeneralGood code Pinmemberflyingdonkey17:14 25 Dec '05  
GeneralIs this event system asynchronous? PinmemberMattias Bergkvist21:30 28 Sep '04  
GeneralNice... PinmemberM.Khadem18:35 6 Nov '03  
GeneralRe: Nice... Pinmembermgomez10:15 7 Nov '03  
GeneralSource Code Pinmembermgomez3:35 3 Dec '02  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 2 Dec 2002
Editor: Chris Maunder
Copyright 2002 by Manuel Alejandro Gómez
Everything else Copyright © CodeProject, 1999-2009
Web21 | Advertise on the Code Project