本文將以滑鼠勾點作為範例,告訴您如何設定執行緒及勾點程序特定的勾點。您可以使用勾點監視某些類型的事件。您可以建立這些事件與特定執行緒的關聯,或是將相同桌面中所有執行緒當作一個呼叫執行緒,建立這些事件與該執行緒的關聯。
設定滑鼠勾點
如果要設定勾點,請呼叫 User32.dll 檔的
SetWindowsHookEx 函式。這個函式會在與勾點關聯的勾點鏈結中安裝應用程式定義的勾點程序。
如果要設定滑鼠勾點及監視滑鼠事件,請依照下列步驟執行:
- 啟動 Microsoft Visual Studio .NET。
- 在 [檔案] 功能表上,指向 [新增],再按一下
[專案]。
- 在 [新增專案] 對話方塊中,按一下 [專案類型]
下方的 [Visual C# 專案],然後按一下 [範本] 下方的
[Windows 應用程式]。在 [名稱] 方塊中,輸入
ThreadSpecificMouseHook。根據預設,會建立名為 Form1 的表單。
- 在 Form1.cs 檔中的其他 using 陳述式後加入下一行程式碼。
using System.Runtime.InteropServices;
- 在 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); - 將 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";
}
} - 在 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);
}
} - 按 F5
以執行專案。按一下表單上的按鈕以設定勾點。當指標移動到表單上時,表單標題列上會出現滑鼠座標。再按一下按鈕以移除勾點。
.NET Framework 中不支援全域勾點
除了 WH_KEYBOARD_LL 低階勾點及 WH_MOUSE_LL 低階勾點之外,您無法在 Microsoft .NET
Framework 中實作全域勾點。如果要安裝全域勾點,勾點必須具有原生 DLL 匯出,以便將自身插入需要呼叫有效且一致函式的另一個處理序中。這個行為需要
DLL 匯出。.NET Framework 不支援 DLL 匯出。Managed 程式碼沒有函式指標值一致的概念,因為這些函式指標是動態建置的
Proxy。
低階勾點程序是由安裝勾點的執行緒所呼叫。低階勾點不會要求在 DLL 中實作勾點程序。
如需有關勾點的詳細資訊,請造訪下列 Microsoft Developer Network (MSDN) 網站: