mfc消息處理和消息映射的概念
關鍵詞: MFC
1、消息處理和消息映射的概念
2、消息種類
3、常用消息
4、消息處理函數
5、消息映射
所有windows應用程序都是消息驅動的,消息處理是所有windows應用程序的核心部分。當用戶單擊鼠標或改變窗口大小時,都將給適當的窗口發送消息。每個消息都對應於某個特定的事件。
一、消息處理和消息映射的概念
1、消息
消息主要指由用戶操作而嚮應用程序發出的信息,也包括操作系統內部產生的消息。例如,單擊鼠標左按鈕,windows將產WM_LBUTTONDOWN消息,而釋放鼠標左按鈕將產生WM_LBUTTONUP消息,按下鍵盤上的字母鍵,將產生WM_CHAR消息。
2、windows消息組成結構
windows消息由消息號和參數組成:
消息號
windows操作系統通過32整數標識一條windows消息,稱爲消息號。windows消息號具有三個特點:
(1)唯一性
唯一性指對於windows操作系統中的每一條消息都有一個且只有一個消息號與它相對應。由於windows操作系統通過消息激活相應的過程,因此消息的標識必須是唯一的。
(2) 直觀性
消息號在形式上表現爲消息名,消息名往住直觀地說明了消息的產生方式和類型,例如消息名WM_LBUTTONDOWN直觀地表示了單擊產生的消息。
(3)可自定義性
windows系統定義了一些消息號和消息名,程序員可以運用這些消息,也可以使用自已定義的窗口的消息。形式如下:
#define 消息名 消息號
注意,爲了不與現有的windows系統消息相沖突,在消息號的定義中通常採用如下:
WM_USER+n WM_USER是windows操作系統定義的用戶消息起始值,程序員必須從該起始值後選取消息號,例如自定義消息名爲“MESSAGE_1”和“MESSAGE_2”,可採用如下形式:
#define MESSAGE_1 WM_USER+1
#DEFINE MESSAGE_2 WM_USER+2
參 數
windows的消息具有以下兩個參數:
(1)字參數(wParam)
(2)長參數(lParam)
字參數和長參數都是32位整數,用於提供消息的附帶消息,是消息傳遞過程中參數的載體。附加信息的消息號取決於消息號。
3、消息處理
在MFC中,每個專門的處理函數旱單獨處理每個消息。消息處理函數通常是某一類的成員函數,編寫消息處理函數是編寫框架應用程序的主要任務。
可以使用ClassWizard創建消息處事函數,然後從Classwizard直接跳到源文件消息處理函數,編寫處理代碼。
4、消息映射
可以接收消息和命令的所有框架類都有自已的消息映射。框架利用消息映射把消息、命令與它們的處理函數鏈接起來。從CCmdTarget類派生的任何類都可以有消息映射。雖然叫作“消息映射”,但消息映射既可以處理消息,也可以處理命令。
二、消息種類
消息主要有三種類型,即windows消息,命令消息和控件通知。
按消息的產生可以分爲四類:
*(1)外界輸入事件產生的消息
*(2)windows系統嚮應用程序發出的消息
*(3)應用程序之間發送的消息
*(4)其他
根據產生消息的對象,可以進一步將消息分爲以下幾類:
*(1)窗口管理消息
包括激活基本窗口操作的消息,如關閉、最大化等。
*(2)初始化消息
應用程序、窗口、控件等對象初始化的消息。
*(3)輸入消息
包括鍵盤、鼠標、繪圖儀等處部輸入工具的輸入消息。
*(4)系統消息
windows系統內部消息。
*(5)剪貼板消息
操作剪貼板時產生的消息。
*(6)系統信息消息
用於系統信息發送和處理的消息。
*(7)控件處理消息
操作控件時產生的消息。
*(8)控件通知消息
系統採用空件通知消息向控件發送消息。
*(9)滾動條消息
操作滾動條時產生的消息
*(10)非用戶區消息
非用戶區產生的消息
*(11)MDI消息
用於多文檔操作的消息
*(12)DDE消息
用於動態數據交換的消息。
*(13)應用程序自定義的消息等等。
1、windows消息
除WM_COMMAND外,所有以WM_開頭的消息都是windows消息。windows消息由窗口和視圖處理。這類消息通常含有用於確定如何對消息進行處理的一些參數。
2、控件消息
控件通知包含從控件和其他子窗口傳遞給父窗口的WM_COMMAND通知消息。例如,當用戶改變編輯控件中的文本時,編輯控件將發送給父窗(例如對話框)一條含有EN_EXCHANGE控件通知碼的WM_COMMAND消息。窗口的消息處理函數將以適當的方式對通知消息作出響應,如獲取編輯框中的文本等。
像其他標準windows消息一樣,控件通知消息由窗口和視圖進行處理。但是如果用戶單擊控件按鈕時發出的BN_CLICKED控件通知消息將作爲命令消息來處理。
3、命令消息
命令消息包括來自用戶界面對象的WM_COMMAND通知消息。菜單項、工具欄按鈕和加速鍵都是可以產生命令的用戶界面對象。每個這樣的對象都有一個ID。通過給對象和命令分配給同一個ID可以把用戶界面對象和命令聯繫起來。命令是被作爲特殊的消息來處理的。
通常,命令ID是以其表示的用戶界面對象的功能來命名的。例如,Edit菜單中的Copy命令就可以用ID_EDIT_COPY來表示。MFC類庫預定義了某些命令ID(如ID_EDIT_PASTE和ID_FILE_OPEN等等)。其他命令ID則要編程人員自已定義,所有預定義命令ID的列表,參見AFXRES.H文件。
命令消息的處理和其他消息的處理不同。命令消息可以被更廣泛的對象(如文檔、文檔模板、應用程序對象、窗口和視圖等)處理。windows把命令發送給多個候選對象,稱爲命令目標。通常其中一個對象有針對該命令的處理函數。處理函數處理命令的方法和處理windows消息的方法是一樣的。但調用機制不一樣。
三、常用消息
windows中一些常用的消息:
1、WM_LBUTTONDOWN
產生:單擊。
參數:
wParam:包含一個整數值,以標識鼠標鍵的按下狀態。
鼠標的按下標識及說明
數值 說明
MK_LBUTTON 標識按下鼠標左鍵
MK_MBUTTON 標識按下鼠標中鍵
MK_RBUTTON 標識按下鼠標右鍵
lParam:長參數lParam的低字位包含當前座標的x座標,在高字節包含當前座標的Y座標。
相似的消息有:
WM_LBUTTONUP
WM_RBUTTONDOWN
WM_RBUTTONUP
WM_LBUTTONDBLCLK
WM_RBUTTONDBLCLK
2、WM_KEYDOWN
產生:按下一個非系統鍵的時候產生該事件,系統鍵是指實現系統操作的組合鍵,例如,Alt與某個功能鍵的組合以實現菜單操作等。
參數:
wParam:按下鍵的虛擬鍵盤碼,虛擬鍵碼用來標識按下或者釋放的是哪個鍵,例如功能鍵F1的虛擬鍵碼在windows.h文件中定義爲VK_F1。
lParam:長參數中記錄了按鍵的重複次數,掃描碼、轉移代碼、先前鍵的狀態等信息。
相似的消息有:
WM_KEYUP:放開按下的非系統鍵時產生的事件。
3、WM_CHAR
產生:按一個非系統鍵時產生。
參數:
wParam:所按下的鍵的ASCII碼。
lParam:長參數中記錄了按鍵的重複次數,掃描碼、轉移代碼、先前鍵的狀態等信息。
4、WM_CREATE
產生:由CreateWindow函數發出,創建窗口。
參數:
wParam:沒用。
lParam:包含一個指向CREATESTRUCT數據結構的指針,該結構是傳遞給CreateWindow函數的參數的副本。
5、WM_CLOSE
產生:當關閉當前窗口時產生。
參數:
wParam:未用。
lParam:未用。
6、WM_DESTROY
產生:當窗口要銷燬時由DestroyWindow函數發出。
參數:
wParam:沒用到。
lParam:沒用到。
7、WM_QUIT
產生:退出應用程序時由PostQuitMessage函數發出。
參數:
wParam:含有退出代碼,退出代碼標識應用程序退出運行時的有關信息。
lParam:未用。
8、WM_COMMAND
產生:用戶與窗口或控件交互時,控件向其窗口發送WM_COMMAND消息。該消息的wParam參數的低字節中包含子窗口(控件)的標識值ID,高字節中包含子窗口向父窗口發出的通知代碼,lParam參數中包含控件子窗口句柄。
9、WM_PAINT
用戶改變窗口大小或拖動窗口,系統嚮應用程序發送WM_PAINT消息,WM_PAINT消息調用BeginPaint函數。
四、消息處理函數
1、windows消息和控件通知的處理函數
windows消息和控件通知都是由派生於CWnd的窗口類對象處理的。它們包括CFrameWnd、CMDIFrameWnd、CMDIChildWnd、CView、CDialog以及從這些派生的用戶自定義的類。這樣的類對象封裝了windows窗口句柄HWND。
windows消息和控件通知都有默認的處理函數,這些函數在CWnd類中進行了預定義,MFC類庫以消息名爲基礎形成這些處理函數的名稱,這些處理函數的名稱都以前綴"On"開始。有的處理函數不帶參數,有的則有幾個參數;有的還有除void以外的返回值類型。CWnd中消息處理函數的說明都有afx_msg前綴。關鍵字afx_msg用於把處理函數和其他CWnd成員函數區分開來。例如,消息WM_PAINT的處理函數在CWnd中被聲明成:
afx_msg void OnPaint();
windows消息常見的有鼠標消息(如WM_LBUTTONDOWN)消息)、鍵盤字符消息(WM_CHAR消息)、鍵盤按鍵消息(WM_KEYDOWN)、窗口重畫消息WM_PAINT,水平和垂直條滾動消息WM_HSCROLL和WM_VSCROLL)以及系統時鐘消息WM_TIMER等。
2、命令消息的處理函數
由於用戶界面的對象是用戶自已定義的,每個應用程序的用戶界面對象千差萬別,所以對用戶界面對象的命令消息沒有默認的處理函數。如果某條命令直接影響某個對象,則應該讓這個對象來處理這條命令。例如FILE菜單上的Open命令當然與應用程序有關:應用程序打開一個特定的文檔來響應該命令。報以,Open命令的處理函數是應用程序類的一個成員函數。
把命令消息映射成處理函數時,ClassWizard以命令ID來命名處理函數,可以接受、修改、或替換推薦使用的名字。例如,Edit菜單項的Cut命令,對應ID就是ID_EDIT_CUT,處理函數被命名成:
afx_msg void OnEditCut();
此外,對於控件按鈕的BN_CLICKED通知消息,其處理函數可以被命名爲:
afx_msg void OnClickedUseAsDefault();
命令消息的處理函數沒有參數值,也不返回值。
五、消息映射
用MFC Application Wizard 創建應用程序框架時,AppWizard爲創建的每個命令目標類(包括派生的應用程序對象、文檔、視圖、和邊框窗口等)編寫一個消息映射。每個命令目標類的消息映射存在相應的.cpp文件中。可以在AppWizard創建的基本消息映射的基礎上,使用ClassWizard爲每個類將處理的消息和命令添加一些條目。例如,對於應用程序類,MFC AppWizard創建的基本消息映射爲:
BEGIN_MESSAGE_MAP(CTextEditApp,CWinApp)
//{{AFX_MSG_MAP(CTextEditApp)
ON_COMMAND(ID_APP_ABOUT,OnAppAbout)
//注:ClassWizard將在此處添加和刪除消息映射宏
//不要編輯這些生成的代碼塊
//}}AFX_MSG_MAP
//基於標準文件的文檔命令(新建和打開)
ON_COMMAND(ID_FILE_NEW,CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN,CWinApp::OnFileOpen)
//標準的打印設置命令
ON_COMMAND(ID_FILE_PRINT_SETUP,CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()
1、WM_LBUTTONDOWN
產生:單擊。
參數:
wParam:包含一個整數值,以標識鼠標鍵的按下狀態。
鼠標的按下標識及說明
數值 說明
MK_LBUTTON 標識按下鼠標左鍵
MK_MBUTTON 標識按下鼠標中鍵
MK_RBUTTON 標識按下鼠標右鍵
lParam:長參數lParam的低字位包含當前座標的x座標,在高字節包含當前座標的Y座標。
相似的消息有:
WM_LBUTTONUP
WM_RBUTTONDOWN
WM_RBUTTONUP
WM_LBUTTONDBLCLK
WM_RBUTTONDBLCLK
2、WM_KEYDOWN
產生:按下一個非系統鍵的時候產生該事件,系統鍵是指實現系統操作的組合鍵,例如,Alt與某個功能鍵的組合以實現菜單操作等。
參數:
wParam:按下鍵的虛擬鍵盤碼,虛擬鍵碼用來標識按下或者釋放的是哪個鍵,例如功能鍵F1的虛擬鍵碼在windows.h文件中定義爲VK_F1。
lParam:長參數中記錄了按鍵的重複次數,掃描碼、轉移代碼、先前鍵的狀態等信息。
相似的消息有:
WM_KEYUP:放開按下的非系統鍵時產生的事件。
3、WM_CHAR
產生:按一個非系統鍵時產生。
參數:
wParam:所按下的鍵的ASCII碼。
lParam:長參數中記錄了按鍵的重複次數,掃描碼、轉移代碼、先前鍵的狀態等信息。
4、WM_CREATE
產生:由CreateWindow函數發出,創建窗口。
參數:
wParam:沒用。
lParam:包含一個指向CREATESTRUCT數據結構的指針,該結構是傳遞給CreateWindow函數的參數的副本。
5、WM_CLOSE
產生:當關閉當前窗口時產生。
參數:
wParam:未用。
lParam:未用。
6、WM_DESTROY
產生:當窗口要銷燬時由DestroyWindow函數發出。
參數:
wParam:沒用到。
lParam:沒用到。
7、WM_QUIT
產生:退出應用程序時由PostQuitMessage函數發出。
參數:
wParam:含有退出代碼,退出代碼標識應用程序退出運行時的有關信息。
lParam:未用。
8、WM_COMMAND
產生:用戶與窗口或控件交互時,控件向其窗口發送WM_COMMAND消息。該消息的wParam參數的低字節中包含子窗口(控件)的標識值ID,高字節中包含子窗口向父窗口發出的通知代碼,lParam參數中包含控件子窗口句柄。
9、WM_PAINT
用戶改變窗口大小或拖動窗口,系統嚮應用程序發送WM_PAINT消息,WM_PAINT消息調用BeginPaint函數。