首先感謝各位老鳥這麼久以來對小弟那麼多的指導,給小弟提供N多的協助,所以才能讓我的第一篇技術文章可以這麼快和大家見面!也趁今天是小弟20歲生日呵呵,沒人給我慶祝,所以寫篇文章做個紀念,也祝我自己生日快樂! ^o^
小弟我學習Delphi算起來也有半年時間,看到網上很多朋友對HOOK非常的感興趣。所以即興寫了一篇文章,在CSDN裡小弟曾經發過一篇《Delphi的MU視窗代碼》(慚愧啊)由於那時候學的不久,所以有很多地方不是很完善,藉此文章重新向大家詳細介紹一下Windows下的訊息鉤子函數的用法和Windows的子類處理,希望對你們有協助。
好了,廢話了這麼久,也該進入正題了,關於HOOK的介紹就不再此介紹了,以前有很多例子和文章可以參考,實在不行google或者baidu一下!^_^
首先我們先看一下安裝HOOK的函數:
HHOOK SetWindowsHookEx( int idHook, //要安裝的HOOK的類型 HOOKPROC lpfn, //HOOK的回呼函數 HINSTANCE hMod, //進程 DWORD dwThreadId //程式的線程,如果為0則是全域HOOK);
熟悉了SetWindowsHookEx函數,我們就能開始我們的工作,掛鈎進程。首先開啟Delphi,建立一個DLL工程(DLL Wizard)。然後建立一個新的單元(Unit1)。首先在單元的 interface 下面聲明要用到的函數。
var OldHook:HHOOK; Histance:HISTANCE; OldProc:FARPROC;
我們的第一個函數是安裝HOOK,讓我們看一下代碼:
Function SetHook:Boolean;stdcall;begin OldHook:=SetWindowsHookEx(WH_KEYBOARD,@HookProc,Histance,0); if (OldHook=0) then exit else Result:=True;end;
這樣的話就安裝一個全域的鍵盤HOOK,HOOK的方法還有很多,在此就不一一列舉了。
下面介紹一下回呼函數:
Function HookProc(nCode,wParam,lParam:Integer);Integer;stdcall;begin Result:=CallNextHookEx(OldHook,nCode,wParam,lParam);end;
這樣的話就完成了對進程的掛鈎。可是掛上鉤我們的工作並沒結束,相反,我們的工作才剛剛開始。鉤子的作用是幫我們把DLL注入到別人的進程空間。現在我們的DLL已經在別人的進程空間內。所以,我們就可以做我們想做的事。
下面介紹一下Windows的子類化處理。
大家都知道,在Windows裡不管你做了什麼事,都會向Windows發送一條訊息,然後由Windows作出相應的處理後才會返回給傳送訊息的應用程式。那大家會問:“HOOK不是已經攔截了Windows訊息了嗎?”
是啊,那也要看是攔截了什麼訊息,就如上面我們寫的WH_KEYBOARD,我們攔截了鍵盤訊息,我們可以在按下任何一個按鍵的時候做出處理。訊息的種類有很多。可是我們今天要講的是Windows的子類化處理,這又是一門新的技術。不廢話了,這就開始。^_^
相信大家都見過兩這個API:GetWindowsLong 和 SetWindowLong;可能你們會說,這些不是處理視窗訊息的嗎?對,這就是我們要用到的API。
接下來讓我們看一下這些API的參數。LONG GetWindowLong( HWND hWnd, //表單的控制代碼 int nIndex //欲取回的資訊,可參照下表); nIndex的值可以是下列任何一個GWL_EXSTYLE 擴充視窗樣式 GWL_STYLE 視窗樣式 GWL_WNDPROC 該視窗的視窗函數的地址 GWL_HINSTANCE 擁有視窗的執行個體的控制代碼 GWL_HWNDPARENT 該視窗之父的控制代碼。不要用SetWindowWord來改變這個值 GWL_ID 對話方塊中一個子視窗的標識符 GWL_USERDATA 含義由應用程式規定 DWL_DLGPROC 這個視窗的對話方塊函數地址 DWL_MSGRESULT 在對話方塊函數中處理的一條訊息返回的值 DWL_USER 含義由應用程式規定
也許大家會注意到 GWL_WNDPROC 這個參數。沒錯,我們子類處理就是要用到這個參數。代碼如下:OldProc:=GetWindowLong(hWnd,GWL_WNDPROC);
這樣我們的OldProc就指向表單的視窗函數地址;既然得到了視窗函數地址,那麼就修改到我們自訂的訊息處理地址裡吧。下面要用到SetWindowLong函數了。LONG SetWindowLong( HWND hWnd, //指定視窗控制代碼 int nIndex, //和GetWindowLong的nIndex一樣 LONG dwNewLong //新的訊息處理地址);
代碼如下:SetWindowLong(hWnd,GWL_WNDPROC,Longint(@WinProc));
這樣就把指定表單的訊息轉到了我們的函數內執行;
回呼函數如下:Function WinProc(Hwnd,Msg,wParam,lParam:longint):LRESULT; stdcall;beginResult:=CallWindowProc(OldProc,Hwnd,Msg,wParam,lParam);end;這裡的Msg就是視窗的訊息,後面賦上訊息表。
小節:文章寫到這裡,相信大家應該明白HOOK和子類是什麼回事吧。下面再解釋一下為什麼不在HOOK裡處理訊息。前面已經提到,HOOK是協助我們把DLL注入別人的進程。而Windows子類處理只能在進程內處理訊息,所以只有我們到了別人的進程空間內,才能做出訊息屏蔽的動作。這樣說大家都能明白了吧。
好了,就不廢話了。下面賦上原始碼。希望大家多多支援! ^_^ (複製就可以用的哦)
##########################################################################unit Unit1;
interfaceuses Windows;var OldHook:HHOOK; //用來儲存HOOK的傳回值 OldProc:FARPROC; //用來指向視窗訊息
Function SetHook:Boolean;stdcall; Function HookProc(nCode,wParam,lParam:Integer):Integer;stdcall; Function WinProc(Hwnd,Msg,wParam,lParam:longint):LRESULT; stdcall; implementation{###################################################################################}//安裝HOOKFunction SetHook:Boolean;stdcall;var Histance:Cardinal; begin //安裝HOOK OldHook:=SetWindowsHookEx(WH_KEYBOARD,@HookProc,Histance,0); if (OldHook=0) then exit else Result:=True;end;
{###################################################################################}//HOOK回呼函數Function HookProc(nCode,wParam,lParam:Integer):Integer;stdcall;varWinStr:HWND;begin //設定熱鍵 if (wParam=VK_F12) then begin WinStr:=FindWindow(nil,'視窗的標題文字'); OldProc:=FARPROC(GetWindowLong(WinStr,GWL_WNDPROC)); SetWindowLong(WinStr,GWL_WNDPROC,Longint(@WinProc)); end; //將HOOK傳遞給Windows處理 Result:=CallNextHookEx(OldHook,nCode,wParam,lParam);end;
{###################################################################################}//自訂Windows訊息處理函數Function WinProc(Hwnd,Msg,wParam,lParam:longint):LRESULT; stdcall;begin{在這做出對訊息的處理
case Msg of WM_ACTIVATEAPP:exit; WM_ACTIVATE:exit; WM_KILLFOCUS:exit; WM_SETFOCUS:exit; end;上面這些訊息是視窗失去焦點和獲得焦點的屏蔽}//將視窗訊息傳遞給Windows處理Result:=CallWindowProc(OldProc,Hwnd,Msg,wParam,lParam);end;end.
##########################################################################
附錄:訊息類型(搜集整理於互連網上)
##########################################################################
WM_NULL = $0000; WM_CREATE = $0001; 應用程式建立一個視窗 WM_DESTROY = $0002; 一個視窗被銷毀 WM_MOVE = $0003; 移動一個視窗 WM_SIZE = $0005; 改變一個視窗的大小 WM_ACTIVATE = $0006; 一個視窗被啟用或失去啟用狀態; WM_SETFOCUS = $0007; 獲得焦點後 WM_KILLFOCUS = $0008; 失去焦點 WM_ENABLE = $000A; 改變enable狀態 WM_SETREDRAW = $000B; 設定視窗是否能重畫 WM_SETTEXT = $000C; 應用程式發送此訊息來設定一個視窗的文本 WM_GETTEXT = $000D; 應用程式發送此訊息來複製對應視窗的文本到緩衝區 WM_GETTEXTLENGTH = $000E; 得到與一個視窗有關的文本的長度(不包含Null 字元) WM_PAINT = $000F; 要求一個視窗重畫自己 WM_CLOSE = $0010; 當一個視窗或應用程式要關閉時發送一個訊號 WM_QUERYENDSESSION = $0011; 當使用者選擇結束對話方塊或程式自己調用ExitWindows函數 WM_QUIT = $0012; 用來結束程式運行或當程式調用postquitmessage函數 WM_QUERYOPEN = $0013; 當使用者視窗恢複以前的大小位置時,把此訊息發送給某個表徵圖 WM_ERASEBKGND = $0014; 當視窗背景必須被擦除時(例在視窗改變大小時) WM_SYSCOLORCHANGE = $0015; 當系統色彩改變時,發送此訊息給所有最上層視窗 WM_ENDSESSION = $0016; 當系統進程發出WM_QUERYENDSESSION訊息後,此訊息發送給應用程式, 通知它對話是否結束 WM_SYSTEMERROR = $0017; WM_SHOWWINDOW = $0018; 當隱藏或顯示視窗是發送此訊息給這個視窗 WM_ACTIVATEAPP = $001C; 發此訊息給應用程式哪個視窗是啟用的,哪個是非啟用的; WM_FONTCHANGE = $001D; 當系統的字型資源庫變化時發送此訊息給所有最上層視窗 WM_TIMECHANGE = $001E; 當系統的時間變化時發送此訊息給所有最上層視窗 WM_CANCELMODE = $001F; 發送此訊息來取消某種進行中的摸態(操作) WM_SETCURSOR = $0020; 如果滑鼠引起游標在某個視窗中移動且滑鼠輸入沒有被捕獲時,就發訊息給某個視窗 WM_MOUSEACTIVATE = $0021; 當游標在某個非啟用的視窗中而使用者正按著滑鼠的某個鍵發送此訊息給當前視窗 WM_CHILDACTIVATE = $0022; 發送此訊息給MDI子視窗當使用者點擊此視窗的標題列,或當視窗被啟用,移動,改變大小 WM_QUEUESYNC = $0023; 此訊息由基於電腦的訓練程式發送,通過WH_JOURNALPALYBACK的hook程式 分離出使用者輸入訊息 WM_GETMINMAXINFO = $0024; 此訊息發送給視窗當它將要改變大小或位置; WM_PAINTICON = $0026; 發送給已最小化的視窗當它表徵圖將要被重畫 WM_ICONERASEBKGND = $0027; 此訊息發送給某個已最小化的視窗,僅當它在畫表徵圖前它的背景必須被重畫 WM_NEXTDLGCTL = $0028; 發送此訊息給一個對話方塊程式去更改焦點位置 WM_SPOOLERSTATUS = $002A; 每當列印管理列隊增加或減少一條作業時發出此訊息 WM_DRAWITEM = $002B; 當button,combobox,listbox,menu的可視外觀改變時發送 此訊息給這些空件的所有者 WM_MEASUREITEM = $002C; 當button, combo box, list box, list view control, or menu item 被建立時 發送此訊息給控制項的所有者 WM_DELETEITEM = $002D; 當the list box 或 combo box 被銷毀 或 當 某些項被刪除通過LB_DELETESTRING, LB_RESETCONTENT, CB_DELETESTRING, or CB_RESETCONTENT 訊息 WM_VKEYTOITEM = $002E; 此訊息有一個LBS_WANTKEYBOARDINPUT風格的發出給它的所有者來響應WM_KEYDOWN訊息 WM_CHARTOITEM = $002F; 此訊息由一個LBS_WANTKEYBOARDINPUT風格的列表框發送給他的所有者來響應WM_CHAR訊息 WM_SETFONT = $0030; 當繪製文本時程式發送此訊息得到控制項要用的顏色 WM_GETFONT = $0031; 應用程式發送此訊息得到當前控制項繪製文本的字型 WM_SETHOTKEY = $0032; 應用程式發送此訊息讓一個視窗與一個熱鍵相關連 WM_GETHOTKEY = $0033; 應用程式發送此訊息來判斷熱鍵與某個視窗是否有關聯 WM_QUERYDRAGICON = $0037; 此訊息發送給已最小化的視窗,當此視窗將要被拖放而它的類中沒有定義表徵圖,應用程式能返回一個表徵圖或游標的控制代碼,當使用者拖放表徵圖時系統顯示這個表徵圖或游標 WM_COMPAREITEM = $0039; 發送此訊息來判定combobox或listbox新增加的項的相對位置 WM_GETOBJECT = $003D; WM_COMPACTING = $0041; 顯示記憶體已經很少了 WM_WINDOWPOSCHANGING = $0046; 發送此訊息給那個視窗的大小和位置將要被改變時,來調用setwindowpos函數或其它視窗管理函數 WM_WINDOWPOSCHANGED = $0047; 發送此訊息給那個視窗的大小和位置已經被改變時,來調用setwindowpos函數或其它視窗管理函數 WM_POWER = $0048;(適用於16位的Windows) 當系統將要進入暫停狀態時發送此訊息 WM_COPYDATA = $004A; 當一個應用程式傳遞資料給另一個應用程式時發送此訊息 WM_CANCELJOURNAL = $004B; 當某個使用者取消程式日誌啟用狀態,提交此訊息給程式 WM_NOTIFY = $004E; 當某個控制項的某個事件已經發生或這個控制項需要得到一些資訊時,發送此訊息給它的父視窗 WM_INPUTLANGCHANGEREQUEST = $0050; 當使用者選擇某種輸入語言,或輸入語言的熱鍵改變 WM_INPUTLANGCHANGE = $0051; 當平台現場已經被改變後發送此訊息給受影響的最最上層視窗 WM_TCARD = $0052; 當程式已經初始化Windows協助常式時發送此訊息給應用程式 WM_HELP = $0053; 此訊息顯示使用者按下了F1,如果某個菜單是啟用的,就發送此訊息個此視窗關聯的菜單,否則就 發送給有焦點的視窗,如果當前都沒有焦點,就把此訊息發送給當前啟用的視窗 WM_USERCHANGED = $0054; 當使用者已經登入或退出後發送此訊息給所有的視窗,當使用者登入或退出時系統更新使用者的具體 設定資訊,在使用者更新設定時系統馬上發送此訊息; WM_NOTIFYFORMAT = $0055; 公用控制項,自訂控制項和他們的父視窗通過此訊息來判斷控制項是使用ANSI還是UNICODE結構 在WM_NOTIFY訊息,使用此控制項能使某個控制項與它的父控制項之間進行相互連信 WM_CONTEXTMENU = $007B; 當使用者某個視窗中點擊了一下右鍵就發送此訊息給這個視窗 WM_STYLECHANGING = $007C; 當調用SETWINDOWLONG函數將要改變一個或多個 視窗的風格時發送此訊息給那個視窗 WM_STYLECHANGED = $007D; 當調用SETWINDOWLONG函數一個或多個 視窗的風格後發送此訊息給那個視窗 WM_DISPLAYCHANGE = $007E; 當顯示器的解析度改變後發送此訊息給所有的視窗 WM_GETICON = $007F; 此訊息發送給某個視窗來返回與某個視窗有關連的大表徵圖或小表徵圖的控制代碼; WM_SETICON = $0080; 程式發送此訊息讓一個新的大表徵圖或小表徵圖與某個視窗關聯; WM_NCCREATE = $0081; 當某個視窗第一次被建立時,此訊息在WM_CREATE訊息發送前發送; WM_NCDESTROY = $0082; 此訊息通知某個視窗,非客戶區正在銷毀 WM_NCCALCSIZE = $0083; 當某個視窗的用戶端區域必須被核算時發送此訊息 WM_NCHITTEST = $0084;//移動滑鼠,按住或釋放滑鼠時發生 WM_NCPAINT = $0085; 程式發送此訊息給某個視窗當它(視窗)的架構必須被繪製時; WM_NCACTIVATE = $0086; 此訊息發送給某個視窗 僅當它的非客戶區需要被改變來顯示是啟用還是非啟用狀態; WM_GETDLGCODE = $0087; 發送此訊息給某個與對話方塊程式關聯的控制項,widdows控制方位鍵和TAB鍵使輸入進入此控制項 通過響應WM_GETDLGCODE訊息,應用程式可以把他當成一個特殊的輸入控制項並能處理它 WM_NCMOUSEMOVE = $00A0; 當游標在一個視窗的非客戶區內移動時發送此訊息給這個視窗 //非客戶區為:表單的標題列及窗 的邊框體 WM_NCLBUTTONDOWN = $00A1; 當游標在一個視窗的非客戶區同步選取滑鼠左鍵時提交此訊息 WM_NCLBUTTONUP = $00A2; 當使用者釋放滑鼠左鍵同時游標某個視窗在非客戶區十發送此訊息; WM_NCLBUTTONDBLCLK = $00A3; 當使用者雙擊滑鼠左鍵同時游標某個視窗在非客戶區十發送此訊息 WM_NCRBUTTONDOWN = $00A4; 當使用者按下滑鼠右鍵同時游標又在視窗的非客戶區時發送此訊息 WM_NCRBUTTONUP = $00A5; 當使用者釋放滑鼠右鍵同時游標又在視窗的非客戶區時發送此訊息 WM_NCRBUTTONDBLCLK = $00A6; 當使用者雙擊滑鼠右鍵同時游標某個視窗在非客戶區十發送此訊息 WM_NCMBUTTONDOWN = $00A7; 當使用者按下滑鼠中鍵同時游標又在視窗的非客戶區時發送此訊息 WM_NCMBUTTONUP = $00A8; 當使用者釋放滑鼠中鍵同時游標又在視窗的非客戶區時發送此訊息 WM_NCMBUTTONDBLCLK = $00A9; 當使用者雙擊滑鼠中鍵同時游標又在視窗的非客戶區時發送此訊息 WM_KEYFIRST = $0100; WM_KEYDOWN = $0100; //按下一個鍵 WM_KEYUP = $0101; //釋放一個鍵 WM_CHAR = $0102; //按下某鍵,並已發出WM_KEYDOWN, WM_KEYUP訊息 WM_DEADCHAR = $0103; 當用translatemessage函數翻譯WM_KEYUP訊息時發送此訊息給擁有焦點的視窗 WM_SYSKEYDOWN = $0104; 當使用者按住ALT鍵同步選取其它鍵時提交此訊息給擁有焦點的視窗; WM_SYSKEYUP = $0105; 當使用者釋放一個鍵同時ALT 鍵還按著時提交此訊息給擁有焦點的視窗 WM_SYSCHAR = $0106; 當WM_SYSKEYDOWN訊息被TRANSLATEMESSAGE函數翻譯後提交此訊息給擁有焦點的視窗 WM_SYSDEADCHAR = $0107; 當WM_SYSKEYDOWN訊息被TRANSLATEMESSAGE函數翻譯後發送此訊息給擁有焦點的視窗 WM_KEYLAST = $0108; WM_INITDIALOG = $0110; 在一個對話方塊程式被顯示前發送此訊息給它,通常用此訊息初始化控制項和執行其它任務 WM_COMMAND = $0111; 當使用者選擇一條功能表命令項或當某個控制項發送一條訊息給它的父視窗,一個快速鍵被翻譯 WM_SYSCOMMAND = $0112; 當使用者選擇視窗菜單的一條命令或當使用者選擇最大化或最小化時那個視窗會收到此訊息 WM_TIMER = $0113; //發生了定時器事件 WM_HSCROLL = $0114; 當一個視窗標準水平捲軸產生一個滾動事件時發送此訊息給那個視窗,也發送給擁有它的控制項 WM_VSCROLL = $0115; 當一個視窗標準垂直捲軸產生一個滾動事件時發送此訊息給那個視窗也,發送給擁有它的控制項 WM_INITMENU = $0116; 當一個菜單將要被啟用時發送此訊息,它發生在使用者菜單條中的某項或按下某個菜單鍵,它允許程式在顯示前更改菜單 WM_INITMENUPOPUP = $0117; 當一個下拉式功能表或子功能表將要被啟用時發送此訊息,它允許程式在它顯示前更改菜單,而不要改變全部 WM_MENUSELECT = $011F; 當使用者選擇一條功能表項目時發送此訊息給菜單的所有者(一般是視窗) WM_MENUCHAR = $0120; 當菜單已被啟用使用者按下了某個鍵(不同於加速鍵),發送此訊息給菜單的所有者; WM_ENTERIDLE = $0121; 當一個模態對話方塊或菜單進入空載狀態時發送此訊息給它的所有者,一個模態對話方塊或菜單進入空載狀態就是在處理完一條或幾條先前的訊息後沒有訊息它的列隊中等待 WM_MENURBUTTONUP = $0122; WM_MENUDRAG = $0123; WM_MENUGETOBJECT = $0124; WM_UNINITMENUPOPUP = $0125; WM_MENUCOMMAND = $0126; WM_CHANGEUISTATE = $0127; WM_UPDATEUISTATE = $0128; WM_QUERYUISTATE = $0129; WM_CTLCOLORMSGBOX = $0132; 在Windows繪製訊息框前發送此訊息給訊息框的所有者視窗,通過響應這條訊息,所有者視窗可以通過使用給定的相關顯示裝置的控制代碼來設定訊息框的文本和背景顏色 WM_CTLCOLOREDIT = $0133; 當一個編輯型控制項將要被繪製時發送此訊息給它的父視窗;通過響應這條訊息,所有者視窗可以通過使用給定的相關顯示裝置的控制代碼來設定編輯框的文本和背景顏色 WM_CTLCOLORLISTBOX = $0134; 當一個列表框控制項將要被繪製前發送此訊息給它的父視窗;通過響應這條訊息,所有者視窗可以通過使用給定的相關顯示裝置的控制代碼來設定列表框的文本和背景顏色 WM_CTLCOLORBTN = $0135; 當一個按鈕控制項將要被繪製時發送此訊息給它的父視窗;通過響應這條訊息,所有者視窗可以通過使用給定的相關顯示裝置的控制代碼來設定按紐的文本和背景顏色 WM_CTLCOLORDLG = $0136; 當一個對話方塊控制項將要被繪製前發送此訊息給它的父視窗;通過響應這條訊息,所有者視窗可以通過使用給定的相關顯示裝置的控制代碼來設定對話方塊的文本背景顏色 WM_CTLCOLORSCROLLBAR= $0137; 當一個捲軸控制項將要被繪製時發送此訊息給它的父視窗;通過響應這條訊息,所有者視窗可以通過使用給定的相關顯示裝置的控制代碼來設定捲軸的背景顏色 WM_CTLCOLORSTATIC = $0138; 當一個靜態控制項將要被繪製時發送此訊息給它的父視窗;通過響應這條訊息,所有者視窗可以通過使用給定的相關顯示裝置的控制代碼來設定靜態控制項的文本和背景顏色 WM_MOUSEFIRST = $0200; WM_MOUSEMOVE = $0200; // 移動滑鼠 WM_LBUTTONDOWN = $0201; //按下滑鼠左鍵 WM_LBUTTONUP = $0202; //釋放滑鼠左鍵 WM_LBUTTONDBLCLK = $0203; //雙擊滑鼠左鍵 WM_RBUTTONDOWN = $0204; //按下滑鼠右鍵 WM_RBUTTONUP = $0205; //釋放滑鼠右鍵 WM_RBUTTONDBLCLK = $0206; //雙擊滑鼠右鍵 WM_MBUTTONDOWN = $0207; //按下滑鼠中鍵 WM_MBUTTONUP = $0208; //釋放滑鼠中鍵 WM_MBUTTONDBLCLK = $0209; //雙擊滑鼠中鍵 WM_MOUSEWHEEL = $020A; 當滑鼠輪子轉動時發送此訊息個當前有焦點的控制項 WM_MOUSELAST = $020A; WM_PARENTNOTIFY = $0210; 當MDI子視窗被建立或被銷毀,或使用者按了一下滑鼠鍵而游標在子視窗上時發送此訊息給它的父視窗 WM_ENTERMENULOOP = $0211; 發送此訊息通知應用程式的主視窗that已經進入了菜單迴圈模式 WM_EXITMENULOOP = $0212; 發送此訊息通知應用程式的主視窗that已退出了菜單迴圈模式 WM_NEXTMENU = $0213; WM_SIZING = 532; 當使用者正在調整視窗大小時發送此訊息給視窗;通過此訊息應用程式可以監看式視窗大小和位置也可以修改他們 WM_CAPTURECHANGED = 533; 發送此訊息 給視窗當它失去捕獲的滑鼠時; WM_MOVING = 534; 當使用者在移動視窗時發送此訊息,通過此訊息應用程式可以監看式視窗大小和位置也可以修改他們; WM_POWERBROADCAST = 536; 此訊息發送給應用程式來通知它有關電源管理事件; WM_DEVICECHANGE = 537; 當裝置的硬體設定改變時發送此訊息給應用程式或裝置驅動程式 WM_IME_STARTCOMPOSITION = $010D; WM_IME_ENDCOMPOSITION = $010E; WM_IME_COMPOSITION = $010F; WM_IME_KEYLAST = $010F; WM_IME_SETCONTEXT = $0281; WM_IME_NOTIFY = $0282; WM_IME_CONTROL = $0283; WM_IME_COMPOSITIONFULL = $0284; WM_IME_SELECT = $0285; WM_IME_CHAR = $0286; WM_IME_REQUEST = $0288; WM_IME_KEYDOWN = $0290; WM_IME_KEYUP = $0291; WM_MDICREATE = $0220; 應用程式發送此訊息給多文檔的客戶視窗來建立一個MDI 子視窗 WM_MDIDESTROY = $0221; 應用程式發送此訊息給多文檔的客戶視窗來關閉一個MDI 子視窗 WM_MDIACTIVATE = $0222; 應用程式發送此訊息給多文檔的客戶視窗通知客戶視窗啟用另一個MDI子視窗,當客戶視窗收到此訊息後,它發出WM_MDIACTIVE訊息給MDI子視窗(未啟用)啟用它; WM_MDIRESTORE = $0223; 程式 發送此訊息給MDI客戶視窗讓子視窗從最大最小化恢複到原來大小 WM_MDINEXT = $0224; 程式 發送此訊息給MDI客戶視窗啟用下一個或前一個視窗 WM_MDIMAXIMIZE = $0225; 程式發送此訊息給MDI客戶視窗來最大化一個MDI子視窗; WM_MDITILE = $0226; 程式 發送此訊息給MDI客戶視窗以平鋪方式重新排列所有MDI子視窗 WM_MDICASCADE = $0227; 程式 發送此訊息給MDI客戶視窗以層疊方式重新排列所有MDI子視窗 WM_MDIICONARRANGE = $0228; 程式 發送此訊息給MDI客戶視窗重新排列所有最小化的MDI子視窗 WM_MDIGETACTIVE = $0229; 程式 發送此訊息給MDI客戶視窗來找到啟用的子視窗的控制代碼 WM_MDISETMENU = $0230; 程式 發送此訊息給MDI客戶視窗用MDI菜單代替子視窗的菜單 WM_ENTERSIZEMOVE = $0231; WM_EXITSIZEMOVE = $0232; WM_DROPFILES = $0233; WM_MDIREFRESHMENU = $0234; WM_MOUSEHOVER = $02A1; WM_MOUSELEAVE = $02A3; WM_CUT = $0300; 程式發送此訊息給一個編輯框或combobox來刪除當前選擇的文本 WM_COPY = $0301; 程式發送此訊息給一個編輯框或combobox來複製當前選擇的文本到剪貼簿 WM_PASTE = $0302; 程式發送此訊息給editcontrol或combobox從剪貼簿中得到資料 WM_CLEAR = $0303; 程式發送此訊息給editcontrol或combobox清除當前選擇的內容; WM_UNDO = $0304; 程式發送此訊息給editcontrol或combobox撤消最後一次操作 WM_RENDERFORMAT = $0305;
WM_RENDERALLFORMATS = $0306; WM_DESTROYCLIPBOARD = $0307; 當調用ENPTYCLIPBOARD函數時 發送此訊息給剪貼簿的所有者 WM_DRAWCLIPBOARD = $0308; 當剪貼簿的內容變化時發送此訊息給剪貼簿觀察鏈的第一個視窗;它允許用剪貼簿觀察視窗來 顯示剪貼簿的新內容; WM_PAINTCLIPBOARD = $0309; 當剪貼簿包含CF_OWNERDIPLAY格式的資料並且剪貼簿觀察視窗的客戶區需要重畫; WM_VSCROLLCLIPBOARD = $030A; WM_SIZECLIPBOARD = $030B; 當剪貼簿包含CF_OWNERDIPLAY格式的資料並且剪貼簿觀察視窗的用戶端區域的大小已經改變是此訊息通過剪貼簿觀察視窗發送給剪貼簿的所有者; WM_ASKCBFORMATNAME = $030C; 通過剪貼簿觀察視窗發送此訊息給剪貼簿的所有者來請求一個CF_OWNERDISPLAY格式的剪貼簿的名字 WM_CHANGECBCHAIN = $030D; 當一個視窗從剪貼簿觀察鏈中移去時發送此訊息給剪貼簿觀察鏈的第一個視窗; WM_HSCROLLCLIPBOARD = $030E; 此訊息通過一個剪貼簿觀察視窗發送給剪貼簿的所有者 ;它發生在當剪貼簿包含CFOWNERDISPALY格式的資料並且有個事件在剪貼簿觀察窗的水平捲軸上;所有者應滾動剪貼簿圖象並更新捲軸的值; WM_QUERYNEWPALETTE = $030F; 此訊息發送給將要收到焦點的視窗,此訊息能使視窗在收到焦點時同時有機會實現他的邏輯調色盤 WM_PALETTEISCHANGING= $0310; 當一個應用程式正要實現它的邏輯調色盤時發此訊息通知所有的應用程式 WM_PALETTECHANGED = $0311; 此訊息在一個擁有焦點的視窗實現它的邏輯調色盤後發送此訊息給所有頂級並重疊的視窗,以此來改變系統調色盤 WM_HOTKEY = $0312; 當使用者按下由REGISTERHOTKEY函數註冊的熱鍵時提交此訊息 WM_PRINT = 791; 應用程式發送此訊息僅當Windows或其它應用程式發出一個請求要求繪製一個應用程式的一部分; WM_PRINTCLIENT = 792; WM_HANDHELDFIRST = 856; WM_HANDHELDLAST = 863; WM_PENWINFIRST = $0380; WM_PENWINLAST = $038F; WM_COALESCE_FIRST = $0390; WM_COALESCE_LAST = $039F; WM_DDE_FIRST = $03E0; WM_DDE_INITIATE = WM_DDE_FIRST + 0; 一個DDE客戶程式提交此訊息開始一個與伺服器程式的會話來響應那個指定的程式和主題名; WM_DDE_TERMINATE = WM_DDE_FIRST + 1; 一個DDE應用程式(無論是客戶還是伺服器)提交此訊息來終止一個會話; WM_DDE_ADVISE = WM_DDE_FIRST + 2; 一個DDE客戶程式提交此訊息給一個DDE服務程式來請求伺服器每當資料項目改變時更新它 WM_DDE_UNADVISE = WM_DDE_FIRST + 3; 一個DDE客戶程式通過此訊息通知一個DDE服務程式不更新指定的項或一個特殊的剪貼簿格式的項 WM_DDE_ACK = WM_DDE_FIRST + 4; 此訊息通知一個DDE(動態資料交換)程式已收到並正在處理WM_DDE_POKE, WM_DDE_EXECUTE, WM_DDE_DATA, WM_DDE_ADVISE, WM_DDE_UNADVISE, or WM_DDE_INITIAT訊息 WM_DDE_DATA = WM_DDE_FIRST + 5; 一個DDE服務程式提交此訊息給DDE客戶程式來傳遞個一資料項目給客戶或通知客戶的一條可用資料項目 WM_DDE_REQUEST = WM_DDE_FIRST + 6; 一個DDE客戶程式提交此訊息給一個DDE服務程式來請求一個資料項目的值; WM_DDE_POKE = WM_DDE_FIRST + 7; 一個DDE客戶程式提交此訊息給一個DDE服務程式,客戶使用此訊息來請求伺服器接收一個未經同意的資料項目;伺服器通過回覆WM_DDE_ACK訊息提示是否它接收這個資料項目; WM_DDE_EXECUTE = WM_DDE_FIRST + 8; 一個DDE客戶程式提交此訊息給一個DDE服務程式來發送一個字串給伺服器讓它象串列命令一樣被處理,伺服器通過提交WM_DDE_ACK訊息來作回應; WM_DDE_LAST = WM_DDE_FIRST + 8; WM_APP = $8000; WM_USER = $0400; 此訊息能輔助應用程式自訂私人訊息; ///////////////////////////////////////////////////////////////////// 通知訊息(Notification message)是指這樣一種訊息,一個視窗內的子控制項發生了一些事情,需要通知父視窗。通知訊息只適用於標準的視窗控制項如按鈕、列表框、組合框、編輯框,以及Windows 95公用控制項如樹狀檢視、列表視圖等。例如,單擊或雙擊一個控制項、在控制項中選擇部分文本、操作控制項的捲軸都會產生通知訊息。 按扭 B N _ C L I C K E D //使用者單擊了按鈕 B N _ D I S A B L E //按鈕被禁止 B N _ D O U B L E C L I C K E D //使用者雙擊了按鈕 B N _ H I L I T E //使用者加亮了按鈕 B N _ PA I N T按鈕應當重畫 B N _ U N H I L I T E加亮應當去掉 組合框 C B N _ C L O S E U P組合框的列表框被關閉 C B N _ D B L C L K使用者雙擊了一個字串 C B N _ D R O P D O W N組合框的列表框被拉出 C B N _ E D I T C H A N G E使用者修改了編輯框中的文本 C B N _ E D I T U P D AT E編輯框內的文本即將更新 C B N _ E R R S PA C E組合框記憶體不足 C B N _ K I L L F O C U S組合框失去輸入焦點 C B N _ S E L C H A N G E在組合框中選擇了一項 C B N _ S E L E N D C A N C E L使用者的選擇應當被取消 C B N _ S E L E N D O K使用者的選擇是合法的 C B N _ S E T F O C U S組合框獲得輸入焦點 編輯框 E N _ C H A N G E編輯框中的文本己更新 E N _ E R R S PA C E編輯框記憶體不足 E N _ H S C R O L L使用者點擊了水平捲軸 E N _ K I L L F O C U S編輯框正在失去輸入焦點 E N _ M A X T E X T插入的內容被截斷 E N _ S E T F O C U S編輯框獲得輸入焦點 E N _ U P D AT E編輯框中的文本將要更新 E N _ V S C R O L L使用者點擊了垂直捲軸訊息含義 列表框 L B N _ D B L C L K使用者雙擊了一項 L B N _ E R R S PA C E列表框記憶體不夠 L B N _ K I L L F O C U S列表框正在失去輸入焦點 L B N _ S E L C A N C E L選擇被取消 L B N _ S E L C H A N G E選擇了另一項 L B N _ S E T F O C U S列表框獲得輸入焦點
##########################################################################