如何在 Visual C# .NET 中設定 Windows 勾點

文章翻譯 文章翻譯
文章編號: 318804 - 檢視此文章適用的產品。
如需本文的 Microsoft Visual Basic 版本,請參閱 319524
全部展開 | 全部摺疊

在此頁中

簡介

本文將以滑鼠勾點作為範例,告訴您如何設定執行緒及勾點程序特定的勾點。您可以使用勾點監視某些類型的事件。您可以建立這些事件與特定執行緒的關聯,或是將相同桌面中所有執行緒當作一個呼叫執行緒,建立這些事件與該執行緒的關聯。

其他相關資訊

設定滑鼠勾點

如果要設定勾點,請呼叫 User32.dll 檔的 SetWindowsHookEx 函式。這個函式會在與勾點關聯的勾點鏈結中安裝應用程式定義的勾點程序。

如果要設定滑鼠勾點及監視滑鼠事件,請依照下列步驟執行:
  1. 啟動 Microsoft Visual Studio .NET。
  2. [檔案] 功能表上,指向 [新增],再按一下 [專案]
  3. [新增專案] 對話方塊中,按一下 [專案類型] 下方的 [Visual C# 專案],然後按一下 [範本] 下方的 [Windows 應用程式]。在 [名稱] 方塊中,輸入 ThreadSpecificMouseHook。根據預設,會建立名為 Form1 的表單。
  4. 在 Form1.cs 檔中的其他 using 陳述式後加入下一行程式碼。
    using System.Runtime.InteropServices;
  5. Form1 類別中加入下列程式碼。
    public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
    
    //Declare the hook handle as an int.
    static int hHook = 0;
    
    //Declare the mouse hook constant.
    //For other hook types, you can obtain these values from Winuser.h in the Microsoft SDK.
    public const int WH_MOUSE = 7;
    private System.Windows.Forms.Button button1;
    
    //Declare MouseHookProcedure as a HookProc type.
    HookProc MouseHookProcedure;			
    
    //Declare the wrapper managed POINT class.
    [StructLayout(LayoutKind.Sequential)]
    public class POINT 
    {
    	public int x;
    	public int y;
    }
    
    //Declare the wrapper managed MouseHookStruct class.
    [StructLayout(LayoutKind.Sequential)]
    public class MouseHookStruct 
    {
    	public POINT pt;
    	public int hwnd;
    	public int wHitTestCode;
    	public int dwExtraInfo;
    }
    
    //This is the Import for the SetWindowsHookEx function.
    //Use this function to install a thread-specific hook.
    [DllImport("user32.dll",CharSet=CharSet.Auto,
     CallingConvention=CallingConvention.StdCall)]
    public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, 
    IntPtr hInstance, int threadId);
    
    //This is the Import for the UnhookWindowsHookEx function.
    //Call this function to uninstall the hook.
    [DllImport("user32.dll",CharSet=CharSet.Auto,
     CallingConvention=CallingConvention.StdCall)]
    public static extern bool UnhookWindowsHookEx(int idHook);
    		
    //This is the Import for the CallNextHookEx function.
    //Use this function to pass the hook information to the next hook procedure in chain.
    [DllImport("user32.dll",CharSet=CharSet.Auto,
     CallingConvention=CallingConvention.StdCall)]
    public static extern int CallNextHookEx(int idHook, int nCode, 
    IntPtr wParam, IntPtr lParam);
  6. Button 控制項加入表單中,然後在 Button1_click 程序中加入下列程式碼。
    private void button1_Click(object sender, System.EventArgs e)
    {
    	if(hHook == 0)
    	{
    	        // Create an instance of HookProc.
    		MouseHookProcedure = new HookProc(Form1.MouseHookProc);
    				
    		hHook = SetWindowsHookEx(WH_MOUSE, 
    					MouseHookProcedure, 
    					(IntPtr)0,
    					AppDomain.GetCurrentThreadId());
    		//If the SetWindowsHookEx function fails.
    		if(hHook == 0 )
    		{
    			MessageBox.Show("SetWindowsHookEx Failed");
    			return;
    		}
    		button1.Text = "UnHook Windows Hook";
    	}
    	else
    	{
    		bool ret = UnhookWindowsHookEx(hHook);
    		//If the UnhookWindowsHookEx function fails.
    		if(ret == false )
    		{
    			MessageBox.Show("UnhookWindowsHookEx Failed");
    			return;
    		}
    		hHook = 0;
    		button1.Text = "Set Windows Hook";
    		this.Text = "Mouse Hook";
    	} 
    }
  7. Form1 類別的 MouseHookProc 函式中加入下列程式碼。
    public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
    {
    	//Marshall the data from the callback.
    	MouseHookStruct MyMouseHookStruct = (MouseHookStruct) Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
    
    	if (nCode < 0)
    	{
    		return CallNextHookEx(hHook, nCode, wParam, lParam);
    	}
    	else
    	{
    		//Create a string variable that shows the current mouse coordinates.
    		String strCaption = "x = " + 
    				MyMouseHookStruct.pt.x.ToString("d") + 
    					"  y = " + 
    		MyMouseHookStruct.pt.y.ToString("d");
    		//You must get the active form because it is a static function.
    		Form tempForm = Form.ActiveForm;
            
    		//Set the caption of the form.
    		tempForm.Text = strCaption;
    		return CallNextHookEx(hHook, nCode, wParam, lParam); 
    	}
    }
  8. 按 F5 以執行專案。按一下表單上的按鈕以設定勾點。當指標移動到表單上時,表單標題列上會出現滑鼠座標。再按一下按鈕以移除勾點。

.NET Framework 中不支援全域勾點

除了 WH_KEYBOARD_LL 低階勾點及 WH_MOUSE_LL 低階勾點之外,您無法在 Microsoft .NET Framework 中實作全域勾點。如果要安裝全域勾點,勾點必須具有原生 DLL 匯出,以便將自身插入需要呼叫有效且一致函式的另一個處理序中。這個行為需要 DLL 匯出。.NET Framework 不支援 DLL 匯出。Managed 程式碼沒有函式指標值一致的概念,因為這些函式指標是動態建置的 Proxy。

低階勾點程序是由安裝勾點的執行緒所呼叫。低階勾點不會要求在 DLL 中實作勾點程序。

?考

如需有關勾點的詳細資訊,請造訪下列 Microsoft Developer Network (MSDN) 網站:
http://msdn.microsoft.com/library/en-us/winui/WinUI/WindowsUserInterface/Windowing/Hooks/AboutHooks.asp

屬性

文章編號: 318804 - 上次校閱: 2007年12月3日 - 版次: 3.4
這篇文章中的資訊適用於:
  • Microsoft .NET Framework 2.0
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0
  • Microsoft Visual C# 2005
  • Microsoft Visual C# .NET 2003 標準版
  • Microsoft Visual C# .NET 2002 Standard Edition
關鍵字:?
kbhowtomaster KB318804
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com