每一個窗口應用都有一個消息隊列,線程經過消息循環機制不斷地從該隊列中取出消息進行處理。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時,會首先把該消息轉化爲反射消息,並轉交給控件子窗體優先處理該消息。只有在控件子窗體不處理該消息的狀況下,父窗體纔有機會處理。