SendMessage函數完全使用手冊(ZT)

SendMessage函數完全使用手冊(ZT)

    首先  我們瞭解一下Windows的消息機制。Windows是一個消息驅動式系

統,Windows消息提供應用程序與應用程序之間,應用程序與Windows系統之間進

行通信的手段。
    舉個例子,打開記事本程序,該程序有一個 “文件“菜單。 那麼,在運行該程序

的時候,如果用戶單擊“文件菜單“裏的“新建“命令, 這個動作將被Windows所捕

捉,Windows經過分析得知這個動作應該由我們打開的記事本程序所來處理,然後

Windows就發送個消息 譬如我們編程的時候有時用到的 WM_COMMAND的消息給記

事本,然後記事本就把這個消息處理掉。 這個過程就是消息處理。
    接下來,我們把SendMessage的完整形式講一下
SendMessage
    Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal

hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As

Long
別名
     SendMessageA
說明
     調用一個窗口的窗口函數,將一條消息發給那個窗口。除非消息處理完畢,否

則該函數不會返回

SendMessage所包含4個參數
     hwnd        32位的窗口句柄窗口可以是任何類型的屏幕對象,因爲Win32能夠維

護大多數可視對象的句柄

     wMsg        用於區別其他消息的常量值,這些常量可以是Windows單元中預定

義的常量,也可以是自定義的常量
     wParam    通常是一個與消息有關的常量值,也可能是窗口或控件的句柄
     lParam      通常是一個指向內存中數據的指針。由於WParm、lParam和Pointer

都是32位的,因此,它們之間可以相互轉換

wMsg函數
  WM_CREATE                                   創建一個窗口
  WM_DESTROY                                  當一個窗口被破壞時發送
  WM_MOVE                                     移動一個窗口
  WM_SIZE                                     改變一個窗口的大小
  WM_ACTIVATE                                 一個窗口被激活或失去激活狀態
  WM_SETFOCUS                                 一個窗口獲得焦點
  WM_KILLFOCUS                                一個窗口失去焦點
  WM_ENABLE                                   一個窗口改變成Enable狀態
  WM_SETREDRAW                                設置窗口是否能重畫
  WM_SETTEXT                                  應用程序發送此消息來設置一個窗口的文本
  WM_GETTEXT                                  應用程序發送此消息來複制對應窗口的文本到緩衝區
  WM_GETTEXTLENGTH                            得到與一個窗口有關的文本的長度(不包含空字符)
  WM_PAINT                                    要求一個窗口重畫自己
  WM_CLOSE                                    當一個窗口或應用程序要關閉時發送一個信號
  WM_QUERYENDSESSION                          當用戶選擇結束對話框或程序自己調用ExitWindows函數
  WM_QUIT                                     用來結束程序運行
  WM_QUERYOPEN                                當用戶窗口恢復以前的大小位置時,把此消息發送給某個圖標
  WM_ERASEBKGND                               當窗口背景必須被擦除時(例在窗口改變大小時)
  WM_SYSCOLORCHANGE                           當系統顏色改變時,發送此消息給所有頂級窗口
  WM_ENDSESSION                               當系統進程發出WM_QUERYENDSESSION消息後,此消息發送給應用程序,通知它對話是否結束
  WM_SHOWWINDOW                               當隱藏或顯示窗口是發送此消息給這個窗口WM_ACTIVATEAPP

                                              發此消息給應用程序哪個窗口是激活的,哪個是非激活的
  WM_FONTCHANGE                               當系統的字體資源庫變化時發送此消息給所有頂級窗口
  WM_TIMECHANGE                               當系統的時間變化時發送此消息給所有頂級窗口
  WM_CANCELMODE                               發送此消息來取消某種正在進行的摸態(操作)
  WM_SETCURSOR                                如果鼠標引起光標在某個窗口中移動且鼠標輸入沒有被捕獲時,就發消息給某個窗口
  WM_MOUSEACTIVATE                            當光標在某個非激活的窗口中而用戶正按着鼠標的某個鍵發送此消息給當前窗口
  WM_CHILDACTIVATE                            發送此消息給MDI子窗口當用戶點擊此窗口的標題欄,或當窗口被激活,移動,改變大小
  WM_QUEUESYNC                                此消息由基於計算機的訓練程序發送,通過WH_JOURNALPALYBACK的hook程序分離出用戶輸入消息
  WM_GETMINMAXINFO                            此消息發送給窗口當它將要改變大小或位置
  WM_PAINTICON                                發送給最小化窗口當它圖標將要被重畫

 WM_ICONERASEBKGND                            此消息發送給某個最小化窗口,僅當它在畫圖標前它的背景必須被重畫
  WM_NEXTDLGCTL                               發送此消息給一個對話框程序去更改焦點位置
  WM_SPOOLERSTATUS                            每當打印管理列隊增加或減少一條作業時發出此消息
  WM_DRAWITEM                                 當button,combobox,listbox,menu的可視外觀改變時發送
  WM_MEASUREITEM                              當button, combo box, list box, list,view control, or menu item 被創建時
  WM_VKEYTOITEM                               此消息有一個LBS_WANTKEYBOARDINPUT風格的發出給它的所有者來響應WM_KEYDOWN消息
  WM_CHARTOITEM                               此消息由一個LBS_WANTKEYBOARDINPUT風格的列表框發送給他的所有者來響應WM_CHAR消息
  WM_SETFONT                                  當繪製文本時程序發送此消息得到控件要用的顏色
  WM_GETFONT                                  應用程序發送此消息得到當前控件繪製文本的字體
  WM_SETHOTKEY                                應用程序發送此消息讓一個窗口與一個熱鍵相關連
  WM_GETHOTKEY                                應用程序發送此消息來判斷熱鍵與某個窗口是否有關聯
  WM_QUERYDRAGICON                            此消息發送給最小化窗口,當此窗口將要被拖放而它的類中沒有定義圖標,

                                              應用程序能返回一個圖標或光標的句柄,當用戶拖放圖標時系統顯示這個圖標或光標
  WM_COMPAREITEM                              發送此消息來判定combobox或listbox新增加的項的相對位置
  WM_COMPACTING                               顯示內存已經很少了
  WM_WINDOWPOSCHANGING                        發送此消息給那個窗口的大小和位置將要被改變時,來調用setwindowpos函數或其它窗口管理函數
  WM_WINDOWPOSCHANGED                         發送此消息給那個窗口的大小和位置已經被改變時,來調用setwindowpos函數或其它窗口管理函數
  WM_POWER                                    當系統將要進入暫停狀態時發送此消息
  WM_COPYDATA                                 當一個應用程序傳遞數據給另一個應用程序時發送此消息
  WM_CANCELJOURNA                             當某個用戶取消程序日誌激活狀態,提交此消息給程序
  WM_NOTIFY                                   當某個控件的某個事件已經發生或這個控件需要得到一些信息時,發送此消息給它的父窗口
  WM_INPUTLANGCHANGEREQUEST                   當用戶選擇某種輸入語言,或輸入語言的熱鍵改變
  WM_INPUTLANGCHANGE                          當平臺現場已經被改變後發送此消息給受影響的最頂級窗口
  WM_TCARD                                    當程序已經初始化windows幫助例程時發送此消息給應用程序
  WM_HELP                                     此消息顯示用戶按下了F1,如果某個菜單是激活的,就發送此消息個此窗口關聯的菜單,

                                              否則就發送給有焦點的窗口,如果當前都沒有焦點,就把此消息發送給當前激活的窗口
  WM_USERCHANGED                              當用戶已經登入或退出後發送此消息給所有的窗口,當用戶登入或退出時系統更新用戶的具體設置信息,

                                              在用戶更新設置時系統馬上發送此消息
  WM_NOTIFYformAT                             公用控件,自定義控件和他們的父窗口通過此消息來判斷控件是使用ANSI還是UNICODE結構
  WM_CONTEXTMENU                              當用戶某個窗口中點擊了一下右鍵就發送此消息給這個窗口
  WM_styleCHANGING                            當調用SETWINDOWLONG函數將要改變一個或多個 窗口的風格時發送此消息給那個窗口
  WM_styleCHANGED                             當調用SETWINDOWLONG函數一個或多個 窗口的風格後發送此消息給那個窗口
  WM_DISPLAYCHANGE                            當顯示器的分辨率改變後發送此消息給所有的窗口
  WM_GETICON                                  此消息發送給某個窗口來返回與某個窗口有關連的大圖標或小圖標的句柄
  WM_SETICON                                  程序發送此消息讓一個新的大圖標或小圖標與某個窗口關聯
  WM_NCCREATE                                 當某個窗口第一次被創建時,此
消息在WM_CREATE消息發送前發送
  WM_NCDESTROY                                此消息通知某個窗口,非客戶區正在銷燬
  WM_NCCALCSIZE                                當某個窗口的客戶區域必須被覈算時發送此消息
  WM_NCHITTEST                                 移動鼠標,按住或釋放鼠標時發生
  WM_NCPAINT                                   程序發送此消息給某個窗口當它(窗口)的框架必須被繪製時
  WM_NCACTIVATE                                此消息發送給某個窗口僅當它的非客戶區需要被改變來顯示是激活還是非激活狀態
  WM_GETDLGCODE                                發送此消息給某個與對話框程序關聯的控件,widdows控制方位鍵和TAB鍵使輸入進入此控件通過應
  WM_NCMOUSEMOVE                               當光標在一個窗口的非客戶區內移動時發送此消息給這個窗口  非客戶區爲:窗體的標題欄及窗 的邊框體
  WM_NCLBUTTONDOWN                             當光標在一個窗口的非客戶區同時按下鼠標左鍵時提交此消息
  WM_NCLBUTTONUP                               當用戶釋放鼠標左鍵同時光標某個窗口在非客戶區十發送此消息
  WM_NCLBUTTONDBLCLK                           當用戶雙擊鼠標左鍵同時光標某個窗口在非客戶區十發送此消息
  WM_NCRBUTTONDOWN                             當用戶按下鼠標右鍵同時光標又在窗口的非客戶區時發送此消息
  WM_NCRBUTTONUP                               當用戶釋放鼠標右鍵同時光標又在窗口的非客戶區時發送此消息
  WM_NCRBUTTONDBLCLK                           當用戶雙擊鼠標右鍵同時光標某個窗口在非客戶區十發送此消息
  WM_NCMBUTTONDOWN                             當用戶按下鼠標中鍵同時光標又在窗口的非客戶區時發送此消息
  WM_NCMBUTTONUP                               當用戶釋放鼠標中鍵同時光標又在窗口的非客戶區時發送此消息
  WM_NCMBUTTONDBLCLK                           當用戶雙擊鼠標中鍵同時光標又在窗口的非客戶區時發送此消息
  WM_KEYFIRST        WM_KEYDOWN                按下一個鍵
  WM_KEYUP                                     釋放一個鍵
  WM_CHAR                                      按下某鍵,並已發出WM_KEYDOWN, WM_KEYUP消息
  WM_DEADCHAR                                  當用translatemessage函數翻譯
  WM_KEYUP                                     消息時發送此消息給擁有焦點的窗口
  WM_SYSKEYDOWN                                當用戶按住ALT鍵同時按下其它,鍵時提交此消息給擁有焦點的窗口  
  WM_SYSKEYUP                                  當用戶釋放一個鍵同時ALT 鍵還按着時提交此消息給擁有焦點的窗口
  WM_SYSCHAR                                   當WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函數翻譯後提交此消息給擁有焦點的窗口
  WM_SYSDEADCHAR                               當WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函數翻譯後發送此消息給擁有焦點的窗口
  WM_INITDIALOG                                在一個對話框程序被顯示前發送此消息給它,通常用此消息初始化控件和執行其它任務
  WM_COMMAND                                   當用戶選擇一條菜單命令項或當某個控件發送一條消息給它的父窗口,一個快捷鍵被翻譯
  WM_SYSCOMMAND                                當用戶選擇窗口菜單的一條命令或當用戶選擇最大化或最小化時那個窗口會收到此消息
  WM_TIMER                                     發生了定時器事件
  WM_HSCROLL                                   當一個窗口標準水平滾動條產生一個滾動事件時發送此消息給那個窗口,也發送給擁有它的控件
  WM_VSCROLL                                   當一個窗口標準垂直滾動條產生一個滾動事件時發送此消息給那個窗口也,發送給擁有它的控件
  WM_INITMENU                                  當一個菜單將要被激活時發送此消息,它發生在用戶菜單條中的某項或按下某個菜單鍵,

                                               它允許程序在顯示前更改菜單
  WM_INITMENUPOPUP                             當一個下拉菜單或子菜單將要被激活時發送此消息,它允許程序在它顯示前更改菜單,而不要改變全部
  WM_MENUSELECT                                當用戶選擇一條菜單項時發送此消息給菜單的所有者(一般是窗口)
  WM_MENUCHAR                                  當菜單已被激活用戶按下了某個鍵(不同於加速鍵),發送此消息給菜單的所有者
  WM_ENTERIDLE                                 當一個模態對話框或菜單進入空載狀態時發送此消息給它的所有者,

                                               一個模態對話框或菜單進入空載狀態就是在處理完一條或幾條先前的消息後沒有消息它的列隊中等待

  WM_CTLCOLORMSGBOX                           在windows繪製消息框前發送此消息給消息框的所有者窗口,通過響應這條消息,

                                              所有者窗口可以通過使用給定的相關顯示設備的句柄來設置消息框的文本和背景顏色
  WM_CTLCOLOREDIT                             當一個編輯型控件將要被繪製時發送此消息給它的父窗口 通過響應這條消息,

                                              所有者窗口可以通過使用給定的相關顯示設備的句柄來設置編輯框的文本和背景顏色
  WM_CTLCOLORLISTBOX                          當一個列表框控件將要被繪製前發送此消息給它的父窗口 通過響應這條消息,

                                               所有者窗口可以通過使用給定的相關顯示設備的句柄來設置列表框的文本和背景顏色
  WM_CTLCOLORBTN                               當一個按鈕控件將要被繪製時發送此消息給它的父窗口 通過響應這條消息,

                                                所有者窗口可以通過使用給定的相關顯示設備的句柄來設置按紐的文本和背景顏色
  WM_CTLCOLORDLG                                當一個對話框控件將要被繪製前發送此消息給它的父窗口 通過響應這條消息,

                                                 所有者窗口可以通過使用給定的相關顯示設備的句柄來設置對話框的文本背景顏色
  WM_CTLCOLORSCROLLBAR                           當一個滾動條控件將要被繪製時發送此消息給它的父窗口 通過響應這條消息,

                                                  所有者窗口可以通過使用給定的相關顯示設備的句柄來設置滾動條的背景顏色
  WM_CTLCOLORSTATIC                               當一個靜態控件將要被繪製時發送此消息給它的父窗口 通過響應這條消息,

                                                所有者窗口可以 通過使用給定的相關顯示設備的句柄來設置靜態控件的文本和背景顏色
  WM_MOUSEFIRST WM_MOUSEMOVE                    移動鼠標
  WM_LBUTTONDOWN                                按下鼠標左鍵
  WM_LBUTTONUP                                  釋放鼠標左鍵
  WM_LBUTTONDBLCLK                              雙擊鼠標左鍵
  WM_RBUTTONDOWN                                按下鼠標右鍵
  WM_RBUTTONUP                                  釋放鼠標右鍵
  WM_RBUTTONDBLCLK                              雙擊鼠標右鍵
  WM_MBUTTONDOWN                                按下鼠標中鍵
  WM_MBUTTONUP                                  釋放鼠標中鍵
  WM_MBUTTONDBLCLK                              雙擊鼠標中鍵
  WM_MOUSEWHEEL                                 當鼠標輪子轉動時發送此消息個當前有焦點的控件
  WM_PARENTNOTIFY                               當MDI子窗口被創建或被銷燬,或用戶按了一下鼠標鍵而光標在子窗口上時發送此消息給它的父窗口
  WM_ENTERMENULOOP                              發送此消息通知應用程序的主窗口that已經進入了菜單循環模式
  WM_EXITMENULOOP                               發送此消息通知應用程序的主窗口that已退出了菜單循環模式
  WM_SIZING                                     當用戶正在調整窗口大小時發送此消息給窗口 通過此消息應用程序可以監視窗口大小和位置也可以修改他們
  WM_CAPTURECHANGED                             發送此消息 給窗口當它失去捕獲的鼠標時
  WM_MOVING                                     當用戶在移動窗口時發送此消息,通過此消息應用程序可以監視窗口大小和位置也可以修改他們
  WM_POWERBROADCAST                             此消息發送給應用程序來通知它有關電源管理事件

 
  WM_DEVICECHANGE                               當設備的硬件配置改變時發送此消息給應用程序或設備驅動程序
  WM_MDIDESTROY                                 應用程序發送此消息給多文檔的客戶窗口來關閉一個MDI 子窗口
  WM_MDIACTIVATE                                應用程序發送此消息給多文檔的客戶窗口通知客戶窗口激活另一個MDI子窗口,

                                                當客戶窗口收到此消息後,它發出WM_MDIACTIVE消息給MDI子窗口(未激活)激活它
  WM_MDIRESTORE                                 程序 發送此消息給MDI客戶窗口讓子窗口從最大最小化恢復到原來大小
  WM_MDINEXT                                    程序 發送此消息給MDI客戶窗口激活下一個或前一個窗口
  WM_MDIMAXIMIZE                                程序發送此消息給MDI客戶窗口來最大化一個MDI子窗口
  WM_MDITILE                                    程序 發送此消息給MDI客戶窗口以平鋪方式重新排列所有MDI子窗口
  WM_MDICASCADE                                 程序 發送此消息給MDI客戶窗口以層疊方式重新排列所有MDI子窗口
  WM_MDIICONARRANGE                             程序 發送此消息給MDI客戶窗口重新排列所有最小化的MDI子窗口
  WM_MDIGETACTIVE                               程序 發送此消息給MDI客戶窗口來找到激活的子窗口的句柄
  WM_MDISETMENU                                 程序 發送此消息給MDI客戶窗口用MDI菜單代替子窗口的菜單
  WM_CUT                                        程序發送此消息給一個編輯框或combobox來刪除當前選擇的文本
  WM_COPY                                       程序發送此消息給一個編輯框或combobox來複制當前選擇的文本到剪貼板
  WM_PASTE                                      程序發送此消息給editcontrol或combobox從剪貼板中得到數據
  WM_CLEAR                                      程序發送此消息給editcontrol或combobox清除當前選擇的內容
  WM_UNDO                                       程序發送此消息給editcontrol或combobox撤消最後一次操作
  WM_DESTROYCLIPBOARD                           當調用ENPTYCLIPBOARD函數時 發送此消息給剪貼板的所有者
  WM_DRAWCLIPBOARD                              當剪貼板的內容變化時發送此消息給剪貼板觀察鏈的第一個窗口

                                                它允許用剪貼板觀察窗口來顯示剪貼板的新內容
  WM_PAINTCLIPBOARD                             當剪貼板包含CF_OWNERDIPLAY格式的數據並且剪貼板觀察窗口的客戶區需要重畫
  WM_SIZECLIPBOARD                              當剪貼板包含CF_OWNERDIPLAY格式的數據並且剪貼板觀察窗口的客戶區域的大小已經改變是

                                                此消息通過剪貼板觀察窗口發送給剪貼板的所有者
  WM_ASKCBformATNAME                            通過剪貼板觀察窗口發送此消息給剪貼板的所有者來請求一個CF_OWNERDISPLAY格式的剪貼板的名字
  WM_CHANGECBCHAIN                              當一個窗口從剪貼板觀察鏈中移去時發送此消息給剪貼板觀察鏈的第一個窗口
  WM_HSCROLLCLIPBOARD                           此消息通過一個剪貼板觀察窗口發送給剪貼板的所有者  它發生在當剪貼板包含CFOWNERDISPALY格式的數

                                                據並且有個事件在剪貼板觀察窗的水平滾動條上 所有者應滾動剪貼板圖象並更新滾動條的值
  WM_QUERYNEWPALETTE                           此消息發送給將要收到焦點的窗口,此消息能使窗口在收到焦點時同時有機會實現他的邏輯調色板
  WM_PALETTEISCHANGING                         當一個應用程序正要實現它的邏輯調色板時發此消息通知所有的應用程序
  WM_PALETTECHANGED                            此消息在一個擁有焦點的窗口實現它的邏輯調色板後發送此消息給所有頂級並重疊的窗口,以此來改變系統

                                               調色板
  WM_HOTKEY                                    當用戶按下由REGISTERHOTKEY函數註冊的熱鍵時提交此消息
  WM_PRINT                                     應用程序發送此消息僅當WINDOWS或其它應用程序發出一個請求要求繪製一個應用程序的一部分

 

什麼是消息?

   消息系統對於一個win32程序來說十分重要,它是一個程序運行的動力源泉。一個消息,是系統定義的一個32位的值,他唯一的定義了一個事件,向Windows發出一個通知,告訴應用程序某個事情發生了。例如,單擊鼠標、改變窗口尺寸、按下鍵盤上的一個鍵都會使Windows發送一個消息給應用程序。

   消息本身是作爲一個記錄傳遞給應用程序的,這個記錄中包含了消息的類型以及其他信息。例如,對於單擊鼠標所產生的消息來說,這個記錄中包含了單擊鼠標時的座標。這個記錄類型叫做MSG,MSG含有來自windows應用程序消息隊列的消息信息,它在Windows中聲明如下:

typedef struct tagMsg
{
HWND hwnd; 接受該消息的窗口句柄
UINT message; 消息常量標識符,也就是我們通常所說的消息號
WPARAM wParam; 32位消息的特定附加信息,確切含義依賴於消息值
LPARAM lParam; 32位消息的特定附加信息,確切含義依賴於消息值
DWORD time; 消息創建時的時間
POINT pt; 消息創建時的鼠標/光標在屏幕座標系中的位置
}MSG;

   消息可以由系統或者應用程序產生。系統在發生輸入事件時產生消息。舉個例子, 當用戶敲鍵, 移動鼠標或者單擊控件。系統也產生消息以響應由應用程序帶來的變化, 比如應用程序改變系統字體改變窗體大小。應用程序可以產生消息使窗體執行任務,或者與其他應用程序中的窗口通訊。

   消息中有什麼?

   我們給出了上面的註釋,是不是會對消息結構有了一個比較清楚的認識?如果還沒有,那麼我們再試着給出下面的解釋:

   hwnd 32位的窗口句柄。窗口可以是任何類型的屏幕對象,因爲Win32能夠維護大多數可視對象的句柄(窗口、對話框、按鈕、編輯框等)。

   message用於區別其他消息的常量值,這些常量可以是Windows單元中預定義的常量,也可以是自定義的常量。消息標識符以常量命名的方式指出消息的含義。當窗口過程接收到消息之後,他就會使用消息標識符來決定如何處理消息。例如、WM_PAINT告訴窗口過程窗體客戶區被改變了需要重繪。符號常量指定系統消息屬於的類別,其前綴指明瞭處理解釋消息的窗體的類型。

   wParam 通常是一個與消息有關的常量值,也可能是窗口或控件的句柄。

   lParam 通常是一個指向內存中數據的指針。由於WParam、lParam和Pointer都是32位的,因此,它們之間可以相互轉換。

消息標識符的值

   系統保留消息標識符的值在0x0000在0x03ff(WM_USER-1)範圍。這些值被系統定義消息使用。 應用程序不能使用這些值給自己的消息。應用程序消息從WM_USER(0X0400)到0X7FFF,或0XC000到0XFFFF;WM_USER到0X7FFF範圍的消息由應用程序自己使用;0XC000到0XFFFF範圍的消息用來和其他應用程序通信,我們順便說一下具有標誌性的消息值:

WM_NULL---0x0000 空消息。
0x0001----0x0087 主要是窗口消息。
0x00A0----0x00A9 非客戶區消息
0x0100----0x0108 鍵盤消息
0x0111----0x0126 菜單消息
0x0132----0x0138 顏色控制消息
0x0200----0x020A 鼠標消息
0x0211----0x0213 菜單循環消息
0x0220----0x0230 多文檔消息
0x03E0----0x03E8 DDE消息
0x0400 WM_USER
0x8000 WM_APP
0x0400----0x7FFF 應用程序自定義私有消息

   消息有的分類?

   其實,windows中的消息雖然很多,但是種類並不繁雜,大體上有3種:窗口消息、命令消息和控件通知消息。

   窗口消息大概是系統中最爲常見的消息,它是指由操作系統和控制其他窗口的窗口所使用的消息。例如CreateWindow、DestroyWindow和MoveWindow等都會激發窗口消息,還有我們在上面談到的單擊鼠標所產生的消息也是一種窗口消息。

   命令消息,這是一種特殊的窗口消息,他用來處理從一個窗口發送到另一個窗口的用戶請求,例如按下一個按鈕,他就會向主窗口發送一個命令消息。

   控件通知消息,是指這樣一種消息,一個窗口內的子控件發生了一些事情,需要通知父窗口。通知消息只適用於標準的窗口控件如按鈕、列表框、組合框、編輯框,以及Windows公共控件如樹狀視圖、列表視圖等。例如,單擊或雙擊一個控件、在控件中選擇部分文本、操作控件的滾動條都會產生通知消息。 她類似於命令消息,當用戶與控件窗口交互時,那麼控件通知消息就會從控件窗口發送到它的主窗口。但是這種消息的存在並不是爲了處理用戶命令,而是爲了讓主窗口能夠改變控件,例如加載、顯示數據。例如按下一個按鈕,他向父窗口發送的消息也可以看作是一個控件通知消息;單擊鼠標所產生的消息可以由主窗口直接處理,然後交給控件窗口處理。

   其中窗口消息及控件通知消息主要由窗口類即直接或間接由CWND類派生類處理。相對窗口消息及控件通知消息而言,命令消息的處理對象範圍就廣得多,它不僅可以由窗口類處理,還可以由文檔類,文檔模板類及應用類所處理。

   由於控件通知消息很重要的,人們用的也比較多,但是具體的含義往往令初學者暈頭轉向,所以我決定把常見的幾個列出來供大家參考:

   按扭控件

BN_CLICKED 用戶單擊了按鈕
BN_DISABLE 按鈕被禁止
BN_DOUBLECLICKED 用戶雙擊了按鈕
BN_HILITE 用/戶加亮了按鈕
BN_PAINT 按鈕應當重畫
BN_UNHILITE 加亮應當去掉

   組合框控件

CBN_CLOSEUP 組合框的列表框被關閉
CBN_DBLCLK 用戶雙擊了一個字符串
CBN_DROPDOWN 組合框的列表框被拉出
CBN_EDITCHANGE 用戶修改了編輯框中的文本
CBN_EDITUPDATE 編輯框內的文本即將更新
CBN_ERRSPACE 組合框內存不足
CBN_KILLFOCUS 組合框失去輸入焦點
CBN_SELCHANGE 在組合框中選擇了一項
CBN_SELENDCANCEL 用戶的選擇應當被取消
CBN_SELENDOK 用戶的選擇是合法的
CBN_SETFOCUS 組合框獲得輸入焦點

   編輯框控件

EN_CHANGE 編輯框中的文本己更新
EN_ERRSPACE 編輯框內存不足
EN_HSCROLL 用戶點擊了水平滾動條
EN_KILLFOCUS 編輯框正在失去輸入焦點
EN_MAXTEXT 插入的內容被截斷
EN_SETFOCUS 編輯框獲得輸入焦點
EN_UPDATE 編輯框中的文本將要更新
EN_VSCROLL 用戶點擊了垂直滾動條消息含義

   列表框控件

LBN_DBLCLK 用戶雙擊了一項
LBN_ERRSPACE 列表框內存不夠
LBN_KILLFOCUS 列表框正在失去輸入焦點
LBN_SELCANCEL 選擇被取消
LBN_SELCHANGE 選擇了另一項
LBN_SETFOCUS 列表框獲得輸入焦點

隊列消息和非隊列消息

   從消息的發送途徑來看,消息可以分成2種:隊列消息和非隊列消息。消息隊列由可以分成系統消息隊列和線程消息隊列。系統消息隊列由Windows維護,線程消息隊列則由每個GUI線程自己進行維護,爲避免給non-GUI現成創建消息隊列,所有線程產生時並沒有消息隊列,僅當線程第一次調用GDI函數數系統給線程創建一個消息隊列。隊列消息送到系統消息隊列,然後到線程消息隊列;非隊列消息直接送給目的窗口過程。

   對於隊列消息,最常見的是鼠標和鍵盤觸發的消息,例如WM_MOUSERMOVE,WM_CHAR等消息,還有一些其它的消息,例如:WM_PAINT、WM_TIMER和WM_QUIT。當鼠標、鍵盤事件被觸發後,相應的鼠標或鍵盤驅動程序就會把這些事件轉換成相應的消息,然後輸送到系統消息隊列,由Windows系統去進行處理。Windows系統則在適當的時機,從系統消息隊列中取出一個消息,根據前面我們所說的MSG消息結構確定消息是要被送往那個窗口,然後把取出的消息送往創建窗口的線程的相應隊列,下面的事情就該由線程消息隊列操心了,Windows開始忙自己的事情去了。線程看到自己的消息隊列中有消息,就從隊列中取出來,通過操作系統發送到合適的窗口過程去處理。 //有關Windows中消息的走向的說明


   一般來講,系統總是將消息Post在消息隊列的末尾。這樣保證窗口以先進先出的順序接受消息。然而,WM_PAINT是一個例外,同一個窗口的多個 WM_PAINT被合併成一個 WM_PAINT 消息, 合併所有的無效區域到一個無效區域。合併WM_PAIN的目的是爲了減少刷新窗口的次數

   非隊列消息將會繞過系統隊列和消息隊列,直接將消息發送到窗口過程,。系統發送非隊列消息通知窗口,系統發送消息通知窗口。 例如,當用戶激活一個窗口系統發送WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR。這些消息通知窗口它被激活了。非隊列消息也可以由當應用程序調用系統函數產生。例如,當程序調用SetWindowPos系統發送WM_WINDOWPOSCHANGED消息。一些函數也發送非隊列消息,例如下面我們要談到的函數。

   消息的發送

   瞭解了上面的這些基礎理論之後,我們就可以進行一下簡單的消息發送與接收。

   把一個消息發送到窗口有3種方式:發送、寄送和廣播。

   發送消息的函數有SendMessage、SendMessageCallback、SendNotifyMessage、SendMessageTimeout;寄送消息的函數主要有PostMessage、PostThreadMessage、PostQuitMessage;廣播消息的函數我知道的只有BroadcastSystemMessage、BroadcastSystemMessageEx。

   SendMessage的原型如下:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam),這個函數主要是向一個或多個窗口發送一條消息,一直等到消息被處理之後纔會返回。不過需要注意的是,如果接收消息的窗口是同一個應用程序的一部分,那麼這個窗口的窗口函數就被作爲一個子程序馬上被調用;如果接收消息的窗口是被另外的線程所創建的,那麼窗口系統就切換到相應的線程並且調用相應的窗口函數,這條消息不會被放進目標應用程序隊列中。函數的返回值是由接收消息的窗口的窗口函數返回,返回的值取決於被髮送的消息。

   PostMessage的原型如下:BOOL PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam),該函數把一條消息放置到創建hWnd窗口的線程的消息隊列中,該函數不等消息被處理就馬上將控制返回。需要注意的是,如果hWnd參數爲HWND_BROADCAST,那麼,消息將被寄送給系統中的所有的重疊窗口和彈出窗口,但是子窗口不會收到該消息;如果hWnd參數爲NULL,則該函數類似於將dwThreadID參數設置成當前線程的標誌來調用PostThreadMEssage函數。

   從上面的這2個具有代表性的函數,我們可以看出消息的發送方式和寄送方式的區別所在:被髮送的消息是否會被立即處理,函數是否立即返回。被髮送的消息會被立即處理,處理完畢後函數纔會返回;被寄送的消息不會被立即處理,他被放到一個先進先出的隊列中,一直等到應用程序空線的時候纔會被處理,不過函數放置消息後立即返回。

   實際上,發送消息到一個窗口處理過程和直接調用窗口處理過程之間並沒有太大的區別,他們直接的唯一區別就在於你可以要求操作系統截獲所有被髮送的消息,但是不能夠截獲對窗口處理過程的直接調用

   以寄送方式發送的消息通常是與用戶輸入事件相對應的,因爲這些事件不是十分緊迫,可以進行緩慢的緩衝處理,例如鼠標、鍵盤消息會被寄送,而按鈕等消息則會被髮送。

   廣播消息用得比較少,BroadcastSystemMessage函數原型如下:

long BroadcastSystemMessage(DWORD dwFlags,LPDWORD lpdwRecipients,UINT uiMessage,WPARAM wParam,LPARAM lParam);

   該函數可以向指定的接收者發送一條消息,這些接收者可以是應用程序、可安裝的驅動程序、網絡驅動程序、系統級別的設備驅動消息和他們的任意組合。需要注意的是,如果dwFlags參數是BSF_QUERY並且至少一個接收者返回了BROADCAST_QUERY_DENY,則返回值爲0,如果沒有指定BSF_QUERY,則函數將消息發送給所有接收者,並且忽略其返回值。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章