WM_COMMAND 和 WM_NOTIFY 的區別


當我們按下一個菜單選項,或者一個控件需要通知父窗口一個事件發生(如鼠標單擊、雙擊等),或者快捷鍵被按下時,Windows將會發送一個 WM_COMMAND 消息給父窗口。那么 WM_COMMAND 消息參數是什么呢?

 

 

WM_COMMAND 消息來源 WPARAM 高位 WPARAM 低位 LPARAM
菜單 0 菜單 ID 0
快捷鍵 1 快捷鍵對應菜單 ID 0
控件 響應 Code(如BN_CLICKED) 控件 ID 控件句柄


OK,一切運行的很好,通過 WPARAM 高位置1或0區分菜單、快捷鍵、或者控件事件Code,通過 WPARAM 低位可以知道發出WM_COMMAND消息的菜單項或控件ID,通過LPARAM知道控件句柄。

 

 

 

 

 

 

 

 

 

 

然而,有一天,當選中一個 ListControl 控件中的某一行時,人們忽然發現父窗口需要知道被選中該行的索引,這下為難了,對於控件來看,整個WM_COMMAND消息的WPARAM、LPARAM 都被塞的滿滿的。怎么辦呢?這兒有一種解決辦法:新增一個消息,就叫WM_LIST_CONTROL_CLICKED吧,如下:

 

消息類型 WPARAM 高位 WPARAM 低位 LPARAM
WM_LIST_CONTROL_CLICKED 被選中行的索引 ListControl 控件的 ID ListControl 控件的句柄

 

 

 

 

 

 

 

 

 

 

呃,看起來的確解決了問題,我們把事件 Code 通過消息 ID 體現了出來,然后把被選中行的索引塞進了WPARAM的高位,看起來非常完美!然而又有一天,人們發現對ListView,父窗口需要知道單擊該控件時選中的行號和列號,以便處理,照貓畫虎,我們又加了一個WM_LIST_VIEW_CLICKED。接着人們發現其他一些控件都需要這樣的改進,如果這樣增加消息的話,豈不是沒完沒了了?!!

 

於是,WM_NOTIFY消息橫空出世:

 

 

消息類型 WPARAM LPARAM
WM_NOTIFY 發生 WM_NOTIFY 消息的控件 ID NMHDR 指針


現在,我們將所有附加信息都存放在 NMHDR(Notify Message Handler)的一個結構體中,該結構體指針通過 LPARAM 通知到父窗口。NMHDR如下:

 

 

 

 

 

 

 

 

 

 

[cpp]  view plain copy
 
  1. typedef struct tagNMHDR  
  2. {  
  3.     HWND      hwndFrom;     // 控件句柄.  
  4.     UINT_PTR  idFrom;       // 控件 ID.  
  5.     UINT      code;         // NM_ code.  
  6. }   NMHDR;  

這只是一個一般的結構,如果我們需要知道 ListView選中的行和列,那么需要:

 

 

[cpp]  view plain copy
 
  1. typedef struct tagNMLISTVIEW  
  2. {  
  3.     NMHDR   hdr;            // NMHDR.  
  4.     int     iItem;          // 行號.  
  5.     int     iSubItem;       // 列號.  
  6.     UINT    uNewState;  
  7.     UINT    uOldState;  
  8.     UINT    uChanged;  
  9.     POINT   ptAction;  
  10.     LPARAM  lParam;  
  11. } NMLISTVIEW, *LPNMLISTVIEW;  

像其他的控件,都會對應這樣一個結構體,它們的第一個字段一定是 NMHDR。但一些微軟標准控件並不會發送WM_NOTIFY 消息,這些控件有:Edit、ComboBox、ListBox、Button、ScrollBar、Static等。所以在使用過程中請注意用法,最好的做法是參考MSDN。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM