Click here to Skip to main content
Click here to Skip to main content

Tagged as

Go to top

Implement Delphi TMethod in C++

, 5 Dec 2010
Rate this:
Please Sign up or sign in to vote.
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();
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

No Biography provided

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web04 | 2.8.140926.1 | Last Updated 5 Dec 2010
Article Copyright 2010 by Member 2398479
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid