在不使用Windows窗体中的事件的情况下按下检测Shift键?

我需要能够检测到Shift键被保持,但我不想使用事件或全局变量来确定它。 C#中是否有API可以让您询问当前按下哪些键而不是使用该事件?

if ((Control.ModifierKeys & Keys.Shift) != 0) 

如果另一个修改键也向下(例如,Ctrl + Shift),这也将true 。 如果要在没有任何其他修改器的情况下检查是否按下Shift,请使用

 if (Control.ModifierKeys == Keys.Shift) 

请注意,如果另一个非修饰符向下(例如,Shift + A),即使这样也是true 。 如果要检查是否按下了Shift和Only Shift,则必须使用API​​调用。


如果您在inheritanceControl的类(例如表单)中,则可以删除Control限定符。 ( static属性在inheritance的类中不需要限定符)

Form.ModifierKeys (静态属性)

您可以安装低级键盘钩子 。

 using System; using System.Diagnostics; using System.Windows.Forms; using System.Runtime.InteropServices; class InterceptKeys { private const int WH_KEYBOARD_LL = 13; private const int WM_KEYDOWN = 0x0100; private static LowLevelKeyboardProc _proc = HookCallback; private static IntPtr _hookID = IntPtr.Zero; public static void Main() { _hookID = SetHook(_proc); Application.Run(); UnhookWindowsHookEx(_hookID); } private static IntPtr SetHook(LowLevelKeyboardProc proc) { using (Process curProcess = Process.GetCurrentProcess()) using (ProcessModule curModule = curProcess.MainModule) { return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); } } private delegate IntPtr LowLevelKeyboardProc( int nCode, IntPtr wParam, IntPtr lParam); private static IntPtr HookCallback( int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) { int vkCode = Marshal.ReadInt32(lParam); Console.WriteLine((Keys)vkCode); } return CallNextHookEx(_hookID, nCode, wParam, lParam); } [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool UnhookWindowsHookEx(IntPtr hhk); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr GetModuleHandle(string lpModuleName); } 

不确定这是否在C#中可用,但您可以调用GetAsyncKeyState 。 此方法在调用方法时返回键的状态。

要从C#调用它,您需要像任何其他Win32 API一样使用互操作。