`
wsql
  • 浏览: 12104380 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

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

阅读更多

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 文档:
分享到:
评论

相关推荐

    Visual_Studio.NET相关词汇中英翻译

    在Visual Studio.NET中,开发者可以根据自己的习惯设置各种快捷键,从而提高工作效率。 #### 快捷键映射 (Accelerator Mapping) 快捷键映射是指将一组特定的键盘按键与程序中的某个命令或功能相对应的过程。这种...

    C# easyHook 实例 源码 拿去参考

    2. `WindowsFormsApplication8.suo`:这是Visual Studio的用户选项文件,存储用户的个性化设置,如断点、窗口布局等,但不直接影响代码逻辑。 3. `ClassLibrary1`:可能是一个类库项目,包含实际的easyHook实现代码...

    UE4程序嵌入WINFORM

    4. **嵌入UE4窗口**:在WinForm的代码中,使用`SetParent`函数将UE4的窗口句柄设置为你WinForm的某个控件(如PictureBox或Panel)的子窗口,这样UE4的渲染视口就会显示在这个控件上。 5. **通信与交互**:为了实现...

    将控件添加到另一个应用程序之上

    5. **C#与Win32 API集成**:在C#环境中,我们可以使用P/Invoke定义Win32 API函数的原型,并在.NET代码中调用。例如,定义`SetWindowsHookEx`、`CallNextHookEx`、`UnhookWindowsHookEx`等钩子相关的函数。 6. **...

    Hook自定义MessageBox

    3. **Visual Studio 2015**:这是微软的一款强大的集成开发环境(IDE),用于编写C++、C#、VB.NET等多种编程语言的应用程序。在VS2015中,我们可以利用其丰富的调试工具和插件支持来实现Hook技术。 4. **MessageBox...

    vc++ 开发实例源码包

    代码里用了备份dll的方法,因此在自定义的函数中可以直接调用在内存中备份的dll代码,而不需要再把函数头部改来改去。 IOCP反弹远控客户端模型,外加上线服务端,全部代码注释! 如题。这个是IOCP远程控制软件的...

    vc++ 应用源码包_6

    代码里用了备份dll的方法,因此在自定义的函数中可以直接调用在内存中备份的dll代码,而不需要再把函数头部改来改去。 IOCP反弹远控客户端模型,外加上线服务端,全部代码注释! 如题。这个是IOCP远程控制软件的...

    vc++ 应用源码包_1

    代码里用了备份dll的方法,因此在自定义的函数中可以直接调用在内存中备份的dll代码,而不需要再把函数头部改来改去。 IOCP反弹远控客户端模型,外加上线服务端,全部代码注释! 如题。这个是IOCP远程控制软件的...

    vc++ 应用源码包_2

    代码里用了备份dll的方法,因此在自定义的函数中可以直接调用在内存中备份的dll代码,而不需要再把函数头部改来改去。 IOCP反弹远控客户端模型,外加上线服务端,全部代码注释! 如题。这个是IOCP远程控制软件的...

    vc++ 应用源码包_5

    代码里用了备份dll的方法,因此在自定义的函数中可以直接调用在内存中备份的dll代码,而不需要再把函数头部改来改去。 IOCP反弹远控客户端模型,外加上线服务端,全部代码注释! 如题。这个是IOCP远程控制软件的...

    vc++ 应用源码包_3

    代码里用了备份dll的方法,因此在自定义的函数中可以直接调用在内存中备份的dll代码,而不需要再把函数头部改来改去。 IOCP反弹远控客户端模型,外加上线服务端,全部代码注释! 如题。这个是IOCP远程控制软件的...

Global site tag (gtag.js) - Google Analytics