消息處理(一)

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

相關文章
相關標籤/搜索