一、注释宏
这里运用了手动修改AFX_MSG注释宏中的内容。
VC中独特的注释宏可以让代码变灰,它的格式如下
//{{AFX //注意:这里只要是以AFX开头的字符串都可以,比如:AFXDWADWXXADW.
...中间的代码是灰色的
//}}AFX
注释宏的开始标记其中//和{{之间不能有空格 AFX必须大写并且和{{也没有空格
注释宏的结束标记也如此。
二、加入消息函数
举个例子 .h中有如下代码,为了简单起见,别的无关的我都以省略号代替:
class
CMSGDlg : public CDialog
{
public:
.....
protected:
.....
// Generated message map functions
//{{AFX_MSG(CMSGDlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnButton1();
afx_msg void OnButton2();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
点cpp中如下代码:
BEGIN_MESSAGE_MAP(CMSGDlg,CDialog)
//{{AFX_MSG_MAP(CMSGDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
假定我们现在要加入一个WM_USER + 1 这个消息可以按照如下步骤:
假定 #defineSER_MESSAAGE (WM_USER + 1)
在该类中定义一个形如
LRESULT
CMSGDlg::OnSeverMessage(WPARAM msg,LPARAM param)
一个成员函数,当然斜体部分名字可以由你决定
在class中加入上面函数的申明。
加完后h中的文件类容为:
class CMSGDlg :public CDialog
{
public:
.....
protected:
.....
// Generated message map functions
//{{AFX_MSG(CMSGDlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnButton1();
afx_msg void OnButton2();
afx_msg LRESULT OnSeverMessage(WPARAM msg, LPARAM param);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
同样在cpp的注释宏之间加入后的类容为:
BEGIN_MESSAGE_MAP(CMSGDlg, CDialog)
//{{AFX_MSG_MAP(CMSGDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
ON_MESSAGE(SER_MESSAAGE, OnSeverMessage)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
好了以上功能已经完成。
三、内部
下面讲下原因:
消息映射机制很多书上都已经讲的很清楚了,实际上每个类都有自己的静态消息映射表,上面实际上就是在初始化的时候把这个静态数组填入所需要的数据(ID和函数地址等等的元组)从而达到消息映射的效果,并且根据类的继承特性每个消息表中都有一个指针指向其父类的消息表从而达到消息沿着类向上回溯的效果!我们着重讲下这个消息的宏:
该宏的定义是这样的位于AFXMSG_.H中:
#define
ON_MESSAGE(message, memberFxn) \
{ message, 0, 0, 0, AfxSig_lwl, \
(AFX_PMSG)(AFX_PMSGW)(LRESULT
(AFX_MSG_CALLCWnd::*)(WPARAM, LPARAM))&memberFxn
},
我们可以这么使用它,如下:
#defineSER_MESSAAGE (WM_USER + 1)
ON_MESSAGE(SER_MESSAAGE, OnSeverMessage)
其实也可以加在外部,加载内部只是为了好看而已
其实afx_msg 和 AFX_MSG_CALL 这两个本身的定义只是一个标识而已,
AFX_PMSG AFX_PMSGW的转换只是为了赋值需要,调用的时候并不会按照AFX_PMSG形式去调用的,所以这两个我们也不用管他们。
因为如何调用已经在AfxSig_lwl(消息映射体中第4个参数)说明了,具体代码在WINCORE.cpp中 的CWnd::WindowProc中的CWnd::OnWndMsg中被调用。