TN061: ON_NOTIFY 及 WM_NOTIFY 訊息
注意事項 |
---|
由於它第一次線上文件中包含尚未更新下列技術提示。如此一來,某些程序和主題可能已經過期或不正確。如需最新資訊,建議您先搜尋線上文件索引中有興趣的主題。 |
這份技術提示提供背景資訊的新 WM_NOTIFY 訊息,並描述建議 (也最常見的方式處理 WM_NOTIFY 在 MFC 應用程式中的訊息。
在 [Windows 3.x 告知訊息
在 Windows 3.x 中,控制項通知事件,例如按下滑鼠的父系變更內容,並在選取的項目,和控制項背景繪製可以傳送訊息給父代。 簡單的通知會傳送特殊 WM_COMMAND 訊息,告知程式碼 (例如 BN_CLICKED),並控制識別碼封裝成wParam和控制項的控制代碼,以lParam。 請注意,因為wParam和lParam已滿,沒有方法来傳遞的任何額外資料,這些訊息可以是簡單的通知。 舉個例說,在 BN_CLICKED 通知,就無法傳送的滑鼠指標位置的相關資訊,在按下按鈕時。
當 Windows 3.x 中的控制項需要傳送通知訊息,其中包含其他資料時,它們會使用各種不同的特殊用途的訊息,包括WM_CTLCOLOR, WM_VSCROLL, WM_HSCROLL, WM_DRAWITEM, WM_MEASUREITEM, WM_COMPAREITEM, WM_DELETEITEM, WM_CHARTOITEM, WM_VKEYTOITEM,依此類推。 這些訊息可以反映到他們的控制項中。 如需詳細資訊,請參閱 TN062: Windows 控制項訊息反映的。
在 Win32 的告知訊息
存在於 Windows 3.1 中的控制項,Win32 API 使用大部分的 Windows 3.x 中所用之告知訊息。 但是,Win32 也將若干精密、 複雜的控制項加入至 Windows 3.x 中所支援。 通常,這些控制項需要傳送其他的資料,並顯示其通知訊息。 與其將新的 WM_ 1 訊息的每個新的通知需要額外的資料,Win32 API 的設計人員選擇將新增一個訊息, WM_NOTIFY,它可以傳遞任何數量的詳細資料以標準化方式。
WM_NOTIFY 訊息包含傳送訊息的控制項 ID wParam ,並指向在結構lParam。 這種結構可能是 NMHDR 結構或部分結構 NMHDR 做為其第一個成員的結構。 請注意,因為 NMHDR 成員是第一個、 變數的指標,此結構可用來做任一個變數的指標, NMHDR 或做為變數的指標,較大的結構取決於您對它所做的轉換。
在大部分的情況下,指標將會指到一個較大的結構,您可能需要將它轉換,當您使用它。 在只有幾個通知,例如常見的通知 (其名稱開頭 NM_) 和工具提示控制項的 TTN_SHOW 和 TTN_POP 通知,是 NMHDR 實際上使用的結構。
NMHDR 結構或初始成員包含的控制代碼和傳送訊息,告知程式碼的控制項 ID (例如 TTN_SHOW)。 格式的 NMHDR 結構如下所示:
typedef struct tagNMHDR {
HWND hwndFrom;
UINT idFrom;
UINT code;
} NMHDR;
對於 TTN_SHOW 訊息, 的程式碼 成員會設定為 TTN_SHOW。
大部分的通知結構,其中包含以傳遞指標 NMHDR 做為其第一個成員的結構。 舉個例說,請考慮使用的清單檢視控制項的結構 LVN_KEYDOWN 通知訊息,當按下按鍵清單檢視控制項中,會傳送。 將指標指到 LV_KEYDOWN 結構,定義如下所示:
typedef struct tagLV_KEYDOWN {
NMHDR hdr;
WORD wVKey;
UINT flags;
} LV_KEYDOWN;
請注意,因為 NMHDR 這種結構中的第一個成員,您所傳入的通知訊息的指標可以轉換成其中一個變數的指標, NMHDR 或變數的指標, LV_KEYDOWN。
通知共通用於所有新的 Windows 控制項
某些通知是通用於所有新的 Windows 控制項。 這些通知傳遞變數的指標, NMHDR 結構。
告知程式碼 |
送出因為 |
---|---|
NM_CLICK |
使用者按下滑鼠左鍵的按鈕,在控制項中 |
NM_DBLCLK |
使用者按兩下的滑鼠的左鍵的按鈕,在控制項中 |
NM_RCLICK |
使用者已按一下滑鼠右鍵在控制項中 |
NM_RDBLCLK |
使用者按兩下的滑鼠右鍵在控制項中 |
NM_RETURN |
當控制項具有輸入焦點時,使用者按下 ENTER 鍵 |
NM_SETFOCUS |
控制項具有輸入的焦點 |
NM_KILLFOCUS |
控制項已遺失輸入的焦點 |
NM_OUTOFMEMORY |
控制項無法完成作業,因為沒有足夠的記憶體 |
ON_NOTIFY: 處理 WM_NOTIFY 訊息,在 MFC 應用程式
此函式CWnd::OnNotify處理告知訊息。 它的預設實作會檢查要呼叫的告知處理常式的訊息對應。 一般情況下,您不會覆寫OnNotify。 相反地,您提供了一個處理函式,然後新增該處理常式的訊息對應項目加入主控視窗的類別的訊息對應。
類別精靈,透過類別的屬性工作表,可以建立ON_NOTIFY訊息對應項目,並讓您有一個基本架構處理函式。 如需有關如何以達成更容易使用類別精靈的詳細資訊,請參閱訊息對應到函式。
ON_NOTIFY訊息對應巨集語法如下:
ON_NOTIFY( wNotifyCode, id, memberFxn )
其中斜體的參數會用來取代:
wNotifyCode
無法處理,例如通知訊息的程式碼 LVN_KEYDOWN。id
子控制項識別碼將通知傳送。memberFxn
此通知會在傳送時所要呼叫成員函式。
您的成員函式必須宣告具有下列原型:
afx_msg void memberFxn( NMHDR * pNotifyStruct, LRESULT * result );
備註
其中斜體的參數為:
pNotifyStruct
通知的結構,如上面所述的指標。result
變數的指標的結果程式碼,您將會傳回之前。
範例
若要指定您想要的成員函式OnKeydownList1來處理 LVN_KEYDOWN 訊息從CListCtrl誰的 ID 是IDC_LIST1,您可以使用類別精靈,來將下列加入您的訊息對應:
ON_NOTIFY( LVN_KEYDOWN, IDC_LIST1, OnKeydownList1 )
在上述範例中,類別精靈所提供的函式是:
void CMessageReflectionDlg::OnKeydownList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;
// TODO: Add your control notification handler
// code here
*pResult = 0;
}
請注意類別精靈會自動提供正確型別的指標。 您可以透過其中一個存取通知的結構pNMHDR或pLVKeyDow。
ON_NOTIFY_RANGE
如果您需要處理相同 WM_NOTIFY 訊息的一組控制項,您可以使用 ON_NOTIFY_RANGE 而不是ON_NOTIFY。 舉個例說,您可能會有一組按鈕,您想要執行的特定通知訊息的相同的動作。
當您使用 ON_NOTIFY_RANGE,您可以指定要用來處理通知訊息,藉由指定開始和結束範圍的子系的識別項的子系識別項的連續範圍。
類別精靈不處理 ON_NOTIFY_RANGE。 若要使用它,您需要自行編輯您的訊息對應。
訊息對應項目,而且函式原型的 ON_NOTIFY_RANGE 如下:
ON_NOTIFY_RANGE( wNotifyCode, id, idLast, memberFxn )
其中斜體的參數會用來取代:
wNotifyCode
無法處理,例如通知訊息的程式碼 LVN_KEYDOWN。id
識別項的連續範圍中第一個識別項。idLast
識別項的連續範圍中最後一個識別項。memberFxn
此通知會在傳送時所要呼叫成員函式。
您的成員函式必須宣告具有下列原型:
afx_msg void memberFxn( UINT id, NMHDR * pNotifyStruct, LRESULT * result );
備註
其中斜體的參數為:
id
傳送告知的控制項的子系識別項。pNotifyStruct
若要通知的結構,如前文所述變數的指標。result
變數的指標的結果程式碼,您將會傳回之前。
ON_NOTIFY_EX ON_NOTIFY_EX_RANGE
如果您想要在通知中的多個物件至路由處理訊息,您可以使用 ON_NOTIFY_EX (或 ON_NOTIFY_EX_RANGE) 而不是ON_NOTIFY (或 ON_NOTIFY_RANGE)。 之間的唯一差異 EX 個呼叫成員函式版本與一般的版本是 EX 版會傳回 BOOL ,表示是否應該繼續的訊息處理。 傳回 ,則為 FALSE 從此函式可讓您處理多個物件在相同的訊息。
類別精靈不處理 ON_NOTIFY_EX 或 ON_NOTIFY_EX_RANGE。 如果您想要使用其中任何一種,您需要自行編輯您的訊息對應。
訊息對應項目,而且函式原型的 ON_NOTIFY_EX 和 ON_NOTIFY_EX_RANGE 如下。 參數的意義是相同的非-EX 版本。
ON_NOTIFY_EX( nCode, id, memberFxn )
ON_NOTIFY_EX_RANGE( wNotifyCode, id, idLast, memberFxn )
這兩個以上的原型是一樣的:
afx_msg BOOL memberFxn( UINT id, NMHDR * pNotifyStruct, LRESULT * result );
備註
在這兩種情況下, id持有子系的控制項識別碼傳送告知。
您的函式必須傳回 ,則為 TRUE 如果完全處理通知訊息或 ,則為 FALSE 中命令路由內的其他物件,如果應該有一個機會來處理訊息。