《深入浅出MFC》 中相关疑问?(消息传递)

wang603603 2012-12-27 04:11:51
在MFC 中的消息传递‘一般’是从子类流向父类的。
其中CWinThread类并不在‘消息传递网’ 中。
模拟代码主要如下:

#include <iostream>
#include<Windows.h>
#include <string>

using namespace std;


#define RUNTIME_CLASS_NAME(class_name) \
(#class_name )

enum ID
{
CObjectid = 0,
CCmdTergetid = 1,
CWinThreadid = 11,CWinAppid = 111,
CWndid = 12,CViewid = 121,CFrameWndid = 122
};

struct AFX_MSGMAP_ENTRY
{
char* pName;
ID id;

};
struct AFX_MSGMAP {

AFX_MSGMAP* pBaseMessageMap;

AFX_MSGMAP_ENTRY* lpEntry;
};

#define ClassName(class_name) #class_name
#define Classid(class_name) class_name##id

#define DECLARE_MESSAGE_MAP() \
static AFX_MSGMAP_ENTRY _messageEntries[];\
static AFX_MSGMAP messageMap;\
virtual AFX_MSGMAP* GetMessageMap() const;


#define BEGIN_MESSAGE_MAP(class_name, base_class_name) \
AFX_MSGMAP* class_name::GetMessageMap() const\
{ return &class_name::messageMap;} \
AFX_MSGMAP class_name::messageMap = \
{ \
&(base_class_name::messageMap), (AFX_MSGMAP_ENTRY*)&(class_name::_messageEntries)\
};\
AFX_MSGMAP_ENTRY class_name::_messageEntries[] = {\
ClassName(class_name), Classid(class_name) \
};

class CObject
{

};

class CCmdTerget : public CObject
{

public:
DECLARE_MESSAGE_MAP()
};

AFX_MSGMAP CCmdTerget::messageMap= {NULL, CCmdTerget::_messageEntries};
AFX_MSGMAP_ENTRY CCmdTerget::_messageEntries[] = {ClassName(CCmdTerget),Classid(CCmdTerget)};
AFX_MSGMAP* CCmdTerget::GetMessageMap()const{ return NULL; }

//-
class CWinThread : public CCmdTerget
{

public:


};

class CWinApp : public CWinThread
{

public:
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CWinApp, CWinThread)

//-
class CWnd : public CCmdTerget
{

public:
DECLARE_MESSAGE_MAP()

};
BEGIN_MESSAGE_MAP(CWnd, CCmdTerget)

//
class CView: public CWnd
{

public:
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CView,CWnd)

//
class CFrameWnd : public CWnd
{

public:
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CFrameWnd, CWnd)
//////////////////////////////////////////////////////////////////////////

void Print(AFX_MSGMAP_ENTRY* pEntry)
{
AFX_MSGMAP_ENTRY ame[] =
{
{"CObject", CObjectid} ,
{"CCmdTerget" ,CCmdTergetid} ,
{"CWinThread" ,CWinThreadid},
{"CWinApp" ,CWinAppid},
{"CWnd" ,CWndid} ,
{"CView" ,CViewid},
{"CFrameWnd",CFrameWndid}
};

for (UINT index = 0; index < sizeof(ame)/sizeof(ame[0]); index++)
{
if (strcmp(pEntry->pName,ame[index].pName ) ==0)
{
cout<<ame[index].pName<<" "<<ame[index].id<<endl;
}
}
return;
}

void MsgPrint(AFX_MSGMAP* pMsg)
{
for (; pMsg != NULL; pMsg = pMsg->pBaseMessageMap)
{
if (pMsg->lpEntry)
{
Print(pMsg->lpEntry);
}
}

return;
}


int main( )
{
CWinApp ca;
AFX_MSGMAP* pCa = ca.GetMessageMap();
MsgPrint(pCa);

return 0;
}



//---------------------------------------
主要的疑问就是,子类是通过 pBaseMessageMap 去访问 父类 中的 messageMap
(即,这段代码 

AFX_MSGMAP class_name::messageMap = \
{ \
&(base_class_name::messageMap), (AFX_MSGMAP_ENTRY*)&(class_name::_messageEntries)\
};\


但是在‘CWinThread’类中 并没有 定义 ‘messageMap’ 这个成员啊?
那么&(CWinThread::messageMap)【&(base_class_name::messageMap】
又是怎么编译通过的?

运行后的结果如下:
...全文
213 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
bigwangdi 2012-12-30
  • 打赏
  • 举报
回复
Binzo 2012-12-29
  • 打赏
  • 举报
回复
引用 3 楼 wang603603 的回复:
该死 我忘记了, “继承”啊!。
dhdahai 2012-12-29
  • 打赏
  • 举报
回复
引用 3 楼 wang603603 的回复:
该死 我忘记了, “继承”啊!。
漫步者、 2012-12-28
  • 打赏
  • 举报
回复
封装起来的东东呢,
wang603603 2012-12-28
  • 打赏
  • 举报
回复
该死 我忘记了, “继承”啊!。
wang603603 2012-12-28
  • 打赏
  • 举报
回复
求 详解。。!
赵4老师 2012-12-27
  • 打赏
  • 举报
回复
VS IDE中,在不明白的符号上点鼠标右键,选转到定义。

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧