Win 3.x 時代,控制項通知、選單命令、加速鍵均用 WM_COMMAND,參數結構固定 (wParam 高序通知碼、低序控制項 ID、lParam 控制項句柄),無法攜帶額外資料 (如 ListView 點擊欄位索引)。Win32 引入 WM_NOTIFY 統一解決此問題。
wParam:控制項 ID。lParam:指向結構體指標,首成員必為 NMHDR:typedef struct tagNMHDR {
HWND hwndFrom; // 發送者句柄
UINT idFrom; // 發送者 ID
UINT code; // 通知碼 (如 LVN_KEYDOWN)
} NMHDR;
若需附加資料,定義擴充結構體,首成員為 NMHDR:
typedef struct tagNMLVKEYDOWN {
NMHDR hdr;
WORD wVKey;
UINT flags;
} NMLVKEYDOWN, *LPNMLVKEYDOWN;
void CMyListCtrl::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult) {
LPNMLVKEYDOWN pLVKeyDown = (LPNMLVKEYDOWN)pNMHDR; // 強制轉型
// 使用 pLVKeyDown->wVKey, pLVKeyDown->flags ...
*pResult = 0;
}
對應訊息映射:ON_NOTIFY(LVN_KEYDOWN, IDC_LIST1, OnKeydown)。
連續 ID 控制項共用同一通知處理器:
ON_NOTIFY_RANGE(LVN_KEYDOWN, IDC_LIST_FIRST, IDC_LIST_LAST, OnKeydownRange)
// 處理函式原型:
afx_msg void OnKeydownRange(UINT id, NMHDR* pNMHDR, LRESULT* pResult);
id 參數識別具體發送控制項。
WM_NOTIFY,無需像 Win3.x 定義大量專用訊息 (WM_DRAWITEM 等)。NMHDR,單一指標型別即可傳遞任意資料。WM_NOTIFY 與「訊息反射」關係緊密,控制項可將通知反射回自身處理 (如 ON_NOTIFY_REFLECT),進一步解耦父視窗邏輯。