書小宅之C#——平臺調用Win32 API來說明託管和非託管

Win 32 API參考大全網盤鏈接
提取碼:aove

.NET平臺下實現互操作性有三種技術:

1、平臺調用:主要用於調用C庫函數和Windows API;
2、C++ Interop:主要用於Managed C++(託管C++)中調用C++類庫;
3、COM Interop:主要用於在.NET中調用COM組件和在COM中使用.NET程序集。

平臺調用:可以幫助我們實現在.NET平臺下(也就是指用C#、VB.net語言寫的應用程序下)用託管代碼調用動態鏈接庫(Dll),實現非託管函數(指定的是C/C++語言寫的函數)的調用——“拿來主義”。

如.NET類庫中沒有提供相關API然而Win32 API 中提供了相關的函數實現時可以在.NET程序中調用Win32 API 。

實現步驟如下(具體的方式本文有更詳細介紹):

1、 獲得非託管函數的信息,即dll的名稱,需要調用的非託管函數名等信息。
2、在託管代碼中對非託管函數進行聲明,並且附加平臺調用所需要屬性。
3、在託管代碼中直接調用第二步中聲明的託管函數

Visual Studio自帶兩個工具:
dumpbin.exe :可以用於查看從非託管DLL中導出的函數等信息的命令行工具。
depends.exe:可視化界面工具。

數據封送 是——在託管代碼中對非託管函數進行互操作時,需要通過方法的參數和返回值在託管內存和非託管內存之間傳遞數據的過程,數據封送處理的過程是由CLR(公共語言運行時)的封送處理服務(即封送拆送器)完成的。

可直接複製到本機結構中的類型【blittable】: 在託管內存和非託管內存中有相同表現形式的數據類型。

Windows數據類型 非託管數據類型 託管數據類型 託管數據解釋
BYTE/Uchar/UInt8 unsigned char System.Byte 無符號8位整型
Sbyte/Char/Int8 char System.SByte 有符號8位整型
Short/Int16 short System.Int16 有符號16位整型
USHORT/WORD/UInt16/WCHAR unsigned short System.UInt16 無符號16位整型
Bool/HResult/Int/Long long/int System.Int32 有符號32位整型
DWORD/ULONG/UINT unsigned long/unsigned int System.UInt32 無符號32位整型
INT64/LONGLONG _int64 System.Int64 有符號64位整型
UINT64/DWORDLONG/ULONGLONG _uint64 System.UInt64 無符號64位整型
INT_PTR/hANDLE/wPARAM void*/int或_int64 System.IntPtr 有符號指針類型
HANDLE void* System.UIntPtr 無符號指針類型
FLOAT float System.Single 單精度浮點數
DOUBLE double System.Double 雙精度浮點數

不是可直接複製到本機結構中的類型【non-blittable】: 由於一些類型在託管內存和非託管內存的表現形式不一樣,所以對於這種類型,封送器需要對它們進行相應的類型轉換之後再複製到被調用的函數中。

Windows 數據類型 非託管數據類型 託管數據類型
Bool bool System.Boolean
WCHAR/TCHAR char/ wchar_t System.Char
LPCSTR/LPCWSTR/LPCTSTR/LPSTR/LPWSTR/LPTSTR const char*/const wchar_t*/char*/wchar_t* System.String
LPSTR/LPWSTR/LPTSTR Char*/wchar_t* System.StringBuilder

託管代碼中定義函數原型

爲了在託管代碼中調用非託管代碼,首先我們就要知道非託管函數的定義。
如Win32 GetTempPath函數定義如下:

DWORD WINAPI GetTempPath(
	_In_   DWORD nBufferLength,
	_Out_  LPTSTR lpBuffer
);  

如果在非託管函數的定義裏參數的數據類型是結構體,我們也需要知道這個結構體對應的原始類型。把結構體對象作爲非託管函數參數,我們就需要在託管代碼中定義一個等價的結構,並且要保證兩個結構體在內存中的佈局相同。
託管代碼中定義的結構體有以下三個方面與非託管代碼中的結構體是相同的:

1、字段聲明的順序;
2、字段的類型;
3、字段在內存中的大小。

舉例如下:

// 下面的結構體也屬於可直接複製到本機結構中的類型
//[StructLayout(LayoutKind.Explicit)]
//[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
[StructLayout(LayoutKind.Sequential)]
public struct Point {
   public int x;
   public int y;
}   

StructLayout 屬性的作用就是 允許開發人員顯式指定結構體或類中數據字段的內存佈局,爲了保證結構體中的數據字段在內存中的順序與定義時一致,所以指定爲 LayoutKind.Sequential(該枚舉也是默認值)。

DllImport會按照順序自動去尋找的地方如下,只需要把引用的DLL 拷貝到這三個目錄下,就可以不用寫路徑了。:

1、exe所在目錄
2、System32目錄
3、環境變量目錄

DllImport是System.Runtime.InteropServices命名空間下的一個屬性類,其功能是提供從非託管DLL導出的函數的必要調用信息。 DllImport屬性應用於方法,要求最少要提供包含入口點的dll的名稱。

using System.Runtime.InteropServices;
//對GetTempPath進行託管定義
[DllImport("Kernel32.dll", EntryPoint = "GetTempPath", CharSet = CharSet.Unicode, SetLastError=true,ExactSpelling = true)]
public static extern uint GetTempPath(int bufferLength, StringBuilder buffer);

託管函數中聲明注意一定要加上 static 和extern 這兩個關鍵字。

如果參數的數據類型是結構體類型的,如定義了結構體OSVersionInfo,則 爲了傳遞指向結構體的指針並將初始化的信息傳遞給非託管代碼,需要用ref關鍵字修飾參數 , ref關鍵字標識傳入指針
ref不能使用out關鍵字,如果使用了out關鍵字,CLR【公共語言運行時】就不會對參數進行初始化操作,這樣就會導致調用失敗。

[DllImport("Kernel32",CharSet=CharSet.Unicode,EntryPoint="GetVersionEx")]
private static extern Boolean GetVersionEx_Struct(ref  OSVersionInfo osVersionInfo);

類類型是引用類型,也不能用ref關鍵字。
**[in]:**函數調用前先初始化,非託管代碼能夠獲得在託管代碼中對象設置的初始值(如osVersionInfo)。
**[out]:**函數返回時,將結果複製到託管對象中。

[DllImport("Kernel32", CharSet = CharSet.Unicode, EntryPoint = "GetVersionEx")]
private static extern Boolean GetVersionEx_Struct([In, Out]  OSVersionInfo osVersionInfo);

命名參數說明:

1、EntryPoint 參數給出 dll 中入口點的名稱。未指定則使用方法本身的名稱。
2、CharSet 參數指示用在入口點中的字符集。未指定則使用默認值CharSet.Auto。 (CharSet.Ansi)(平臺調用和非託管內存中字符串編碼不同,會出現亂碼【每個字符佔的字節數不同】)。設置爲CharSet.Auto,則平臺調用會針對目標操作系統適當地自動封送字符串。
3、ExactSpelling 參數指示 EntryPoint 是否必須與指示的入口點的拼寫完全匹配。未指定則使用默認值 false。
4、PreserveSig 參數指示方法的簽名應當被保留還是被轉換。當簽名被轉換時,它被轉換爲一個具有 HRESULT 返回值和該返回值的一個名爲 retval 的附加輸出參數的簽名。未指定則使用默認值 true。
5、SetLastError 參數指示方法是否保留 Win32"上一錯誤"。未指定則使用默認值 false。
6、CallingConvention 參數指示入口點的調用約定。未指定則使用默認值 CallingConvention.Winapi。

託管代碼寫好後,直接在需要的地方傳參調用即可。

Windows API

public static int WM_CHAR = 0x102;
public static int WM_CLICK = 0x00F5;

[DllImport("user32.dll")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
public static extern int AnyPopup();

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

[DllImport("user32.dll")]
public static extern int EnumThreadWindows(IntPtr dwThreadId, CallBack lpfn, int lParam);

[DllImport("user32.dll")]
public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);

[DllImport("user32.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr PostMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);

[DllImport("user32.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr SendMessageA(IntPtr hwnd, int wMsg, int wParam, int lParam);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int GetWindowTextLength(IntPtr hWnd);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr GetParent(IntPtr hWnd);
public delegate bool CallBack(IntPtr hwnd, int lParam);

[DllImport("user32.dll ", EntryPoint = "GetDlgItem")]
//第一個參數就是窗體的句柄,第二個參數就是控件ID。
public static extern IntPtr GetDlgItem(IntPtr hParent, int nIDParentItem);

[DllImport("user32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public extern static IntPtr SetParent(IntPtr hChild, IntPtr hParent);

[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndlnsertAfter, int X, int Y, int cx, int cy, uint Flags);

[DllImport("user32.dll", EntryPoint = "ShowWindow")]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);

[DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
 //創建一個窗口   
        const int WM_CREATE = 0x01;
        //當一個窗口被破壞時發送   
        const int WM_DESTROY = 0x02;
        //移動一個窗口   
        const int WM_MOVE = 0x03;
        //改變一個窗口的大小   
        const int WM_SIZE = 0x05;
        //一個窗口被激活或失去激活狀態   
        const int WM_ACTIVATE = 0x06;
        //一個窗口獲得焦點   
        const int WM_SETFOCUS = 0x07;
        //一個窗口失去焦點   
        const int WM_KILLFOCUS = 0x08;
        //一個窗口改變成Enable狀態   
        const int WM_ENABLE = 0x0A;
        //設置窗口是否能重畫   
        const int WM_SETREDRAW = 0x0B;
        //應用程序發送此消息來設置一個窗口的文本   
        const int WM_SETTEXT = 0x0C;
        //應用程序發送此消息來複制對應窗口的文本到緩衝區   
        const int WM_GETTEXT = 0x0D;
        //得到與一個窗口有關的文本的長度(不包含空字符)   
        const int WM_GETTEXTLENGTH = 0x0E;
        //要求一個窗口重畫自己   
        const int WM_PAINT = 0x0F;
        //當一個窗口或應用程序要關閉時發送一個信號   
        public const int WM_CLOSE = 0x10;
        //當用戶選擇結束對話框或程序自己調用ExitWindows函數   
        const int WM_QUERYENDSESSION = 0x11;
        //用來結束程序運行   
        const int WM_QUIT = 0x12;
        //當用戶窗口恢復以前的大小位置時,把此消息發送給某個圖標   
        const int WM_QUERYOPEN = 0x13;
        //當窗口背景必須被擦除時(例在窗口改變大小時)   
        const int WM_ERASEBKGND = 0x14;
        //當系統顏色改變時,發送此消息給所有頂級窗口   
        const int WM_SYSCOLORCHANGE = 0x15;
        //當系統進程發出WM_QUERYENDSESSION消息後,此消息發送給應用程序,通知它對話是否結束   
        const int WM_ENDSESSION = 0x16;
        //當隱藏或顯示窗口是發送此消息給這個窗口   
        const int WM_SHOWWINDOW = 0x18;
        //發此消息給應用程序哪個窗口是激活的,哪個是非激活的   
        const int WM_ACTIVATEAPP = 0x1C;
        //當系統的字體資源庫變化時發送此消息給所有頂級窗口   
        const int WM_FONTCHANGE = 0x1D;
        //當系統的時間變化時發送此消息給所有頂級窗口   
        const int WM_TIMECHANGE = 0x1E;
        //發送此消息來取消某種正在進行的摸態(操作)   
        const int WM_CANCELMODE = 0x1F;
        //如果鼠標引起光標在某個窗口中移動且鼠標輸入沒有被捕獲時,就發消息給某個窗口   
        const int WM_SETCURSOR = 0x20;
        //當光標在某個非激活的窗口中而用戶正按着鼠標的某個鍵發送此消息給//當前窗口   
        const int WM_MOUSEACTIVATE = 0x21;
        //發送此消息給MDI子窗口//當用戶點擊此窗口的標題欄,或//當窗口被激活,移動,改變大小   
        const int WM_CHILDACTIVATE = 0x22;
        //此消息由基於計算機的訓練程序發送,通過WH_JOURNALPALYBACK的hook程序分離出用戶輸入消息   
        const int WM_QUEUESYNC = 0x23;
        //此消息發送給窗口當它將要改變大小或位置   
        const int WM_GETMINMAXINFO = 0x24;
        //發送給最小化窗口當它圖標將要被重畫   
        const int WM_PAINTICON = 0x26;
        //此消息發送給某個最小化窗口,僅//當它在畫圖標前它的背景必須被重畫   
        const int WM_ICONERASEBKGND = 0x27;
        //發送此消息給一個對話框程序去更改焦點位置   
        const int WM_NEXTDLGCTL = 0x28;
        //每當打印管理列隊增加或減少一條作業時發出此消息    
        const int WM_SPOOLERSTATUS = 0x2A;
        //當button,combobox,listbox,menu的可視外觀改變時發送   
        const int WM_DRAWITEM = 0x2B;
        //當button, combo box, list box, list view control, or menu item 被創建時   
        const int WM_MEASUREITEM = 0x2C;
        //此消息有一個LBS_WANTKEYBOARDINPUT風格的發出給它的所有者來響應WM_KEYDOWN消息    
        const int WM_VKEYTOITEM = 0x2E;
        //此消息由一個LBS_WANTKEYBOARDINPUT風格的列表框發送給他的所有者來響應WM_CHAR消息    
        const int WM_CHARTOITEM = 0x2F;
        //當繪製文本時程序發送此消息得到控件要用的顏色   
        const int WM_SETFONT = 0x30;
        //應用程序發送此消息得到當前控件繪製文本的字體   
        const int WM_GETFONT = 0x31;
        //應用程序發送此消息讓一個窗口與一個熱鍵相關連    
        const int WM_SETHOTKEY = 0x32;
        //應用程序發送此消息來判斷熱鍵與某個窗口是否有關聯   
        const int WM_GETHOTKEY = 0x33;
        //此消息發送給最小化窗口,當此窗口將要被拖放而它的類中沒有定義圖標,應用程序能返回一個圖標或光標的句柄,當用戶拖放圖標時系統顯示這個圖標或光標   
        const int WM_QUERYDRAGICON = 0x37;
        //發送此消息來判定combobox或listbox新增加的項的相對位置   
        const int WM_COMPAREITEM = 0x39;
        //顯示內存已經很少了   
        const int WM_COMPACTING = 0x41;
        //發送此消息給那個窗口的大小和位置將要被改變時,來調用setwindowpos函數或其它窗口管理函數   
        const int WM_WINDOWPOSCHANGING = 0x46;
        //發送此消息給那個窗口的大小和位置已經被改變時,來調用setwindowpos函數或其它窗口管理函數   
        const int WM_WINDOWPOSCHANGED = 0x47;
        //當系統將要進入暫停狀態時發送此消息   
        const int WM_POWER = 0x48;
        //當一個應用程序傳遞數據給另一個應用程序時發送此消息   
        const int WM_COPYDATA = 0x4A;
        //當某個用戶取消程序日誌激活狀態,提交此消息給程序   
        const int WM_CANCELJOURNA = 0x4B;
        //當某個控件的某個事件已經發生或這個控件需要得到一些信息時,發送此消息給它的父窗口    
        const int WM_NOTIFY = 0x4E;
        //當用戶選擇某種輸入語言,或輸入語言的熱鍵改變   
        const int WM_INPUTLANGCHANGEREQUEST = 0x50;
        //當平臺現場已經被改變後發送此消息給受影響的最頂級窗口   
        const int WM_INPUTLANGCHANGE = 0x51;
        //當程序已經初始化windows幫助例程時發送此消息給應用程序   
        const int WM_TCARD = 0x52;
        //此消息顯示用戶按下了F1,如果某個菜單是激活的,就發送此消息個此窗口關聯的菜單,否則就發送給有焦點的窗口,如果//當前都沒有焦點,就把此消息發送給//當前激活的窗口   
        const int WM_HELP = 0x53;
        //當用戶已經登入或退出後發送此消息給所有的窗口,//當用戶登入或退出時系統更新用戶的具體設置信息,在用戶更新設置時系統馬上發送此消息   
        const int WM_USERCHANGED = 0x54;
        //公用控件,自定義控件和他們的父窗口通過此消息來判斷控件是使用ANSI還是UNICODE結構   
        const int WM_NOTIFYFORMAT = 0x55;
        //當用戶某個窗口中點擊了一下右鍵就發送此消息給這個窗口   
        //const int WM_CONTEXTMENU = ??;   
        //當調用SETWINDOWLONG函數將要改變一個或多個 窗口的風格時發送此消息給那個窗口   
        const int WM_STYLECHANGING = 0x7C;
        //當調用SETWINDOWLONG函數一個或多個 窗口的風格後發送此消息給那個窗口   
        const int WM_STYLECHANGED = 0x7D;
        //當顯示器的分辨率改變後發送此消息給所有的窗口   
        const int WM_DISPLAYCHANGE = 0x7E;
        //此消息發送給某個窗口來返回與某個窗口有關連的大圖標或小圖標的句柄   
        const int WM_GETICON = 0x7F;
        //程序發送此消息讓一個新的大圖標或小圖標與某個窗口關聯   
        const int WM_SETICON = 0x80;
        //當某個窗口第一次被創建時,此消息在WM_CREATE消息發送前發送   
        const int WM_NCCREATE = 0x81;
        //此消息通知某個窗口,非客戶區正在銷燬    
        const int WM_NCDESTROY = 0x82;
        //當某個窗口的客戶區域必須被覈算時發送此消息   
        const int WM_NCCALCSIZE = 0x83;
        //移動鼠標,按住或釋放鼠標時發生   
        const int WM_NCHITTEST = 0x84;
        //程序發送此消息給某個窗口當它(窗口)的框架必須被繪製時   
        const int WM_NCPAINT = 0x85;
        //此消息發送給某個窗口僅當它的非客戶區需要被改變來顯示是激活還是非激活狀態   
        const int WM_NCACTIVATE = 0x86;
        //發送此消息給某個與對話框程序關聯的控件,widdows控制方位鍵和TAB鍵使輸入進入此控件通過應   
        const int WM_GETDLGCODE = 0x87;
        //當光標在一個窗口的非客戶區內移動時發送此消息給這個窗口 非客戶區爲:窗體的標題欄及窗 的邊框體   
        const int WM_NCMOUSEMOVE = 0xA0;
        //當光標在一個窗口的非客戶區同時按下鼠標左鍵時提交此消息   
        const int WM_NCLBUTTONDOWN = 0xA1;
        //當用戶釋放鼠標左鍵同時光標某個窗口在非客戶區十發送此消息    
        const int WM_NCLBUTTONUP = 0xA2;
        //當用戶雙擊鼠標左鍵同時光標某個窗口在非客戶區十發送此消息   
        const int WM_NCLBUTTONDBLCLK = 0xA3;
        //當用戶按下鼠標右鍵同時光標又在窗口的非客戶區時發送此消息   
        const int WM_NCRBUTTONDOWN = 0xA4;
        //當用戶釋放鼠標右鍵同時光標又在窗口的非客戶區時發送此消息   
        const int WM_NCRBUTTONUP = 0xA5;
        //當用戶雙擊鼠標右鍵同時光標某個窗口在非客戶區十發送此消息   
        const int WM_NCRBUTTONDBLCLK = 0xA6;
        //當用戶按下鼠標中鍵同時光標又在窗口的非客戶區時發送此消息   
        const int WM_NCMBUTTONDOWN = 0xA7;
        //當用戶釋放鼠標中鍵同時光標又在窗口的非客戶區時發送此消息   
        const int WM_NCMBUTTONUP = 0xA8;
        //當用戶雙擊鼠標中鍵同時光標又在窗口的非客戶區時發送此消息   
        const int WM_NCMBUTTONDBLCLK = 0xA9;
        //WM_KEYDOWN 按下一個鍵   
        const int WM_KEYDOWN = 0x0100;
        //釋放一個鍵   
        const int WM_KEYUP = 0x0101;
        //按下某鍵,並已發出WM_KEYDOWN, WM_KEYUP消息   
        const int WM_CHAR = 0x102;
        //當用translatemessage函數翻譯WM_KEYUP消息時發送此消息給擁有焦點的窗口   
        const int WM_DEADCHAR = 0x103;
        //當用戶按住ALT鍵同時按下其它鍵時提交此消息給擁有焦點的窗口   
        const int WM_SYSKEYDOWN = 0x104;
        //當用戶釋放一個鍵同時ALT 鍵還按着時提交此消息給擁有焦點的窗口   
        const int WM_SYSKEYUP = 0x105;
        //當WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函數翻譯後提交此消息給擁有焦點的窗口   
        const int WM_SYSCHAR = 0x106;
        //當WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函數翻譯後發送此消息給擁有焦點的窗口   
        const int WM_SYSDEADCHAR = 0x107;
        //在一個對話框程序被顯示前發送此消息給它,通常用此消息初始化控件和執行其它任務   
        const int WM_INITDIALOG = 0x110;
        //當用戶選擇一條菜單命令項或當某個控件發送一條消息給它的父窗口,一個快捷鍵被翻譯   
        const int WM_COMMAND = 0x111;
        //當用戶選擇窗口菜單的一條命令或//當用戶選擇最大化或最小化時那個窗口會收到此消息   
        const int WM_SYSCOMMAND = 0x112;
        //發生了定時器事件   
        const int WM_TIMER = 0x113;
        //當一個窗口標準水平滾動條產生一個滾動事件時發送此消息給那個窗口,也發送給擁有它的控件   
        const int WM_HSCROLL = 0x114;
        //當一個窗口標準垂直滾動條產生一個滾動事件時發送此消息給那個窗口也,發送給擁有它的控件   
        const int WM_VSCROLL = 0x115;
        //當一個菜單將要被激活時發送此消息,它發生在用戶菜單條中的某項或按下某個菜單鍵,它允許程序在顯示前更改菜單   
        const int WM_INITMENU = 0x116;
        //當一個下拉菜單或子菜單將要被激活時發送此消息,它允許程序在它顯示前更改菜單,而不要改變全部   
        const int WM_INITMENUPOPUP = 0x117;
        //當用戶選擇一條菜單項時發送此消息給菜單的所有者(一般是窗口)   
        const int WM_MENUSELECT = 0x11F;
        //當菜單已被激活用戶按下了某個鍵(不同於加速鍵),發送此消息給菜單的所有者   
        const int WM_MENUCHAR = 0x120;
        //當一個模態對話框或菜單進入空載狀態時發送此消息給它的所有者,一個模態對話框或菜單進入空載狀態就是在處理完一條或幾條先前的消息後沒有消息它的列隊中等待   
        const int WM_ENTERIDLE = 0x121;
        //在windows繪製消息框前發送此消息給消息框的所有者窗口,通過響應這條消息,所有者窗口可以通過使用給定的相關顯示設備的句柄來設置消息框的文本和背景顏色   
        const int WM_CTLCOLORMSGBOX = 0x132;
        //當一個編輯型控件將要被繪製時發送此消息給它的父窗口通過響應這條消息,所有者窗口可以通過使用給定的相關顯示設備的句柄來設置編輯框的文本和背景顏色   
        const int WM_CTLCOLOREDIT = 0x133;

        //當一個列表框控件將要被繪製前發送此消息給它的父窗口通過響應這條消息,所有者窗口可以通過使用給定的相關顯示設備的句柄來設置列表框的文本和背景顏色   
        const int WM_CTLCOLORLISTBOX = 0x134;
        //當一個按鈕控件將要被繪製時發送此消息給它的父窗口通過響應這條消息,所有者窗口可以通過使用給定的相關顯示設備的句柄來設置按紐的文本和背景顏色   
        const int WM_CTLCOLORBTN = 0x135;
        //當一個對話框控件將要被繪製前發送此消息給它的父窗口通過響應這條消息,所有者窗口可以通過使用給定的相關顯示設備的句柄來設置對話框的文本背景顏色   
        const int WM_CTLCOLORDLG = 0x136;
        //當一個滾動條控件將要被繪製時發送此消息給它的父窗口通過響應這條消息,所有者窗口可以通過使用給定的相關顯示設備的句柄來設置滾動條的背景顏色   
        const int WM_CTLCOLORSCROLLBAR = 0x137;
        //當一個靜態控件將要被繪製時發送此消息給它的父窗口通過響應這條消息,所有者窗口可以 通過使用給定的相關顯示設備的句柄來設置靜態控件的文本和背景顏色   
        const int WM_CTLCOLORSTATIC = 0x138;
        //當鼠標輪子轉動時發送此消息個當前有焦點的控件   
        const int WM_MOUSEWHEEL = 0x20A;
        //雙擊鼠標中鍵   
        const int WM_MBUTTONDBLCLK = 0x209;
        //釋放鼠標中鍵   
        const int WM_MBUTTONUP = 0x208;
        //移動鼠標時發生,同WM_MOUSEFIRST   
        const int WM_MOUSEMOVE = 0x200;
        //按下鼠標左鍵   
        const int WM_LBUTTONDOWN = 0x201;
        //釋放鼠標左鍵   
        const int WM_LBUTTONUP = 0x202;
        //雙擊鼠標左鍵   
        const int WM_LBUTTONDBLCLK = 0x203;
        //按下鼠標右鍵   
        const int WM_RBUTTONDOWN = 0x204;
        //釋放鼠標右鍵   
        const int WM_RBUTTONUP = 0x205;
        //雙擊鼠標右鍵   
        const int WM_RBUTTONDBLCLK = 0x206;
        //按下鼠標中鍵   
        const int WM_MBUTTONDOWN = 0x207;

        const int WM_USER = 0x0400;
        const int MK_LBUTTON = 0x0001;
        const int MK_RBUTTON = 0x0002;
        const int MK_SHIFT = 0x0004;
        const int MK_CONTROL = 0x0008;
        const int MK_MBUTTON = 0x0010;
        const int MK_XBUTTON1 = 0x0020;
        const int MK_XBUTTON2 = 0x0040;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章