MFC 消息映射 消息传递MESSAGE_MAP 读深入浅出MFC感悟

三种消息 标准的windows消息如WM_PAINT 命令消息(菜单和工具栏)WM_COMMAND 通知消息(对话框函数中)WM_NOTIFY(Windows9x新控件不在发送WM_COMMAND,而是发送WM_NOTIFY,但之前的旧控件如edit listbox combobox仍然发WM_COMMAND)


MFC 消息映射 消息传递MESSAGE_MAP 读深入浅出MFC感悟_第1张图片

AfxWndProc作为消息的起头,然后依次调用AfxCallWndProc,pWnd->WindowProc,  OnWndMsg如果在这里不能够处理就交由DefWindowProc处理。
在OnWndMsg中根据是标准消息,命令消息,通知消息,选择各自的处理路径
OnCommand   OnNotify  //均为虚函数

标准消息传递路径:沿着类的继承层次传递 CObject和CWinThread不属于消息传递网的一份子
只要是CWnd派生类,就可以接收任何消息,CCmdTarget派生类只能收到WM_COMMAND消息

WM_COMMAND消息传输路径:要想拦截OnCommand消息就需要实现拦截消息处的OnCommad虚函数。
WM_COMMAND消息会上溯整个消息表,知道找到为止,如下图所示:
MFC 消息映射 消息传递MESSAGE_MAP 读深入浅出MFC感悟_第2张图片

至于各种命令消息应该由谁来处理,习惯上,

  • File菜单中的New、Open和Exit命令由应用程序对象处理,其中CWinApp为它们提供了OnFileNew、OnFileOpen和OnAppExit命令处理程序。
  • File菜单中的Save和Save As命令通常由文档对象处理,它提供了名为CDocument::OnFileSave和CDocument::OnFileSaveAs的默认命令处理程序。
  • 显示和隐藏工具栏和状态栏的命令由框架窗口使用CFrameWnd成员函数来处理,其他大多数命令则由文档或视图处理。

宏展开:
#define  DECLARE_MESSAGE_MAP() \
protected: \
 static const AFX_MSGMAP* PASCAL GetThisMessageMap(); \
 virtual const  AFX_MSGMAP* GetMessageMap() const; \
 
struct  AFX_MSGMAP
{
 const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();    //基类 AFX_MSGMAP指针
 const  AFX_MSGMAP_ENTRY* lpEntries;
};
struct  AFX_MSGMAP_ENTRY
{
 UINT nMessage;   // windows message
 UINT nCode;      // control code or WM_NOTIFY code
 UINT nID;        // control ID (or 0 for windows messages)
 UINT nLastID;    // used for entries specifying a range of control id's
 UINT_PTR nSig;       // signature type (action) or pointer to message #
 AFX_PMSG pfn;    // routine to call (or special value)
};

#define  BEGIN_MESSAGE_MAP(theClass, baseClass) \
 PTM_WARNING_DISABLE \
 const AFX_MSGMAP* theClass::GetMessageMap() const \
  { return GetThisMessageMap(); } \
 const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap() \
 { \
  typedef theClass ThisClass;   \
  typedef baseClass TheBaseClass;   \
  static const AFX_MSGMAP_ENTRY _messageEntries[] =  \
  {
/*
消息映射机制相比于C++的虚函数:消息映射只有在该处添加一条消息映射的时候(如ON_COMMAND), _messageEntries[]中才增加一个结构。而虚函数会为每个类都添加一个虚函数表(无论是否重新实现该虚函数),因此消息映射会省内存一些。
*/
#define  END_MESSAGE_MAP() \
  {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } \
 }; \
  static const AFX_MSGMAP messageMap = \
  { &TheBaseClass::GetThisMessageMap, &_messageEntries[0] }; \
  return &messageMap; \
 }  \
 PTM_WARNING_RESTORE

 


 

你可能感兴趣的:(MFC)