这篇技术文章不是讨论经典的MFC中的消息工作机理的,讨论消息工作原理、方式和路径的文章在网上和书本中随处可见。网上众多的讨论都是关于如何响应并进行用户自定义消息映射的;网上还有一些文章介绍如何在自定义类中响应Windows消息,在本文中都简略叙述。但是,网上大部分的文章没用透彻阐述如何在用户自定义类中响应自定义消息这一通用方法。
问题定义如下:用户自定义一个类,这个类不一定要有界面(完全可以是不可视的),要求自定义的类可以响应某个自定义消息。
首先能够响应消息的类必须都从CCmdTarget类中派生,因为只有以这个类中提供了消息的框架和处理机制,而CWnd类也派生与此类。CWinApp类、CDocument类、CDocTemplate类等都是CmdTarget的派生类,即子类;而CFrameWnd类、CView类、CDialog类等都是从CWnd中派生的,其实也是CCmdTarget的子孙,所以都能够响应消息,但是响应消息的种类不太相同。那么,如果自己定义的类要求响应命令消息(就是WM_COMMAND,也就是一些菜单、工具栏中的消息,包括快捷键,这类消息处理的机制与其他以WM_开头的消息处理机制不同,它具有一条层次明确的消息流动路径),那么自定义的类可以从CCmdTarget中派生。由于CWnd窗体类派生于CCmdTarget父类,那么从CWnd中派生的类也可以理所应当的响应命令消息。这种命令消息无论是往已有的一些诸如CWinApp类中还是自定义的类中添加都是一件非常容易的事情,只需用向导即可,在此不再叙述。
如果用户自定义的类要求响应普通的Windows消息(也就是以WM_开头,除了WM_COMMAND以外的消息,这类消息在WM_USER以下的是系统消息,WM_USER以上的可以由用户自己定义),那就要求自定义的类必须从CWnd中派生。这是由于此类消息的处理机制决定的,这类消息没有命令消息那条繁琐的流动路径,而是消息发出者直接发给对应CWnd的窗体句柄,由CWnd负责消息的响应。所以这类消息必须同一个CWnd类对应,更精确的说必须与一个HWND类型的窗体句柄相对应。这样得出一个重要