|
|
大家直接调用宏即可
因为不用模版,每次RaiseEvent都要写出参数类型,如RaiseEvent(m_pClick,(int,long),aaa,bbb);
但是,更大的好处是,AddCallBack/RemoveCallBack时不用给出参数类型表!
代码的前面是List数据结构的实现,大家完全可以略过不看。
#include <iostream.h>
/////////////////////////////////////////////////////////////////////////////
template <class T> class IList
{
public:
virtual void VAdd(T* item)=0;
virtual void VRemove(int index)=0;
virtual void VClear()=0;
virtual int VGetCount()=0;
virtual T* VGet(int index)=0;
virtual void VSet(int index,T* val)=0;
};
/////////////////////////////////////////////////////////////////////////////
// note: int a[3] is : a[0],a[1],a[2]! so,a[0 to 3] will be int a[3+1]!
template <class T> class ArrayedList : public IList<T>
{
public:
virtual void VAdd(T* item);
virtual void VRemove(int index);
virtual void VClear();
virtual int VGetCount() { return m_Count; };
virtual T* VGet(int index){ if(index) return m_ppTs[index];return 0; };
virtual void VSet(int index,T* val){ if(index) m_ppTs[index]=val;};
~ArrayedList();
ArrayedList();
private:
T** m_ppTs;
public:
int m_Count;
};
template <class T> ArrayedList<T>::ArrayedList()
{
m_ppTs=new T*[0];
m_Count=0;
}
template <class T> ArrayedList<T>::~ArrayedList()
{
delete[] m_ppTs;
m_Count=0;
}
template <class T> void ArrayedList<T>::VAdd(T* item)
{
T** tmp=new T*[m_Count+1+1];
for (int i=1;i<=m_Count;i++)
tmp=m_ppTs;
delete[] m_ppTs;
m_ppTs=tmp;
m_ppTs[m_Count+1]=item;
m_Count+=1;
}
template <class T> void ArrayedList<T>::VClear()
{
delete[] m_ppTs;
m_ppTs=new T*[0];
}
template <class T> void ArrayedList<T>::VRemove(int index)
{
T** tmp=new T*[m_Count-1+1];
for (int i=1;i<=index-1;i++)
tmp=m_ppTs;
if (index<m_Count)
for (i=index+1;i<=m_Count;i++)
tmp[i-1]=m_ppTs;
m_Count-=1;
delete[] m_ppTs;
m_ppTs=tmp;
tmp=0;
}
//==============================================================================
class __obj{};
class CEvent
{
public:
typedef struct
{
__obj* pThis;
void(__obj::* pFunc)();
}CALLBACK;
ArrayedList<CALLBACK>* m_pCallBacks;
void Add(__obj*,void(__obj::*)());
void Remove(__obj*,void(__obj::*)());
CEvent();~CEvent();
};
CEvent::CEvent()
{
m_pCallBacks=new ArrayedList<CALLBACK>;
}
CEvent::~CEvent()
{
delete m_pCallBacks;
}
void CEvent::Add(__obj* pThis,void(__obj::* pFunc)())
{
if(m_pCallBacks->VGetCount())
for(int i=1;i<=m_pCallBacks->VGetCount();i++)
if(m_pCallBacks->VGet(i)->pThis==pThis||m_pCallBacks->VGet(i)->pFunc==pFunc) return;
CALLBACK* tmp=new CALLBACK;
tmp->pThis=pThis;
tmp->pFunc=pFunc;
m_pCallBacks->VAdd(tmp);
}
void CEvent::Remove(__obj* pThis,void(__obj::* pFunc)())
{
if(m_pCallBacks->VGetCount())
for(int i=1;i<=m_pCallBacks->VGetCount();i++)
if(m_pCallBacks->VGet(i)->pThis==pThis||m_pCallBacks->VGet(i)->pFunc==pFunc)
m_pCallBacks->VRemove(i);
}
//********************************************************
#define RaiseEvent(event,types,params)if(event->m_pCallBacks->VGetCount())for (int i=1;i<=event->m_pCallBacks->VGetCount();i++)(event->m_pCallBacks->VGet(i)->pThis->*((void(__obj::*)types)event->m_pCallBacks->VGet(i)->pFunc))params;
//--------------------------------------
#define AddCallBack(event,pthis,func)event->Add((__obj*) pthis,(void(__obj::*)())func);
//--------------------------------------
#define RemoveCallBack(event,pthis,func)event->Remove((__obj*) pthis,(void(__obj::*)())func);
//********************************************************
class CBtn
{
public:
CEvent* m_pClick;
CBtn();~CBtn();
void Init();
};
void CBtn::Init()
{
m_pClick=new CEvent;
cout<<btn is initialized!<<endl;
};
CBtn::CBtn()
{
cout<<btn is created!<<endl;
}
CBtn::~CBtn()
{
delete m_pClick;
}
////////////////////////////////////////////////////////////
class CWnd
{
public:
CBtn* m_pBtn;
void OnClick(int,long);
CWnd();~CWnd();void Init();
};
CWnd::CWnd()
{
cout<<wnd is created!<<endl;
};
CWnd::~CWnd()
{
delete m_pBtn;
}
void CWnd::Init()
{
m_pBtn=new CBtn;
m_pBtn->Init();
AddCallBack(m_pBtn->m_pClick,this,&CWnd::OnClick);
cout<<wnd is initialized!<<endl;
}
void CWnd::OnClick(int a,long b)
{
cout<<btn clicked\n this of CWnd=<<this<<\n<<params:<<a<<\n<<b<<endl;
char* i;cin>>i;
}
//////////////////////////////////////////////////////////
void main()
{
CWnd* pWnd=new CWnd;
pWnd->Init();
cout<<please enter an 1 to RAISE CLICK EVENT !;
int a;
cin>>a;
if(a==1)
RaiseEvent(pWnd->m_pBtn->m_pClick,(int,long),(111,222));
delete pWnd;
}
 |
|