每一个窗口应用都有一个消息队列,线程经过消息循环机制不断地从该队列中取出消息进行处理。app
1、标准窗口消息的处理函数
对于标准窗口消息而言,其处理仅限于某个窗口。首先,由窗口类自己处理,若未处理,则传递给基类处理,对全部的祖先类都不能处理的,则由一个MFC提供的一个全局的默认的处理函数进行处理。spa
经常使用窗口消息:线程
WM_CREATE消息:当调用CreateWindowEx或CreateWindow请求建立窗口时,就会向被建立的窗口发送该消息。只有在WM_CREATE消息处理以后,CreateWindowEx或CreateWindow调用才会返回。重载CWnd::OnCreate时,若是返回0,这表示继续建立窗口;若是返回-1,则将终止窗口的建立。code
WM_DESTROY消息:当窗口被销毁时,就会发送该消息。该消息首先被传递给被销毁的窗体,而后传递给他全部的子窗体。blog
WM_NCDESTROY消息:该消息用于通知窗口,无客户区能够被销毁DestroyWindow函数将在发送WM_DEATROY消息以后紧接着发送该消息,该消息是消息生存期内的最后一个消息。队列
WM_CLOSE消息:当请求关闭一个窗口时,向该窗口发送WM_CLOSE消息。不要在OnClose中进行任何自定义资源的清理操做!事件
2、命令消息的处理资源
命令消息来自菜单、组合键或按钮的单击事件。跟标准窗口消息不一样,它们没有默认的处理程序。所以,为这些类别的消息命名处理程序时只受到约定的限制。rem
(1)使用命令处理链处理同一命令
CMsgStudyApp.h //{{AFX_MSG(CMsgStudyApp) //NOTE - the ClassWizard will add and remove member functions here. //DO NOT EDIT what you see in these blocks of generated code ! afx_msg BOOL OnButton1(UINT nID); afx_msg BOOL OnHelp(UINT nID); //}}AFX_MSG DECLARE_MESSAGE_MAP() CMsgStudyApp.cpp BEGIN_MESSAGE_MAP(CMsgStudyApp, CWinApp) //{{AFX_MSG_MAP(CMsgStudyApp) // NOTE - the ClassWizard will add and remove mapping macros here. //DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG //ON_COMMAND(ID_HELP, CWinApp::OnHelp) ON_COMMAND_EX(ID_HELP,OnHelp) //这个能够沿着处理链处理 ON_COMMAND_EX(IDC_BUTTON1,OnButton1) //这个为何不行 END_MESSAGE_MAP() BOOL CMsgStudyApp::OnButton1(UINT nID) { AfxMessageBox("This is CMsgStudyApp"); //返回FALSE,容许沿着处理链继续处理 return FALSE; } BOOL CMsgStudyApp::OnHelp(UINT nID) { AfxMessageBox("This is CMsgStudyApp"); //返回FALSE,容许沿着处理链继续处理 return FALSE; } CMsgStudyDlg.h // Generated message map functions //{{AFX_MSG(CMsgStudyDlg) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg BOOL OnButton1(UINT nID); afx_msg BOOL OnHelp(UINT nID); //}}AFX_MSG DECLARE_MESSAGE_MAP() CMsgStudyDlg.cpp BEGIN_MESSAGE_MAP(CMsgStudyDlg, CDialog) //{{AFX_MSG_MAP(CMsgStudyDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_COMMAND_EX(IDC_BUTTON1,OnButton1) ON_COMMAND_EX(ID_HELP,OnHelp) END_MESSAGE_MAP() BOOL CMsgStudyDlg::OnButton1(UINT nID) { AfxMessageBox("This is CMsgStudyDlg"); //返回FALSE,容许沿着处理链继续处理 return FALSE; } BOOL CMsgStudyDlg::OnHelp(UINT nID) { AfxMessageBox("This is CMsgStudyDlg"); //返回FALSE,容许沿着处理链继续处理 return FALSE; }
(2)给一组命令提供相同的处理
.h afx_msg void OnButton(UINT nID); .cpp ON_COMMAND_RANGE(IDC_BUTTON1,IDC_BUTTON4,OnButton) void CMsgStudyDlg::OnButton(UINT nID) { switch(nID) { case IDC_BUTTON1: AfxMessageBox("This is BUTTON1"); break; case IDC_BUTTON2: AfxMessageBox("This is BUTTON2"); break; case IDC_BUTTON3: AfxMessageBox("This is BUTTON3"); break; case IDC_BUTTON4: AfxMessageBox("This is BUTTON4"); break; default: break; } }
为同一个命令添加多个消息映射项能编译经过(程序自己没有问题),但只有第一个匹配的消息映射项才会起做用。由于在MFC默认状况下顺次搜索消息映射表,只要在消息映射表中找到一个匹配项,就返回。
3、反射消息的处理
父窗体在处理控件窗口的通知消息,如WM_CTLCOLOR、WM_COMMAND和WM_NOTIFY时,会首先把该消息转化为反射消息,并转交给控件子窗体优先处理该消息。只有在控件子窗体不处理该消息的状况下,父窗体才有机会处理。