HOW TO: Set a Windows Hook in Visual C# .NET

HOW TO: Set a Windows Hook in Visual C# .NET

Article ID:318804
Last Review:February 10, 2003
Revision:2.0
This article was previously published under Q318804
On this Page
SUMMARYSUMMARY
REFERENCESREFERENCES

SUMMARY

This article describes how to set a hook that is specific to a thread and to a hook procedure by using the mouse hook as an example. You can use hooks to monitor certain types of events. You can associate these events with a specific thread or with all of the threads in the same desktop as a calling thread.

back to the top

Set a Mouse Hook

To set a hook, call the SetWindowsHookEx function from the User32.dll file. This function installs an application-defined hook procedure in the hook chain that is associated with the hook.

To set a mouse hook and to monitor the mouse events, follow these steps:
1.Start Microsoft Visual Studio .NET.
2.On the File menu, point to New, and then click Project.
3.In the New Project dialog box, click Visual C# Projects under Project Types, and then click Windows Application under Templates. In the Name box, type ThreadSpecificMouseHook. Form1 is added to the project by default.
4.Add the following line of code in the Form1.cs file after the other using statements:
using System.Runtime.InteropServices;
					
5.Add following code in the Form1 class:
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);

//Declare hook handle as int.
static int hHook = 0;

//Declare mouse hook constant.
//For other hook types, you can obtain these values from Winuser.h in Microsoft SDK.
public const int WH_MOUSE = 7;
private System.Windows.Forms.Button button1;

//Declare MouseHookProcedure as HookProc type.
HookProc MouseHookProcedure;

//Declare wrapper managed POINT class.
[StructLayout(LayoutKind.Sequential)]
public class POINT
{
	public int x;
	public int y;
}

//Declare wrapper managed MouseHookStruct class.
[StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct
{
	public POINT pt;
	public int hwnd;
	public int wHitTestCode;
	public int dwExtraInfo;
}

//Import for SetWindowsHookEx function.
//Use this function to install 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);

//Import for UnhookWindowsHookEx.
//Call this function to uninstall the hook.
[DllImport("user32.dll",CharSet=CharSet.Auto,
 CallingConvention=CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);

//Import for CallNextHookEx.
//Use this function to pass the hook information to 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.Add a Button control to the form, and then add the following code in the Button1_click procedure:
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 SetWindowsHookEx fails.
		if(hHook == 0 )
		{
			MessageBox.Show("SetWindowsHookEx Failed");
			return;
		}
		button1.Text = "UnHook Windows Hook";
	}
	else
	{
		bool ret = UnhookWindowsHookEx(hHook);
		//If UnhookWindowsHookEx fails.
		if(ret == false )
		{
			MessageBox.Show("UnhookWindowsHookEx Failed");
			return;
		}
		hHook = 0;
		button1.Text = "Set Windows Hook";
		this.Text = "Mouse Hook";
	}
}
					
7.Add the following code for the MouseHookProc function in the Form1 class:
public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
	//Marshall the data from callback.
	MouseHookStruct MyMouseHookStruct = (MouseHookStruct) Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));

	if (nCode < 0)
	{
		return CallNextHookEx(hHook, nCode, wParam, lParam);
	}
	else
	{
		//Create a string variable with shows current mouse. coordinates
		String strCaption = "x = " +
				MyMouseHookStruct.pt.x.ToString("d") +
					"  y = " +
		MyMouseHookStruct.pt.y.ToString("d");
		//Need to 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.Press F5 to run the project, and then click the button on the form to set the hook. The mouse coordinates appear on the form caption bar when the pointer moves on the form. Click the button again to remove the hook.
back to the top

Global Hook Is Not Supported in .NET Framework

You cannot implement global hooks in Microsoft .NET Framework. To install a global hook, a hook must have a native dynamic-link library (DLL) export to inject itself in another process that requires a valid, consistent function to call into. This requires a DLL export, which .NET Framework does not support. Managed code has no concept of a consistent value for a function pointer because these function pointers are proxies that are built dynamically.

back to the top

REFERENCES

For more information about windows hooks, see the following MSDN documentation: back to the top
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值