Implement Delphi TMethod in C++






4.50/5 (2 votes)
How to dispatch event messages in C++ like a Delphi TMethod
/* created: 2010/12/04 created: 4:12:2010 20:39 filename: EventHandler.h author: [email deleted] purpose: */ #include <hash_map> #ifndef __IMsgHandler_h__ #define __IMsgHandler_h__ struct IEventHandler { virtual ~IEventHandler(void) {} virtual bool HandleEvent(void* pEvent) = 0; }; template<typename ThisType, typename EventData> class TMethod : public IEventHandler { public: typedef bool (ThisType::*TMemFun)(EventData* pEvent); TMethod(ThisType* pThis, TMemFun pFun) :m_pThis(pThis) ,m_pFun(pFun) { } virtual bool HandleEvent(void* pEvent) { return HandleEventMsg(static_cast<EventData*>(pEvent)); } virtual bool HandleEventMsg(EventData* pEvent) { return (m_pThis->*m_pFun)(pEvent); } private: ThisType* m_pThis; TMemFun m_pFun; }; template<typename ThisType, typename EventData> IEventHandler* NewEventHandler(ThisType* pThis, bool (ThisType::*pFun)(EventData*)) { return new TMethod<ThisType, EventData>(pThis, pFun); } //EventHandlerMgr struct IEventHandler; typedef IEventHandler* PEventHandler; typedef stdext::hash_multimap<unsigned int, IEventHandler*> EVENT_HANDLER_MAP; class TEventHandlerMgr { EVENT_HANDLER_MAP m_MsgHandlerMap; public: TEventHandlerMgr(void) {} ~TEventHandlerMgr(void) {} bool Listen(unsigned int nEvnetId, PEventHandler pMsgHandler) { m_MsgHandlerMap.insert(std::make_pair(nEvnetId, pMsgHandler)); return true; } PEventHandler FindEventHandler(unsigned int nEvnetId) { EVENT_HANDLER_MAP::iterator itr = m_MsgHandlerMap.find(nEvnetId); if (itr==m_MsgHandlerMap.end()) return NULL; return itr->second; } bool RemoveListen(unsigned int nMsgId) { return true; } }; #endif // __IMsgHandler_h__ /* created: 2010/12/04 created: 4:12:2010 20:55 filename: TWidget.h author: [email deleted] purpose: Used for test IEventHandler */ #include "EventHandler.h" #ifndef __TWidget_h__ #define __TWidget_h__ #define EVTID_MOUSE_CLICK 1 struct MouseClickInfo { unsigned int nX; unsigned int nY; }; class TWidget { protected: TEventHandlerMgr m_evtHandlerMgr; public: TWidget(void) {} ~TWidget(void) {} bool Listen(unsigned int nEvnetId, PEventHandler pMsgHandler) { return m_evtHandlerMgr.Listen(nEvnetId, pMsgHandler); } bool RemoveListen(unsigned int nEvnetId) { return m_evtHandlerMgr.RemoveListen(nEvnetId); } void MouseClick() { PEventHandler pEvtHand = m_evtHandlerMgr.FindEventHandler(EVTID_MOUSE_CLICK); if (pEvtHand == NULL) return ; MouseClickInfo aMouseClickInfo; aMouseClickInfo.nX = 50; aMouseClickInfo.nY = 50; pEvtHand->HandleEvent(&aMouseClickInfo); } }; class TDialog : TWidget { TWidget m_btnOk; TWidget m_btnCancel; TWidget m_btnClose; public: TDialog() { m_btnOk.Listen(EVTID_MOUSE_CLICK, NewEventHandler(this, &TDialog::OnButtonOkClick)); m_btnCancel.Listen(EVTID_MOUSE_CLICK,NewEventHandler(this, &TDialog::OnButtonCancelClick)); m_btnClose.Listen(EVTID_MOUSE_CLICK, NewEventHandler(this, &TDialog::OnButtonCancelClick)); } void SimulateClick() { m_btnOk.MouseClick(); } private: bool OnButtonOkClick(MouseClickInfo* pEvent) { pEvent->nX; pEvent->nY; return true; } bool OnButtonCancelClick(MouseClickInfo* pEvent) { pEvent->nX; return true; } }; #endif // __TWidget_h__ int _tmain(int argc, _TCHAR* argv[]) { TDialog dlgMain; dlgMain.SimulateClick();}