消息系统对于一个
win32程序来说十分重要,它是一个程序运行的动力源泉。一个消息,是
系统定义的一个32位的值,它唯一地定义了一个事件,向Windows发出一个通知,告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使
Windows发送一个消息给应用程序。消息可以由系统或者应用程序产生。系统在发生输入事件时产生消息。举个例子, 当用户敲键, 移动鼠标或者单击控件。系统也产生消息以响应由应用程序带来的变化, 比如应用程序改变系统字体改变
窗体大小。应用程序可以产生消息使窗体执行任务,或者与其他应用程序中的窗口通讯。
映射机制
MFC使用一种消息映射机制来处理消息,在应用程序框架中的表现就是一个消息与消息处理函数一一对应的消息映射表,以及消息处理函数的声明和实现等代码。当窗口接收到消息时,会到消息映射表中查找该消息对应的消息处理函数,然后由消息处理函数进行相应的处理。SDK编程时需要在窗口过程中一一判断消息值进行相应的处理,相比之下MFC的消息映射机制要方便好用的多。
消息分类
Windows消息分为系统消息和用户自定义消息。Windows系统消息有三种:
1.标准Windows消息。除WM_COMMAND外以WM_开头的消息是标准消息。例如,WM_CREATE、WM_CLOSE。
2.命令消息。消息名为WM_COMMAND,消息中附带了标识符ID来区分是来自哪个菜单、工具栏按钮或加速键的消息。
3.通知消息。通知消息一般由列表框等子窗口发送给父窗口,消息名也是WM_COMMAND,其中附带了控件通知码来区分控件。
CWnd的派生类都可以接收到标准Windows消息、通知消息和命令消息。命令消息还可以由文档类等接收。
用户自定义消息实际上就是用户定义一个宏作为消息,此宏的值应该大于等于WM_USER,然后此宏就可以跟系统消息一样使用,窗口类中可以定义它的处理函数。
映射表
除了一些没有基类的类或CObject的直接派生类外,其他的类都可以自动生成消息映射表。消息映射表的形式如下面的例子:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
ON_WM_CREATE()
ON_COMMAND(ID_VIEW_CUSTOMIZE, &CMainFrame::OnViewCustomize)
ON_REGISTERED_MESSAGE(AFX_WM_CREATETOOLBAR, &CMainFrame::OnToolbarCreateNew)
ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnApplicationLook)
ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnUpdateApplicationLook)
ON_WM_SETTINGCHANGE()
END_MESSAGE_MAP()
在BEGIN_MESSAG_MAP和END_MESSAGE_MAP之间的内容成为消息映射入口项。消息映射除了在实现文件中添加消息映射表外,在类的定义文件中还会添加一个宏调用:
DECLARE_MESSAGE_MAP()
一般这个宏调用写在类定义的结尾处。
处理函数
如何添加消息处理函数呢?不管是自动还是手动添加都有三个步骤,以单文档应用程序的框架类CMainFrame的WM_CREATE消息为例说明:
1.在类定义中加入消息处理函数的函数声明,注意要以afx_msg打头。例如MainFrm.h中WM_CREATE的消息处理函数的函数声明:afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);。
2.在类的消息映射表中添加该消息的消息映射入口项。例如WM_CREATE的消息映射入口项:ON_WM_CREATE()。
3.在类实现中添加消息处理函数的函数实现。例如MainFrm.cpp中WM_CREATE的消息处理函数的实现:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
......
}
通过以上三个步骤以后,WM_CREATE等消息就可以在窗口类中被消息处理函数处理了。