C# 方便用户按键设置热键。显示热键文本,保存虚拟键代码

C# 方便用户按键设置热键。显示热键文本,保存虚拟键代码,c#,winforms,C#,Winforms,我不确定我对标题的解释是否足够好,但我想让一个人按任意键,然后我可以存储该键代码供以后使用,但更重要的是,我希望直观地显示他们选择的键。有点像游戏中的键盘设置类型 我想知道是否有任何公共类或其他东西可以减轻为每个键编码的麻烦。看看 它提到了这个事件 您还可以在他们释放密钥时侦听事件。有一个专门为此设计的本机Win32控件,称为控件。您可能已经看到它在Windows shell和其他应用程序中使用。这将是我建议你使用的,而不是试图自己重新发明轮子 不幸的是,WinForms没有为此控件提供包装器。

我不确定我对标题的解释是否足够好,但我想让一个人按任意键,然后我可以存储该键代码供以后使用,但更重要的是,我希望直观地显示他们选择的键。有点像游戏中的键盘设置类型

我想知道是否有任何公共类或其他东西可以减轻为每个键编码的麻烦。

看看

它提到了这个事件


您还可以在他们释放密钥时侦听事件。

有一个专门为此设计的本机Win32控件,称为控件。您可能已经看到它在Windows shell和其他应用程序中使用。这将是我建议你使用的,而不是试图自己重新发明轮子

不幸的是,WinForms没有为此控件提供包装器。这意味着你要么自己写,要么就将就一下

编辑:或者为热键控件使用这个快速组合的.NET包装器。公共接口的整体是
KeyData
属性,其工作原理与类的类似命名属性类似。
Text
属性(通过从
控件继承而提供)不起任何作用,但可以重载以返回所选热键的漂亮打印版本。此外,本机控件消息的功能未实现;如果需要该功能,您需要自己添加代码

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

internal static class NativeMethods
{
   internal const string HOTKEY_CLASS = "msctls_hotkey32";
   internal const int CS_GLOBALCLASS = 0x4000;

   internal const int WS_CHILD = 0x40000000;
   internal const int WS_VISIBLE = 0x10000000;
   internal const int WS_TABSTOP = 0x00010000;
   internal const int WS_EX_NOPARENTNOTIFY = 0x00000004;
   internal const int WS_EX_CLIENTEDGE = 0x00000200;
   internal const int WS_EX_LEFT = 0x00000000;
   internal const int WS_EX_LTRREADING = 0x00000000;
   internal const int WS_EX_RIGHTSCROLLBAR = 0x00000000;
   internal const int WS_EX_RIGHT = 0x00001000;
   internal const int WS_EX_RTLREADING = 0x00002000;
   internal const int WS_EX_LEFTSCROLLBAR = 0x00004000;

   internal const int HOTKEYF_SHIFT = 0x01;
   internal const int HOTKEYF_CONTROL = 0x02;
   internal const int HOTKEYF_ALT = 0x04;
   internal const int HOTKEYF_EXT = 0x08;

   internal const int WM_USER = 0x0400;
   internal const int HKM_SETHOTKEY = (WM_USER + 1);
   internal const int HKM_GETHOTKEY = (WM_USER + 2);
   internal const int HKM_SETRULES = (WM_USER + 3);

   [DllImport("user32.dll", CharSet = CharSet.Auto)]
   internal static extern IntPtr SendMessage(IntPtr hWnd,
                                             int msg,
                                             IntPtr wParam,
                                             IntPtr lParam);
}

class HotKey : Control
{
   public HotKey()
   {
      base.SetStyle(ControlStyles.UserPaint
                     | ControlStyles.StandardClick
                     | ControlStyles.StandardDoubleClick
                     | ControlStyles.UseTextForAccessibility, false);
      base.SetStyle(ControlStyles.FixedHeight, true);
   }

   public Keys KeyData
   {
      get
      {
         IntPtr retVal = NativeMethods.SendMessage(Handle,
                                                   NativeMethods.HKM_GETHOTKEY,
                                                   IntPtr.Zero,
                                                   IntPtr.Zero);

         Keys keyCode = (Keys)(retVal.ToInt32() & 0xFF);

         int modifierFlags = (retVal.ToInt32() >> 8);
         Keys modifiers = Keys.None;
         if ((modifierFlags & NativeMethods.HOTKEYF_ALT) == NativeMethods.HOTKEYF_ALT)
            modifiers |= Keys.Alt;
         if ((modifierFlags & NativeMethods.HOTKEYF_CONTROL) == NativeMethods.HOTKEYF_CONTROL)
            modifiers |= Keys.Control;
         if ((modifierFlags & NativeMethods.HOTKEYF_SHIFT) == NativeMethods.HOTKEYF_SHIFT)
            modifiers |= Keys.Shift;

         return (keyCode | modifiers);
      }
      set
      {
         Keys keyCode = (value & (~Keys.Alt & ~Keys.Control & ~Keys.Shift));

         int modifierFlags = 0;
         if ((value & Keys.Alt) == Keys.Alt)
            modifierFlags |= NativeMethods.HOTKEYF_ALT;
         if ((value & Keys.Control) == Keys.Control)
            modifierFlags |= NativeMethods.HOTKEYF_CONTROL;
         if ((value & Keys.Shift) == Keys.Shift)
            modifierFlags |= NativeMethods.HOTKEYF_SHIFT;

         NativeMethods.SendMessage(Handle,
                                   NativeMethods.HKM_SETHOTKEY,
                                   (IntPtr)((modifierFlags << 8) | ((int)keyCode & 0xffff)),
                                   IntPtr.Zero);
      }
   }

   protected override CreateParams CreateParams
   {
      get
      {
         CreateParams cp = base.CreateParams;
         cp.ClassName = NativeMethods.HOTKEY_CLASS;
         cp.ClassStyle = NativeMethods.CS_GLOBALCLASS;
         cp.Style = NativeMethods.WS_CHILD | NativeMethods.WS_VISIBLE | NativeMethods.WS_TABSTOP;
         cp.ExStyle = NativeMethods.WS_EX_NOPARENTNOTIFY | NativeMethods.WS_EX_CLIENTEDGE;
         if (RightToLeft == RightToLeft.No ||
            (RightToLeft == RightToLeft.Inherit && Parent.RightToLeft == RightToLeft.No))
         {
            cp.ExStyle |= NativeMethods.WS_EX_LEFT
                            | NativeMethods.WS_EX_LTRREADING
                            | NativeMethods.WS_EX_RIGHTSCROLLBAR;
         }
         else
         {
            cp.ExStyle |= NativeMethods.WS_EX_RIGHT
                           | NativeMethods.WS_EX_RTLREADING
                           | NativeMethods.WS_EX_LEFTSCROLLBAR;
         }
         return cp;
      }
   }
}
使用系统;
使用System.Windows.Forms;
使用System.Runtime.InteropServices;
内部静态类NativeMethods
{
内部常量字符串热键\u CLASS=“msctls\u热键32”;
内部常量int CS_GLOBALCLASS=0x4000;
内部常量int WS_CHILD=0x40000000;
内部常量int WS_VISIBLE=0x10000000;
内部常量int WS_TABSTOP=0x00010000;
内部常量int WS_EX_NOPARENTNOTIFY=0x00000004;
内部常量int WS_EX_CLIENTEDGE=0x00000200;
内部常量int WS_EX_LEFT=0x00000000;
内部常量int WS_EX_LTRREADING=0x00000000;
内部常量int WS_EX_RIGHTSCROLLBAR=0x00000000;
内部常数int WS_EX_RIGHT=0x00001000;
内部常数int WS_EX_RTLREADING=0x00002000;
内部常量int WS_EX_LEFTSCROLLBAR=0x00004000;
内部常数int HOTKEYF_SHIFT=0x01;
内部常数int HOTKEYF_控制=0x02;
内部常数int HOTKEYF_ALT=0x04;
内部常数int热键f_EXT=0x08;
内部常数int WM_USER=0x0400;
内部常量int HKM_设置热键=(WM_用户+1);
内部常量int HKM_GETHOTKEY=(WM_用户+2);
内部常量int HKM_SETRULES=(WM_用户+3);
[DllImport(“user32.dll”,CharSet=CharSet.Auto)]
内部静态外部IntPtr发送消息(IntPtr hWnd,
int msg,
IntPtr wParam,
IntPtr(内存);
}
类热键:控件
{
公用热键()
{
base.SetStyle(ControlStyles.UserPaint
|ControlStyles.StandardClick
|ControlStyles.StandardDoubleClick
|ControlStyles.UseTextForAccessibility,false);
base.SetStyle(ControlStyles.FixedHeight,true);
}
公钥密钥数据
{
得到
{
IntPtr retVal=NativeMethods.SendMessage(句柄,
NativeMethods.HKM_GETHOTKEY,
IntPtr.Zero,
IntPtr.0);
Keys keyCode=(Keys)(retVal.ToInt32()&0xFF);
int modifierFlags=(retVal.ToInt32()>>8);
关键点修改器=关键点。无;
if((modifierFlags&NativeMethods.HOTKEYF_-ALT)==NativeMethods.HOTKEYF_-ALT)
修饰符|=Keys.Alt;
if((modifierFlags&NativeMethods.HOTKEYF_控件)==NativeMethods.HOTKEYF_控件)
修饰符|=键。控件;
if((modifierFlags&NativeMethods.HOTKEYF\u SHIFT)==NativeMethods.HOTKEYF\u SHIFT)
修饰符|=键。Shift;
返回(键码|修饰符);
}
设置
{
Keys-keyCode=(value&(~Keys.Alt&~Keys.Control&~Keys.Shift));
int modifierFlags=0;
if((value&Keys.Alt)=Keys.Alt)
modifierFlags |=NativeMethods.HOTKEYF|u ALT;
if((值和键控制)=键控制)
modifierFlags |=NativeMethods.HOTKEYF_控件;
if((value&Keys.Shift)=Keys.Shift)
modifierFlags |=NativeMethods.HOTKEYF|u SHIFT;
NativeMethods.SendMessage(句柄,
NativeMethods.HKM_设置热键,

(IntPtr)((modifierFlags console?wpf?winforms?对您来说,最简单的方法是控制控件的按键事件,发送方将是事件参数应向您提供有关按键的信息
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

internal static class NativeMethods
{
   internal const string HOTKEY_CLASS = "msctls_hotkey32";
   internal const int CS_GLOBALCLASS = 0x4000;

   internal const int WS_CHILD = 0x40000000;
   internal const int WS_VISIBLE = 0x10000000;
   internal const int WS_TABSTOP = 0x00010000;
   internal const int WS_EX_NOPARENTNOTIFY = 0x00000004;
   internal const int WS_EX_CLIENTEDGE = 0x00000200;
   internal const int WS_EX_LEFT = 0x00000000;
   internal const int WS_EX_LTRREADING = 0x00000000;
   internal const int WS_EX_RIGHTSCROLLBAR = 0x00000000;
   internal const int WS_EX_RIGHT = 0x00001000;
   internal const int WS_EX_RTLREADING = 0x00002000;
   internal const int WS_EX_LEFTSCROLLBAR = 0x00004000;

   internal const int HOTKEYF_SHIFT = 0x01;
   internal const int HOTKEYF_CONTROL = 0x02;
   internal const int HOTKEYF_ALT = 0x04;
   internal const int HOTKEYF_EXT = 0x08;

   internal const int WM_USER = 0x0400;
   internal const int HKM_SETHOTKEY = (WM_USER + 1);
   internal const int HKM_GETHOTKEY = (WM_USER + 2);
   internal const int HKM_SETRULES = (WM_USER + 3);

   [DllImport("user32.dll", CharSet = CharSet.Auto)]
   internal static extern IntPtr SendMessage(IntPtr hWnd,
                                             int msg,
                                             IntPtr wParam,
                                             IntPtr lParam);
}

class HotKey : Control
{
   public HotKey()
   {
      base.SetStyle(ControlStyles.UserPaint
                     | ControlStyles.StandardClick
                     | ControlStyles.StandardDoubleClick
                     | ControlStyles.UseTextForAccessibility, false);
      base.SetStyle(ControlStyles.FixedHeight, true);
   }

   public Keys KeyData
   {
      get
      {
         IntPtr retVal = NativeMethods.SendMessage(Handle,
                                                   NativeMethods.HKM_GETHOTKEY,
                                                   IntPtr.Zero,
                                                   IntPtr.Zero);

         Keys keyCode = (Keys)(retVal.ToInt32() & 0xFF);

         int modifierFlags = (retVal.ToInt32() >> 8);
         Keys modifiers = Keys.None;
         if ((modifierFlags & NativeMethods.HOTKEYF_ALT) == NativeMethods.HOTKEYF_ALT)
            modifiers |= Keys.Alt;
         if ((modifierFlags & NativeMethods.HOTKEYF_CONTROL) == NativeMethods.HOTKEYF_CONTROL)
            modifiers |= Keys.Control;
         if ((modifierFlags & NativeMethods.HOTKEYF_SHIFT) == NativeMethods.HOTKEYF_SHIFT)
            modifiers |= Keys.Shift;

         return (keyCode | modifiers);
      }
      set
      {
         Keys keyCode = (value & (~Keys.Alt & ~Keys.Control & ~Keys.Shift));

         int modifierFlags = 0;
         if ((value & Keys.Alt) == Keys.Alt)
            modifierFlags |= NativeMethods.HOTKEYF_ALT;
         if ((value & Keys.Control) == Keys.Control)
            modifierFlags |= NativeMethods.HOTKEYF_CONTROL;
         if ((value & Keys.Shift) == Keys.Shift)
            modifierFlags |= NativeMethods.HOTKEYF_SHIFT;

         NativeMethods.SendMessage(Handle,
                                   NativeMethods.HKM_SETHOTKEY,
                                   (IntPtr)((modifierFlags << 8) | ((int)keyCode & 0xffff)),
                                   IntPtr.Zero);
      }
   }

   protected override CreateParams CreateParams
   {
      get
      {
         CreateParams cp = base.CreateParams;
         cp.ClassName = NativeMethods.HOTKEY_CLASS;
         cp.ClassStyle = NativeMethods.CS_GLOBALCLASS;
         cp.Style = NativeMethods.WS_CHILD | NativeMethods.WS_VISIBLE | NativeMethods.WS_TABSTOP;
         cp.ExStyle = NativeMethods.WS_EX_NOPARENTNOTIFY | NativeMethods.WS_EX_CLIENTEDGE;
         if (RightToLeft == RightToLeft.No ||
            (RightToLeft == RightToLeft.Inherit && Parent.RightToLeft == RightToLeft.No))
         {
            cp.ExStyle |= NativeMethods.WS_EX_LEFT
                            | NativeMethods.WS_EX_LTRREADING
                            | NativeMethods.WS_EX_RIGHTSCROLLBAR;
         }
         else
         {
            cp.ExStyle |= NativeMethods.WS_EX_RIGHT
                           | NativeMethods.WS_EX_RTLREADING
                           | NativeMethods.WS_EX_LEFTSCROLLBAR;
         }
         return cp;
      }
   }
}