在 Visual C# .NET 中设置窗口挂钩

原创 2004年10月17日 21:41:00

HOW TO:在 Visual C# .NET 中设置窗口挂钩

本页内容
概要 概要
参考 参考

概要

本文以鼠标挂钩为例,介绍如何设置特定于某个线程的挂钩和特定于某个挂钩过程的挂钩。您可以使用挂钩监视特定类型的事件。您可以将这些事件作为一个调用线程与一个特定的线程或同一桌面中的所有的线程关联起来。

返回页首

设置鼠标挂钩

若要设置挂钩,请从 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 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. 向窗体添加 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 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. Form1 类中为 MouseHookProc 函数添加下面的代码:
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. 按 F5 键运行此项目,然后单击窗体上的按钮以设置此挂钩。当指针在窗体上移动时,鼠标坐标将出现在窗体标题栏上。再次单击此按钮可删除此挂钩。
返回页首

在 .NET 框架中不支持全局挂钩

您无法在 Microsoft .NET 框架中实现全局挂钩。若要安装全局挂钩,挂钩必须有一个本机动态链接库 (DLL) 导出以便将其本身插入到另一个需要调入一个有效而且一致的函数的进程中。这需要一个 DLL 导出,而 .NET 框架不支持这一点。托管代码没有让函数指针具有统一的值这一概念,因为这些函数是动态构建的代理。

返回页首

参考

有关窗口挂钩的更多信息,请参见下面的 MSDN 文档:

HOW TO:在 Visual C# .NET 中设置窗口挂钩

设置鼠标挂钩若要设置挂钩,请从 User32.dll 文件中调用 SetWindowsHookEx 函数。此函数可将一个应用程序定义的挂钩过程安装到与此挂钩关联的挂钩链中。若要设置一个鼠标挂钩并监视鼠...
  • DiMA80
  • DiMA80
  • 2005年01月12日 09:04
  • 1189

C# 系统钩子--hook

一些资料: 纯C#钩子(Hook)实现---(放大镜的DEMO) URL:http://www.souzz.net/html/edu/net/net7/11518.html HOOK专题--微软...
  • ArvinStudy
  • ArvinStudy
  • 2012年10月21日 10:11
  • 1838

VisualStudio、NETFramework及C#版本关系

1.Visual Studio、.NET Framework 及C#版本搭载关系介绍 Visual Studio版本 .NET Framework版本 C#版...
  • qq_34418024
  • qq_34418024
  • 2017年09月05日 10:41
  • 207

Visual Basic.net还是C# ——如何选择.net语言

                        Visual Basic.net还是C#                                                ——如何选择.n...
  • cyz1980
  • cyz1980
  • 2007年04月10日 09:02
  • 1428

spy++ 消息钩子漫谈

spy++ 消息钩子漫谈我们经常使用SPY++来查看应用程序所处理的消息情况,但经常在网上看到许多人在问,SPY++是如何把应用程序所处理的消息展现出来的呢?许多人提出了很好的建议,但是资料都太零散,...
  • chaohaijie
  • chaohaijie
  • 2009年01月21日 21:03
  • 2952

SetWindowPos把窗口置最前

SetWindowPos(hwnd, IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP)          ? HWND_TOPMOST : HWND_NOTOPMOS...
  • haiheng
  • haiheng
  • 2004年10月27日 00:07
  • 2094

Visual Studio 2008“选项”对话框 ->“项目和解决方案”->“生成并运行”

确定在生成项目或其解决方案时是否自动保存更改的文件,可以同时生成的 Visual C++ 项目最大数以及运行时的一些默认行为。若要访问此对话框,请在“工具”菜单上单击“选项”,然后选择“项目和解决方案...
  • yy13210520
  • yy13210520
  • 2010年09月09日 23:56
  • 1981

程序员的超强外挂——Visual Assist .Net

Visual Assist X 10.1 (开发环境增强工具) ...
  • DL88250
  • DL88250
  • 2007年02月12日 00:28
  • 3969

Visual Studio 2012 调试.net framework4.5源码

原文地址:http://www.cnblogs.com/highend/archive/2012/09/17/how-to-debug-in-net45-source.html I:下载.N...
  • XuWei_XuWei
  • XuWei_XuWei
  • 2014年03月25日 17:36
  • 1957

Visual C# .NET 入门

Microsoft Corporation适用于:Microsoft Visual C# .NET摘要:Visual C# .NET 是功能强大的编程语言 Visual Studio 套件的最新成员。...
  • mjh11310
  • mjh11310
  • 2007年07月02日 14:10
  • 556
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在 Visual C# .NET 中设置窗口挂钩
举报原因:
原因补充:

(最多只允许输入30个字)