在C#中引用win32动态连接库
Windows API
使用Windows API编程和C#编程的区别
- 灵活性和控制粒度
Windows API:可以拦截和处理系统级别的所有消息,包括键盘、鼠标、窗口消息等,提供了极高的控制粒度。
高级编程语言库:通常只能处理特定类型的消息(只限于C#封装好的方法),且需要通过重写方法来实现,灵活性较差。 - 功能范围
Windows API:可以发送任意消息到任意窗口,甚至是系统消息,功能非常广泛。
高级编程语言库:功能有限,通常只能发送和处理应用程序内的消息。 - 性能和效率
Windows API:直接调用系统底层函数,性能高效。
高级编程语言库:通过封装实现,可能有额外的性能开销。 - 实现复杂度
Windows API:需要了解系统级编程,有一定的实现复杂度。
高级编程语言库:实现简单,易于使用 - 语言独立性
Windows API 是操作系统级的接口,几乎所有编程语言都可以调用:许多跨平台 GUI 库在 Windows 平台上也是通过调用 Windows API 实现的。
钩子
参考来源: 王旭(http://www.wxzzz.com)
概述
作用:
钩子允许应用程序监视和干预系统和其他应用程序的行为,拦截系统或应用程序中的消息,以便在特定事件发生时执行自定义代码。
种类:
常见的钩子类型
- 键盘钩子、
- 鼠标钩子、
- 窗口消息钩子、
- 系统消息钩子等。
范围:
钩子可以是全局的(系统范围内的钩子,能够监视和干预所有应用程序),也可以是局部的(只针对特定应用程序)。
应用场景
C#客户端(winform,VB,WPF)的事件的触发机制:通过设置勾子监听系统或应用程序中的消息,再配合C#中的event事件实现
困扰我4年-_-
用到的win32API
//安装钩子
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
//下一个钩子
[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
// 卸载钩子
[DllImport("user32.dll")]
private static extern int UnhookWindowsHookEx(int idHook);
鼠标点击事件的触发原理
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
MouseHelper mouseHelper = new MouseHelper();
mouseHelper.MouseEvent += (() => { MessageBox.Show("HaHa"); });
mouseHelper.Listen();
}
}
public class MouseHelper
{
// WH_MOUSE_LL 是一种低级鼠标钩子,允许对鼠标事件进行全局监视,无论事件发生在哪个窗口中。
// 用于拦截和监视鼠标事件,如鼠标移动、按键等。
private const int WH_MOUSE_LL = 14;
//全局事件
public event Action MouseEvent;
// 钩子处理函数委托
private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
/// <summary>
/// 此字段不客观需要的,但我们需要保持一个供参考的将被传递给非托管代码的委托。
/// 为了避免GC把它清理干净。
/// </summary>
private static HookProc s_MouseDelegate;
// 从 user32.dll 导入 SetWindowsHookEx 函数
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
// 从 user32.dll 导入 CallNextHookEx 函数
[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
private static extern int UnhookWindowsHookEx(int idHook);
// 钩子处理函数
private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)0x0201) // WM_LBUTTONDOWN
{
//触发点击事件
MouseEvent?.Invoke();
// 在这里处理鼠标左键按下事件
Console.WriteLine("左键按下");
}
// 继续传递消息
return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam);
}
public void Listen()
{
//为了避免GC把它清理干净。
s_MouseDelegate = HookCallback;
//安装钩子
//要传入静态的s_MouseDelegate,避免GC把它清理掉
SetWindowsHookEx(WH_MOUSE_LL, s_MouseDelegate, IntPtr.Zero, 0);
}
}