C++通用事件支持宏

#ifndef _EVENT_SUPPORT_H_
#define _EVENT_SUPPORT_H_

//#ifdef _DEBUG
//#ifdef DEBUG_NEW
//#define new DEBUG_NEW
//#endif
//#endif

#include "windows.h"
#include <tchar.h> 

#ifndef TXTRACE
inline void TXTRACE(LPCTSTR, ...){}
#endif //

//C++通用事件支持宏

//本代码是经过对Visual C++ 7.0新引入的事件机制进行研究和反编译,
//接近乎相同的原理,编写而来.
//优点: 
//	任何C++类都可作为事件源和事件接收者
//	事件接收者的数目不限
//	支持编译时的类型检测
//	接口简单

//Written by sjh
//Version 1.1	(2001-09)

//Version 1.2	(2001-10)
	//取消了DECLARE_EVENT_SUPPORT宏
	//加入DECLARE_EVENT_RECEIVER宏
	//自动判断事件接收对象是否可用,防止接收对象被delete后的访问从突
//Version 1.3  (2002-6-12)
	//加入多线程支持
/*

使用说明:
	EVENT:
				用来在事件源中定义一个事件,事件的参数可自由定义.
				EVENT( 函数名, (参数定义), (相应的参数列表) ) 

	HookEvent:
				为事件源添加一个事件接收者.
				Source.HookEvent(事件名,接收对象指针,接收函数)

	UnhookEvent:
				删除一个事件源的事件接收者.
				Source.UnhookEvent(事件名,接收对象指针,接收函数)

	RaiseEvent:
				触发事件源的事件.
				Source.RaiseEvent(事件名(事件参数))

	DECLARE_EVENT_RECEIVER(classname)
	
代码示例:

//事件源
class CSource 
{
public:
	//末尾的X是为了区分源与接收者,不易混淆
	//为CSource添加一个 void OnTimerX(void) 的事件
	EVENT(OnTimerX,(),());	

	//为CSource添加一个 void OnDataX(BYTE* pBuf, DWORD nLen) 的事件
	EVENT(OnDataX,(BYTE* pBuf,DWORD nLen),(pBuf,nLen));

public:
	void FireOnTimer()//内部也可以激发事件
	{
		RaiseEvent( OnTimerX() );//使用宏触发OnTimerX事件

		OnTimerX();//也可直接调用OnTimerX
	}
}

//接收者
class CReceiver
{
	DECLARE_EVENT_RECEIVER(CReceiver)
public:
	void OnTimer();
	void OnData(BYTE* pBuf,DWORD nLen);
};

 ...

CSource s;
CReceiver r;

s.HookEvent(OnTimerX, &r, &CReceiver::OnTimer);
s.HookEvent(OnDataX, &r, &CReceiver::OnData);

s.RaiseEvent(OnTimerX());	//激发s的OnTimer事件

BYTE buf[128];
s.RaiseEvent(OnDataX(buf,128)); //激发s的OnData事件

s.FireOnTimer();
 ...

s.UnhookEvent(OnDataX,&r,&CReceiver::OnData);
*/

//p:带括号参数列表如(BYTE* pBuf,DWORD nLen),
//v:带括号参数,如(pBuf,nLen)
#define EVENT(f,p,v) DECLARE_EVENT(public,f,p,v)

//DECLARE_EVENT定义事件
//access为事件激发函数的访问类型
//如果事件只允许在内部被激发,可以将access设为protected
#define DECLARE_EVENT(access,f,p,v) \
	private:\
	struct _event_node_##f\
	{\
		virtual bool _NodeValid() = 0;\
		virtual void _Invoke p = 0;\
		virtual bool _IsEqual(void* pt,void* pf,bool bD) = 0;\
		bool bDeleted;\
		_event_node_##f* _pNext;\
	};\
	template<class T,class F>\
	struct _handler_##f: public _event_node_##f\
	{\
		T* _pThis;\
		F _pFun;\
		int _nPtrData;\
		bool _NodeValid ()\
		{\
			bool _b = false;\
			try{if(memcmp((BYTE*)_nPtrData,"################",16)==0)_b=true;}catch(...){}\
			return _b;\
		}\
		void _Invoke p\
		{\
			(_pThis->*_pFun)v;\
		}\
		bool _IsEqual(void* pt,void* pf,bool bD)\
		{\
			if( (void*)_pThis==pt && (pf==NULL || *((void**)&_pFun)==pf) && bD == bDeleted)\
				return true;\
			return false;\
		}\
	};\
	struct _nodes_##f\
	{\
		CRITICAL_SECTION m_cs;\
		_nodes_##f(){_pNodes=NULL;InitializeCriticalSection(&m_cs);}\
		~_nodes_##f(){DeleteCriticalSection(&m_cs);_event_node_##f* pNode = _pNodes;_event_node_##f* pTemp;while(pNode){pTemp=pNode->_pNext;delete pNode;pNode=pTemp;}}\
		_event_node_##f* _pNodes;\
		void _Lock(){EnterCriticalSection(&m_cs);}\
		void _Unlock(){LeaveCriticalSection(&m_cs);}\
	}_xNodes_##f;\
	public:\
	template<class T,class F>\
	long HookEvent_##f(T* pThis,F pFun)\
	{\
		if(pThis)\
		{\
			_xNodes_##f._Lock();\
			_handler_##f<T,F>* pNode = new _handler_##f<T,F>;\
			pNode->_pThis = pThis;\
			pNode->_nPtrData = (int)pThis + pThis->_xEventReceiver.nOffset;\
			pNode->_pFun = pFun;\
			pNode->_pNext = _xNodes_##f._pNodes;\
			pNode->bDeleted=false;\
			_xNodes_##f._pNodes = pNode;\
			_xNodes_##f._Unlock();\
			return 1;\
		}\
		return 0;\
	}\
	template<class T,class F>\
	long UnhookEvent_##f(T* pThis,F pFun)\
	{\
		_xNodes_##f._Lock();\
		_event_node_##f* pNode = _xNodes_##f._pNodes;\
		_event_node_##f* pPre = NULL;\
		long nResult = 0;\
		void* pTemp = pFun==NULL ? NULL : *((void**)&pFun);\
		while(pNode)\
		{\
			if(pNode->_IsEqual(pThis,pTemp,pNode->bDeleted))\
			{\
				pNode->bDeleted = true;\
				if(pTemp){nResult=1;break;}\
			}\
			else\
			{\
				pPre = pNode;\
				pNode = pNode->_pNext;\
			}\
		}\
		_xNodes_##f._Unlock();\
		return nResult;\
	}\
	void RemoveAllEvent_##f()\
	{\
		_xNodes_##f._Lock();\
		_event_node_##f* pNode = _xNodes_##f._pNodes;\
		_event_node_##f* pTemp = NULL;\
		while(pNode)\
		{\
			pTemp = pNode->_pNext;\
			delete pNode;\
			pNode = pTemp;\
		}\
		_xNodes_##f._pNodes = NULL;\
		_xNodes_##f._Unlock();\
	}\
	access:\
	void f p\
	{\
		_xNodes_##f._Lock();\
		{\
			_event_node_##f* pNode = _xNodes_##f._pNodes;\
			_event_node_##f* pPre = NULL;\
			while(pNode)\
			{\
				if( !pNode->bDeleted && (pNode->_NodeValid()) )\
				{\
					if (pNode->_pNext)\
					{ (pNode->_Invoke v);pPre = pNode; pNode = pNode->_pNext;}\
					else\
					{\
						_xNodes_##f._Unlock();\
						\
						{\
							(pNode->_Invoke v);\
						}\
						return;\
					}\
				}\
				else\
				{TXTRACE(_T("Detected died event receiver , removed ok .\n"));if(pPre){pPre->_pNext = pNode->_pNext; delete pNode; pNode = pPre->_pNext;}\
				else{_xNodes_##f._pNodes = pNode->_pNext; delete pNode; pNode = _xNodes_##f._pNodes?_xNodes_##f._pNodes:NULL;}\
				}\
			}\
		}\
		_xNodes_##f._Unlock();\
	}\

#define HookEvent(e,t,f) HookEvent_##e(t,f)
#define UnhookEvent(e,t,f) UnhookEvent_##e(t,f)
#define RemoveAllEvent(e) RemoveAllEvent_##e()
#define RaiseEvent(e) e

#define DECLARE_EVENT_RECEIVER(classname) \
	public:\
	struct _event_Receiver\
	{\
		_event_Receiver(){memset(data,'#',16);nOffset=offsetof(classname,_xEventReceiver);}\
		~_event_Receiver(){memset(data,0,16);}\
		BYTE data[16];\
		int nOffset;\
	}_xEventReceiver;\




#endif //_EVENT_SUPPORT_H_

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值