最近在编写MFC时,遇到一个情况是,当我要向一个自己定义的Dialog发送消息时只有CDialog对象的指针,而没有我自己定义的CMyDialog(派生自CDialog类)的对象指针。而我要发送的消息却是在CMyDialog中自定义的消息。这时我产生了疑问,通过父类对象的指针发送在子类中定义的自定义消息,能否成功?
进过实践,答案是可以的。具体问题可以用下面代码简要说明。
#define UM_SHOW WM_USER+100
class CMyDialog : public CDialog
{
DECLARE_DYNAMIC(CLogonDialog)
public:
CLogonDialog(CWnd* pParent = NULL); // 标准构造函数
virtual ~CLogonDialog();
// 对话框数据
enum { IDD = IDD_UserLogon };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
afx_msg LRESULT OnShow(WPARAM wParam, LPARAM lParam);
};
在另一个类中MyUser类中出现这样的一行调用:
CDialog* m_pMyDialog;
…… //实现将m_pMyDialog 指向 CMyDialog的对象 。
m_pMyDialog ->PostMessage(UM_SHOW,0,0); //发送子类可以处理的消息
问题是MFC如何知道能够调用子类的消息处理函数?
这里让我想到了MFC的消息处理机制。在该消息处理机制中,每一个类有一个消息和消息处理函数对应的表。然后再通过宏将这些表串起来,这样只需要查表就可以知道这个消息该给谁处理。
在对这张表访问时,需要调用一个函数才能返回这样表的地址,这个函数就是:
virtual AFX_MSGMAP* GetMessageMap() const;
这个函数可以在《深入浅出MFC》的P134找到。
现在注意一个特别关键的地方这个函数是virtual关键字修饰,这样刚才的问题就很好解释了。这是个虚函数,自然通过父类对象的指针发送的消息
m_pMyDialog ->PostMessage(UM_SHOW,0,0); //发送子类可以处理的消息
MFC中会调用到子类的对应处理函数。