用C#语言,怎么监听键盘,请生成一段完整代码
时间: 2023-08-21 07:04:20 浏览: 53
以下是使用 C# 编写的一个实现监听键盘按键的样例程序,该程序以 Windows 窗体应用程序为例。请注意,该代码仅供参考,具体实现可能会因环境、框架版本等因素而有所不同,使用前请仔细阅读其说明文档。
```csharp
using System;
using System.Windows.Forms;
public class Form1 : Form
{
public Form1()
{
InitializeComponent();
HookKeyboard();
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// Form1
//
this.ClientSize = new System.Drawing.Size(284, 261);
this.Name = "Form1";
this.Text = "KeyboardListener";
this.ResumeLayout(false);
}
private void HookKeyboard()
{
// 创建键盘钩子
KeyboardHook hook = new KeyboardHook();
hook.KeyDown += new KeyboardHook.KeyDownEventHandler(hook_KeyDown);
hook.KeyUp += new KeyboardHook.KeyUpEventHandler(hook_KeyUp);
}
private void hook_KeyDown(object sender, KeyboardHook.KeyDownEventArgs e)
{
// 处理键盘按下事件
Console.WriteLine("KeyDown: " + e.KeyCode.ToString());
}
private void hook_KeyUp(object sender, KeyboardHook.KeyUpEventArgs e)
{
// 处理键盘松开事件
Console.WriteLine("KeyUp: " + e.KeyCode.ToString());
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
public class KeyboardHook
{
public delegate void KeyDownEventHandler(object sender, KeyDownEventArgs e);
public delegate void KeyUpEventHandler(object sender, KeyUpEventArgs e);
public event KeyDownEventHandler KeyDown;
public event KeyUpEventHandler KeyUp;
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private const int WM_KEYUP = 0x0101;
private LowLevelKeyboardProc keyboardProc;
private IntPtr hookId = IntPtr.Zero;
public KeyboardHook()
{
keyboardProc = new LowLevelKeyboardProc(HookCallback);
hookId = SetHook(keyboardProc);
}
~KeyboardHook()
{
UnhookWindowsHookEx(hookId);
}
private IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process process = Process.GetCurrentProcess())
{
using (ProcessModule module = process.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(module.ModuleName), 0);
}
}
}
private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0)
{
int vkCode = Marshal.ReadInt32(lParam);
if (wParam == (IntPtr)WM_KEYDOWN && KeyDown != null)
{
KeyDown(this, new KeyDownEventArgs(vkCode));
}
else if (wParam == (IntPtr)WM_KEYUP && KeyUp != null)
{
KeyUp(this, new KeyUpEventArgs(vkCode));
}
}
return CallNextHookEx(hookId, nCode, wParam, lParam);
}
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
[StructLayout(LayoutKind.Sequential)]
private struct KBDLLHOOKSTRUCT
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
private struct MSG
{
public IntPtr hwnd;
public uint message;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public POINT pt;
}
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
public class KeyDownEventArgs : EventArgs
{
public int KeyCode { get; private set; }
public KeyDownEventArgs(int keyCode)
{
KeyCode = keyCode;
}
}
public class KeyUpEventArgs : EventArgs
{
public int KeyCode { get; private set; }
public KeyUpEventArgs(int keyCode)
{
KeyCode = keyCode;
}
}
}
```
在该程序中,我们使用了一个名为 KeyboardHook 的类来实现键盘钩子的注册和处理。该类中定义了 KeyDown 和 KeyUp 两个事件,分别用于处理键盘按下事件和键盘松开事件。在处理事件时,我们可以根据事件参数获取按下的键的信息,例如键码、键名等。
在程序中,我们创建了一个 KeyboardHook 对象,并在构造函数中注册了键盘钩子。在事件处理程序中,我们使用 Console.WriteLine() 方法将按下的键的信息输出到控制台,以便调试和测试。
在使用键盘钩子时,需要注意以下几点:
1. 需要使用 SetWindowsHookEx() 方法注册键盘钩子,该方法会返回一个钩子句柄。在程序结束时,需要使用 UnhookWindowsHookEx() 方法注销键盘钩子,释放资源。
2. 在钩子回调函数中,需要使用 CallNextHookEx() 方法将消息传递给下一个钩子或者系统默认的消息处理函数,否则会导致系统性能下降或者异常。
3. 在使用钩子时,需要注意不要拦截系统级别的按键事件,例如 Ctrl+Alt+Delete、Alt+Tab 等,否则会影响系统的正常运行。