#define DECLARE_MESSAGE_MAP() \
private: \
static const AFX_MSGMAP_ENTRY _messageEntries[]; \
protected: \
static AFX_DATA const AFX_MSGMAP messageMap; \
virtual const AFX_MSGMAP* GetMessageMap() const; \#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
const AFX_MSGMAP* theClass::GetMessageMap() const \
{ return &theClass::messageMap; } \
AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = \
{ &baseClass::messageMap, &theClass::_messageEntries[0] }; \
AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \
{ \越看问题越多,这些是MFC源码,这些明明都是私有跟保护成员,居然可以在类体访问,郁闷!还望高人指点一二。
private: \
static const AFX_MSGMAP_ENTRY _messageEntries[]; \
protected: \
static AFX_DATA const AFX_MSGMAP messageMap; \
virtual const AFX_MSGMAP* GetMessageMap() const; \#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
const AFX_MSGMAP* theClass::GetMessageMap() const \
{ return &theClass::messageMap; } \
AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = \
{ &baseClass::messageMap, &theClass::_messageEntries[0] }; \
AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \
{ \越看问题越多,这些是MFC源码,这些明明都是私有跟保护成员,居然可以在类体访问,郁闷!还望高人指点一二。
这是宏,在编译时会被展开替换掉的,
例如:#define BEGIN_MESSAGE_MAP(CMyWnd, CWnd)
会被展开成:
const AFX_MSGMAP* CMyWnd::GetMessageMap() const
{
return &CMyWnd::messageMap;
}
AFX_COMDAT AFX_DATADEF const AFX_MSGMAP CMyWnd::messageMap =
{ &CWnd::messageMap, &CMyWnd::_messageEntries[0] }; MFC的消息机制原理就是建立了一张静态的消息映射表,通过上面的宏展开你应该不难看出。这几个宏的定义就是对每个对象的消息映射表进行赋值,也是_messageEntries[]这个结构数组,并将对象指针加入到映射表之中,呵呵建议你看下侯捷的深入浅出MFC,里面有详细的解释
本来是想说在类体外的 结果却说成了类体内 ,不好意思 让大家笑话啦。但是这个问题还是存在的
#define 宏 明显是在类体外展开的,又如何去访问
&baseClass::messageMap, &theClass::_messageEntries[0]
俺真的没喝酒,就是一个上午都没找到BUG,还顺带发现了这个疑惑,郁闷,侯捷那本书里边,这些成员都是public,只是为了仿真,没考虑太多,可是MFC源码就不一样啦,一般声明都是protected,可是我觉得在类体外是无法访问protected的,我肯定是漏掉了什么,只是自己美看出来,望高手详细讲一下。
谢谢回帖,请详细说一下,关于 DELACRE_MESSAGE_MAP 这个宏肯定是写在类体内啦,但是BEGIN_MESSAGE_MAP却是写在类体外的,一开始我也用红色字体表明啦,message_Map以及_messageEntries[]却是private以及protected,所以比较郁闷。我肯定是漏了什么,请指点一下。
其实还是在同一个类里面的阿。。theClass是你外面传进去的那个类阿。。
其实就在同一个类里面的。。
Class A --.h文件
{
DECLARE_DYNAMIC(A);
}
--.CPP文件
BEGIN_MESSAGE_MAP(A, CDialog)
END_MESSAGE_MAP()都是类A啊,就相当于在同一类A里面阿。。
class A
{
public:
A();
virtual ~A();
private:
static const int v[];
};..........
A.cpp文件int A::v[] = {1,2,3,......4,5,0};这就是那个宏的真正目的,你把int类型换成函数的结构体就会得到一张消息入口表。
typedef void (CXKCmd::*XK_PCMD) (void);
typedef Tbool (CXKCmd::*XK_PTRANSDATA) (CXKTransData*);
typedef Tbool (CXKCmd::*XK_PBV) (void);
typedef Tbool (CXKCmd::*XK_PBU) (Tuint);
typedef Tbool (CXKCmd::*XK_PBUU) (Twparam, Tlparam);
typedef Tbool (CXKCmd::*XK_PBVPB) (void *, Tbool);
typedef Tuint (CXKCmd::*XK_PUVPII) (void *, Tint, Tint);
typedef Tuint (CXKCmd::*XK_PUUII) (Tuint, Tint, Tint);
typedef void (CXKCmd::*XK_PVPIIBB) (Tint, Tint, Tbool, Tbool);
typedef void (CXKCmd::*XK_PVPVP) ( void *, void * );
typedef Tbool (CXKCmd::*XK_PBUVPVP)( void*, void* );
typedef Tbool (CXKCmd::*XK_PBVP)(void *);
typedef Tbool (CXKCmd::*XK_PBVPCP)(void *,char* );enum XKSig
{
XKSig_end = 0, // 消息映射结束
XKSig_cmd,
XKSig_transdata,
XKSig_pbv,
XKSig_pbu,
XKSig_pbuu,
XKSig_uuii,
XKSig_bvpb,
XKSig_uvpii,
XKSig_vpvp,
XKSig_buvpvp,
XKSig_bvp,
XKSig_vpiibb,
XKSig_bvpcp
};
union XK_MSG_FUNCTION
{
XK_PMSG fnPMSG;
XK_PCMD fnPCMD;
XK_PTRANSDATA fnPTRANSDATA;
XK_PBV fnPBV;
XK_PBU fnPBU;
XK_PBUU fnPBUU;
XK_PUUII fnPUUII;
XK_PBVPB fnPBVPB;
XK_PUVPII fnPUVPII;
XK_PVPVP fnPVPVP;
XK_PBUVPVP fnPBUVPVP;
XK_PBVP fnPBVP;
XK_PVPIIBB fnPVPIIBB;
XK_PBVPCP fnPBVPCP;
};#define XK_ON_COMMAND( msgID, memberFxn ) \
{ (Tuint)msgID, (Tuint)0, XKSig_cmd, (XK_PMSG) memberFxn },#define XK_ON_TRANSDATA( msgID, memberFxn ) \
{ (Tuint)msgID, (Tuint)0, XKSig_transdata, (XK_PTRANSDATA)memberFxn },#define XK_ON_PBV( msgID, memberFxn ) \
{ (Tuint)msgID, (Tuint)0, XKSig_pbv, (XK_PMSG)(XK_PBV) memberFxn },#define XK_ON_PBU( msgID, memberFxn ) \
{ (Tuint)msgID, (Tuint)0, XKSig_pbu, (XK_PMSG)(XK_PBU) memberFxn },#define XK_ON_PBUU( msgID, memberFxn ) \
{ (Tuint)msgID, (Tuint)0, XKSig_pbuu, (XK_PMSG)(XK_PBUU) memberFxn },#define XK_ON_UUII( msgID, memberFxn ) \
{ (Tuint)msgID, (Tuint)0, XKSig_uuii, (XK_PMSG)(XK_PUUII) memberFxn },#define XK_ON_BVPB( msgID, memberFxn )\
{ (Tuint)msgID, (Tuint)0, XKSig_bvpb, (XK_PMSG)(XK_PBVPB) memberFxn },#define XK_ON_UVPII( msgID, memberFxn )\
{ (Tuint)msgID, (Tuint)0, XKSig_uvpii, (XK_PMSG)(XK_PUVPII) memberFxn },#define XK_ON_VPVP( msgID, memberFxn )\
{ (Tuint)msgID, (Tuint)0, XKSig_vpvp, (XK_PMSG)(XK_PVPVP) memberFxn },#define XK_ON_BUVPVP( msgID, memberFxn )\
{ (Tuint)msgID, (Tuint)0, XKSig_buvpvp, (XK_PMSG)(XK_PBUVPVP) memberFxn },#define XK_ON_BVP( msgID, memberFxn )\
{ (Tuint)msgID, (Tuint)0, XKSig_bvp, (XK_PMSG)(XK_PBVP) memberFxn },#define XK_ON_VPIIBB( msgID, memberFxn )\
{ (Tuint)msgID, (Tuint)0, XKSig_vpiibb, (XK_PMSG)(XK_PVPIIBB) memberFxn },#define XK_ON_BVPCP( msgID, memberFxn )\
{ (Tuint)msgID, (Tuint)0, XKSig_bvpcp, (XK_PMSG)(XK_PBVPCP) memberFxn },struct XK_MSGMAP_ENTRY
{
Tuint nMessage; // 消息ID
Tuint nID; // 对象ID
Tuint nSig; // 消息响应函数类型
XK_PMSG pfn; // 消息处理函数
};struct XK_MSGMAP
{
XK_MSGMAP *pBaseMessageMap;
XK_MSGMAP_ENTRY *lpEntries;
};#define XKDEC_MESSAGE_MAP() \
static XK_MSGMAP_ENTRY msgEntries[]; \
static XK_MSGMAP msgMap; \
virtual XK_MSGMAP *GetMessageMap() const;#define XKBEG_MESSAGE_MAP( theClass, baseClass ) \
XK_MSGMAP *theClass::GetMessageMap() const \
{ return &theClass::msgMap; } \
XK_MSGMAP theClass::msgMap = \
{ &(baseClass::msgMap), \
( XK_MSGMAP_ENTRY * ) &( theClass::msgEntries ) }; \
XK_MSGMAP_ENTRY theClass::msgEntries[] = \
{ #define XKEND_MESSAGE_MAP() \
{ 0, 0, XKSig_end, (XK_PMSG) 0 } \
};/* 消息宏定义 */
#define XK_ON_MESSAGE(n,f) XK_ON_PBUU(n,f)#define XK_ON_NEW_DRAWFRAME(f) XK_ON_BVP(XK_WM_NEW_DRAWFRAME, f) // 新建框架
#define XK_ON_ADD_DRAWFRAME(f) XK_ON_BVP(XK_WM_ADD_DRAWFRAME, f) // 增加框架
#define XK_ON_DEL_DRAWFRAME(f) XK_ON_BVP(XK_WM_DEL_DRAWFRAME, f) // 删除框架#define XK_ON_DRAW(f) XK_ON_BVPB(XK_WM_PAINT, f) // 绘制图元消息
#define XK_ON_ADDITEM(f) XK_ON_BVP(XK_WM_ADD_ITEM, f) // 增加图元消息
#define XK_ON_DELITEM(f) XK_ON_PBU(XK_WM_DEL_ITEM, f) // 删除图元消息
#define XK_ON_DELSELITEMS(f) XK_ON_PBV(XK_WM_DEL_SEL_ITEMS, f) // 删除所有选中的图元消息
#define XK_NET_ADD_CLIENT(f) XK_ON_VPVP(XK_CMD_NETUNIT_ADD_CLIENT, f) // 增加网元客户端消息
#define XK_NET_REMOVE_SOCKET(f) XK_ON_VPVP(XK_CMD_NETUNIT_REMOVE_SOCKET, f) // 网元释放本地套接字消息
#define XK_ON_OPEN_NETNODE_WND(f) XK_ON_PBU(XK_WM_OPEN_NET_NODE, f) // 打开网元结点信息窗口
#define XK_ON_CONTROL_SERVICE(f) XK_ON_PBUU(XK_WM_CONTROL_SERVICE, f) // 打开服务控制窗口
#define XK_ON_DRAW_DRAGLINE(f) XK_ON_VPIIBB(XK_WM_DRAW_DRAGLINE, f) // 画拖动连线#define XK_ON_ADD_PROPERTY(f) XK_ON_BVP(XK_WM_ADD_PROPERTY, f) // 增加属性
#define XK_ON_DEL_PROPERTY(f) XK_ON_BVP(XK_WM_DEL_PROPERTY, f) // 删除属性
#define XK_ON_UPDATE_PROPERTY(f) XK_ON_BVP(XK_WM_UPDATE_PROPERTY, f) // 更新属性
class CXKCmd : public CXKObject
{
XKDEC_MESSAGE_MAP()
public:
CXKCmd();
virtual ~CXKCmd();
public:
/* 发送命令消息 */
virtual Tuint SendMsg(Tuint nMsgID, Tlparam lParam = 0, Twparam wParam = 0);
/* 默认命令消息处理函数 */
virtual Tuint DefMsgProc(Tuint nMsgID, Tlparam lParam, Twparam wParam);
protected:
XK_MSGMAP_ENTRY *SearchMsgEntry( Tuint nID );
};
这下应该明白了吧。
using namespace std;
class base
{
private:
static int i;
static int *p;
};
int base::i=10;
int *base::p=&base::i;
class super:public base
{
private:
static int *q;
};int *super::q=&base::i;差不多我已经明白这个问题啦,这段代码在VC6里边可以,到了VC2008就不行啦,说不能访问base的私有成员,VC6果然对标准支持的不好,不过俺多说一句,这个标准太变态啦。谢谢大家的参与,分不多。
呵呵 问题已经大致明白啦,至于消息映射机制 ,相信侯捷那本书已经说的相当明白啦,我也有看过MFC源码,这个还是很明白的,疑惑的是类定义外部怎么能访问私有成员,经过刚才的试验已经发现只有对静态变量初始化的时候才可以,如果掺和上派生类的话,那就更麻烦啦,总之C++访问控制机制太变态啦。