1. 程式人生 > >從ON_MESSAGE和ON_NOTIFY理解windows的訊息機制

從ON_MESSAGE和ON_NOTIFY理解windows的訊息機制

ON_COMMAND用來處理WM_COMMAND訊息。老式的windows控制元件傳送WM_COMMAND作為對父視窗的通知訊息。另外,選單,工具欄也向框架視窗傳送

WM_COMMAND訊息。
   ON_MESSAGE主要用來處理使用者自定義訊息。
   對於某些新型的windows控制元件(如ListCtrl等),向父視窗傳送通知訊息時需要包含大量的資訊,WM_COMMAND已不適應這種要求(因為

WM_COMMAND的wparam和lparam都已經填滿了),ON_NOTIFY主要用來處理這些新型的windows控制元件向父視窗的傳送的WM_NOTIFY通知訊息。
--------------------------------------------------------------
ON_COMMAND是選單和工具欄項處理訊息的巨集

ON_MESSAGE是處理自定義訊息的巨集

ON_NOTIFY 是控制元件向其父視窗傳送訊息處理的巨集

對這幾個訊息的理解要先了解一下Window訊息的背景。
在Windows3.1裡,控制元件會將mouse, keybord等等的訊息通知它的父視窗, 使用的訊息就只有WM_COMMAND, 事件種類和控制元件ID被包含在wParam

中, 控制元件的控制代碼包含在lParam中。由於wParam和 lParam已經滿了,當控制元件要向父視窗傳送其它特殊訊息同時附帶很多資訊的時候就沒有地

方可以存放它們了。所以Windows3.1中定義了許多其它的 訊息種類,比如WM_VSCROLL, WM_CTLCOLOR等等,每種訊息wParam,lParam中附帶的

資訊是不同的。
當到了Win32後,控制元件的種類越來越多,當然不可以為每一個控制元件都定義一套訊息,這樣也不利於系統的擴充。所以在Win32中定義了唯一一

個強大的訊息 WM_NOTIFY。當然WM_NOTIFY也遵守原來的訊息規則,既只帶引數wParam和lParam。唯一不同處在於,此時的lParam中傳送的

是一個NMHDR指標。不同的控制元件可以按照規則對NMHDR進行擴充,因此WM_NOTIFY訊息傳送的資訊量可以相當的大,這個可以看看MSDN中的相

關說明,TreeControl中就有很多這種訊息。

現在就可以知道為什麼有ON_MESSAGE ,ON_COMMAND, , ON_NOTIFY了。
ON_MESSAGE是處理所有的Windows的訊息的,因為所有的訊息都以相同的格式傳送,也就是ID, WPARAM, LPARAM.
ON_COMMAND是專門處理WM_COMMAND訊息的,這樣我們就不用自己解開WM_COMMAND中wParam和lParam中傳送的控制元件ID, 事件種類…(所有的都

在MFC內部解決了:),當然方便了。
ON_NOTIFY更是不用說了,看看他的處理函式,是不是把NMHDR解出來了。

這樣一樣就一目瞭然了,ON_COMMAND和ON_NOTIFY都可以用ON_MESSAGE來處理,只不過自己要多做很多事情。ON_COMMAND和ON_NOTIFY最好就

不要互換了!

 
幾點說明:

1、ON_COMMAND(id,memberFxn)
此巨集通過ClassWizard或手工插入一個訊息對映。它表明那個函式將從一個命令使用者介面(例如一個選單項或toolbar按鈕)處理一個命令消

息。 當一個命令物件通過指定的ID接受到一個Windows WM_COMMAND訊息時,ON_COMMAND將呼叫成員函式memberFxn處理此消 息。在使用者的消

息對映中,對於每個選單或加速器命令(必須被對映到一個訊息處理函式)應該確實有一個ON_COMMAND巨集語句。

2、ON_MESSAGE(message,memberFxn)
指明哪個函式將處理一使用者定義訊息。使用者定義訊息通常定義在WM_USER到0x7FF範圍內。使用者定義訊息是那些不是標準 Windows WM_MESSAGE

訊息的任何訊息。在使用者的訊息對映中,每個必須被對映到一個訊息處理函式。使用者定義訊息應該有一個 ON_MESSAGE巨集語句。

3、ON_Update_COMMAND_UI(id,memberFxn)
此巨集通常通過ClassWizard被插入一個訊息對映,以指明哪個函式將處理一個使用者介面更改命令訊息。在使用者的訊息對映中,每個使用者介面更

改命令(比訊被對映到一個訊息處理函式)應該有一個ON_Update_COMMAND_UI巨集語句。
4、ON_VBXEVENT(wNotifyCode,memberFxn)
此巨集通常通過ClassWizard被插入一個訊息對映,以指明哪個函式將處理一個來自VBX控制的訊息。在使用者的訊息對映中每個被對映到一訊息

處理函式的VBX控制訊息應該有一個巨集語句。
5、ON_REGISTERED_MESSAGE(nmessageVarible,memberFxn)
Windows的RegisterWindowsMesage函式用於定義一個新視窗訊息,此訊息保證在整個系統中是唯一的。此巨集表明哪個函式處理已註冊訊息。

變數nMessageViable應以NEAR修飾符來定義。

6、ON_CONTROL(wNotifyCode,id,memberFxn)
表明哪個函式將處理一個常規控制表示訊息。控制標識訊息是那些從一個控制夫傳送到母視窗的訊息。