C# – 检查是否按下了特定键

我是C#编程的新手。 我正在尝试检查按键是否按下,但是我收到以下错误消息:“错误1当前上下文中不存在名称’键盘’”“错误2当前上下文中不存在名称’Key’ “你能告诉我怎么修理它吗?

//... using System.Windows.Input; class Main { public void Main() { while(true) { if(Keyboard.IsKeyPressed(Key.A)) { //... } return; } } } 

您可以使用键盘钩子。 看看这个 ,从这个问题的答案 :

如果您只需要一些全局热键,则全局键盘挂钩不是正确的解决方案。 高级键盘挂钩意味着您的DLL将被注入其他应用程序,并且不应该在托管代码中完成。 低级键盘钩更好一点,因为它处理您自己的应用程序中的键盘事件。 仍然需要每个键盘事件都由您的线程处理。

Windows API函数RegisterHotKey更适合这种情况。

但是使用一个简单的F-Key作为全局热键是有问题的,因为它可能会与具有焦点的应用程序的本地热键发生冲突。 因此,您应该使全局热键可配置,以便用户可以避免与其常用应用程序发生冲突。

看起来您正在尝试在系统中创建全局热键,并且您的应用程序应在按下时响应。

您将需要两个Win32 API函数RegisterHotKey和UnregisterHotKey 。

看看你using System.Windows.Input ,看起来你正试图用WPF做这个,这是可能的。

让我们从你相当基本的P / Invokes开始:

 using System.Runtime.InteropServices; internal static class NativeMethods { [DllImport("user32.dll")] public static extern bool RegisterHotKey(IntPtr windowHandle, int hotkeyId, uint modifierKeys, uint virtualKey); [DllImport("user32.dll")] public static extern bool UnregisterHotKey(IntPtr windowHandle, int hotkeyId); } 

现在,当您注册Window ,会发生WM_HOTKEY消息发送到您的应用程序的消息泵。 但是,WPF会将此消息抽象出来,因此您需要添加一个HwndSourceHook来接收它。

我们怎么做这一切? 让我们从初始化HwndSourceHook委托开始。 将此代码段添加到您的MainWindow

  using System.Windows.Interop; static readonly int MyHotKeyId = 0x3000; static readonly int WM_HOTKEY = 0x312; void InitializeHook() { var windowHelper = new WindowInteropHelper(this); var windowSource = HwndSource.FromHwnd(windowHelper.Handle); windowSource.AddHook(MessagePumpHook); } IntPtr MessagePumpHook(IntPtr handle, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == WM_HOTKEY) { if ((int)wParam == MyHotKeyId) { // The hotkey has been pressed, do something! handled = true; } } return IntPtr.Zero; } 

好的,现在我们已经准备好了一切来回应WM_HOTKEY消息。 但是,我们还需要注册我们的热键! 让我们添加另外几个初始化方法:

  void InitializeHotKey() { var windowHelper = new WindowInteropHelper(this); // You can specify modifiers such as SHIFT, ALT, CONTROL, and WIN. // Remember to use the bit-wise OR operator (|) to join multiple modifiers together. uint modifiers = (uint)ModifierKeys.None; // We need to convert the WPF Key enumeration into a virtual key for the Win32 API! uint virtualKey = (uint)KeyInterop.VirtualKeyFromKey(Key.A); NativeMethods.RegisterHotKey(windowHelper.Handle, MyHotKeyId, modifiers, virtualKey); } void UninitializeHotKey() { var windowHelper = new WindowInteropHelper(this); NativeMethods.UnregisterHotKey(windowHelper.Handle, MyHotKeyId); } 

好的! 我们把它们放在哪里? 不要把它们放在构造函数中! 为什么? 因为Handle将为0并且无效! 把它们放在这里(在MainWindow ):

  protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); InitializeHook(); InitializeHotKey(); } 

您可以注册多个热键,取消注册并重新注册新的热键。这取决于您。 请记住, 每个热键必须具有注册的唯一ID 。 它只是有意义,因为你的消息泵钩子必须知道哪个热键导致WM_HOTKEY消息!

在应用程序关闭时取消注册所有热键也是一种很好的做法。

申请的类型对我来说并不清楚! 如果您有一个控制台应用程序,而不是Windows窗体应用程序,您可以尝试这样做:

 while (true) { if (Console.KeyAvailable) if (Console.ReadKey(true).Key == ConsoleKey.A) { // Do something } } 

如果你想在Windows窗体应用程序中有一个全局热键,请阅读此内容: http : //www.liensberger.it/web/blog/? p = 207

如果您尝试在Windows窗体应用程序中执行此操作,也许您可​​以将这些代码添加到窗体的KeyDown事件(或您需要使用的键事件)中:

 switch (e.KeyData) { //Detects that you pressed the Up Arrow Key, which key do you need, just //write it here. case Keys.Up: //enter code here` break; }