首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

深入理解 WM_NOTIFY 通知訊息機制

     編輯:VC 教學

引入背景

Win 3.x 時代,控制項通知、選單命令、加速鍵均用 WM_COMMAND,參數結構固定 (wParam 高序通知碼、低序控制項 ID、lParam 控制項句柄),無法攜帶額外資料 (如 ListView 點擊欄位索引)。Win32 引入 WM_NOTIFY 統一解決此問題。

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 參數識別具體發送控制項。

設計優勢

  1. 統一架構:所有複雜通知共用 WM_NOTIFY,無需像 Win3.x 定義大量專用訊息 (WM_DRAWITEM 等)。
  2. 相容性:舊版專用訊息保留,內部實作相同。
  3. 擴充性:擴充結構體首置 NMHDR,單一指標型別即可傳遞任意資料。

與訊息反射的關係

WM_NOTIFY 與「訊息反射」關係緊密,控制項可將通知反射回自身處理 (如 ON_NOTIFY_REFLECT),進一步解耦父視窗邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved