消息映射网的建立可以用宏定义出来,以简化派生类的操作:
#include <iostream>
#include <map>
#include <cassert>
#define PRINT( msg ) { std::cout << msg << std::endl; }
#define FUNC( func ) void func() { PRINT( #func##"()" ); }
#define MFUNC( class, func ) void func() { PRINT( #class##"::"###func##"()" ); }
#define VMFUNC( class, func ) virtual MFUNC( class, func )
enum MsgID {
MsgID_1,
MsgID_2,
};
namespace MFCMacro {
class Wnd;
typedef void (Wnd::*MemberFunc)();
typedef std::map< int, MemberFunc > MsgRegistry;
struct MsgMap {
const MsgRegistry& thisMsgRegistry;
const MsgMap* baseMsgMap;
};
/* MACRO BEGIN *///
#define MSG_BEGIN( theClass, baseClass ) /
protected: /
virtual const MsgMap& GetMsgMap() const { /
static MsgMap msgMap = { /
GetInitilizedMsgRegistry##theClass(), /
&baseClass::GetMsgMap() /
}; /
return msgMap; /
} /
private: /
MsgRegistry& GetInitilizedMsgRegistry##theClass() const { /
static MsgRegistry thisMsgRegistry;
#define MSG_ENTRY( id, func ) /
thisMsgRegistry.insert( std::make_pair( id, (MemberFunc)func ) );
#define MSG_END() /
return thisMsgRegistry; /
}
/* MACRO END *
class Wnd {
...
};
class MyWnd : public Wnd {
MSG_BEGIN( MyWnd, Wnd )
MSG_ENTRY( MsgID_1, &MyWnd::Handle1 )
MSG_END()
private:
MFUNC( MyWnd, Handle1 );
};
}
namespace AutoTest {
void TestMFCMacroMsgMap() {
using namespace MFCMacro;
Wnd* wnd = new MyWnd;
wnd->HandleMsg( MsgID_1 );
wnd->HandleMsg( MsgID_2 );
}
}
void main() {
AutoTest::TestMFCMacroMsgMap();
}
注意
为了表述方便,上面所示的宏直接将消息映射的定义部分放在类声明中。
你也可以像MFC那样将声明和实现分开:
声明
DECLARE_MESSAGE_MAP()
实现
BEGIN_MESSAGE_MAP()
ON_WM_XXX()
ON_COMMAND()
ON_MESSAGE()
...
END_MESSAGE_MAP()
#include <iostream>
#include <map>
#include <cassert>
#define PRINT( msg ) { std::cout << msg << std::endl; }
#define FUNC( func ) void func() { PRINT( #func##"()" ); }
#define MFUNC( class, func ) void func() { PRINT( #class##"::"###func##"()" ); }
#define VMFUNC( class, func ) virtual MFUNC( class, func )
enum MsgID {
MsgID_1,
MsgID_2,
};
namespace MFCMacro {
class Wnd;
typedef void (Wnd::*MemberFunc)();
typedef std::map< int, MemberFunc > MsgRegistry;
struct MsgMap {
const MsgRegistry& thisMsgRegistry;
const MsgMap* baseMsgMap;
};
/* MACRO BEGIN *///
#define MSG_BEGIN( theClass, baseClass ) /
protected: /
virtual const MsgMap& GetMsgMap() const { /
static MsgMap msgMap = { /
GetInitilizedMsgRegistry##theClass(), /
&baseClass::GetMsgMap() /
}; /
return msgMap; /
} /
private: /
MsgRegistry& GetInitilizedMsgRegistry##theClass() const { /
static MsgRegistry thisMsgRegistry;
#define MSG_ENTRY( id, func ) /
thisMsgRegistry.insert( std::make_pair( id, (MemberFunc)func ) );
#define MSG_END() /
return thisMsgRegistry; /
}
/* MACRO END *
class Wnd {
...
};
class MyWnd : public Wnd {
MSG_BEGIN( MyWnd, Wnd )
MSG_ENTRY( MsgID_1, &MyWnd::Handle1 )
MSG_END()
private:
MFUNC( MyWnd, Handle1 );
};
}
namespace AutoTest {
void TestMFCMacroMsgMap() {
using namespace MFCMacro;
Wnd* wnd = new MyWnd;
wnd->HandleMsg( MsgID_1 );
wnd->HandleMsg( MsgID_2 );
}
}
void main() {
AutoTest::TestMFCMacroMsgMap();
}
注意
为了表述方便,上面所示的宏直接将消息映射的定义部分放在类声明中。
你也可以像MFC那样将声明和实现分开:
声明
DECLARE_MESSAGE_MAP()
实现
BEGIN_MESSAGE_MAP()
ON_WM_XXX()
ON_COMMAND()
ON_MESSAGE()
...
END_MESSAGE_MAP()