背景键按下监听器

我有一个简单的窗口forms应用程序,当我按空格键时打开大写锁定,如果我按下一个字母则将其关闭。

问题是我必须专注于窗口才能工作(最顶层也不起作用,最顶层不会只关注它只显示窗口高于其他所有未聚焦的窗口)。

任何人都知道即使我在记事本中写作,我怎么能让它工作?

密钥记录可以用于顽皮的东西,并且像这样操作Caps Lock似乎很奇怪,但由于信息已经公开,并且您比我更了解您的用户故事,我已经发布了一个解决方案。

这是一个基于MSDN论坛中C#中的键盘记录代码发布的代码片段的示例。

using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows.Forms; class Program { private const int WH_KEYBOARD_LL = 13; private const int WM_KEYDOWN = 0x0100; private static LowLevelKeyboardProc _proc = HookCallback; private static IntPtr _hookID = IntPtr.Zero; private static bool lastKeyWasLetter = false; [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); [DllImport("user32.dll")] static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo); private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); [STAThread] static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); _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 static void ToggleCapsLock() { const int KEYEVENTF_EXTENDEDKEY = 0x1; const int KEYEVENTF_KEYUP = 0x2; UnhookWindowsHookEx(_hookID); keybd_event(0x14, 0x45, KEYEVENTF_EXTENDEDKEY, (UIntPtr)0); keybd_event(0x14, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, (UIntPtr)0); _hookID = SetHook(_proc); } private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) { if (lastKeyWasLetter) { if (Control.IsKeyLocked(System.Windows.Forms.Keys.CapsLock)) { ToggleCapsLock(); } lastKeyWasLetter = false; } Keys key = (Keys)Marshal.ReadInt32(lParam); if (key == Keys.Space) { if (!Control.IsKeyLocked(System.Windows.Forms.Keys.CapsLock)) { ToggleCapsLock(); } } else if (key >= Keys.A && key <= Keys.Z) { lastKeyWasLetter = true; } } return CallNextHookEx(_hookID, nCode, wParam, lParam); } } 

将其粘贴到Visual Studio中的新Windows应用程序的Program.cs中进行试用。

如果您拦截按键事件以打开和关闭Caps Lock,则会在应用程序处理事件之前拦截该事件。 这意味着当按下字母键时关闭Caps Lock将导致您键入的应用程序接收小写字母,甚至直接在空格后。

我假设你试图强制每个单词中的第一个字母大写(如果是这样,你可能需要处理其他键,如Return也是如此),所以我的代码片段只会在下一个键上关闭Caps Lock按下一封信后的事件。 请注意,您不能只是尝试捕获该键,因为当您快速键入时,您可以按住初始键,直到您按下以下键为止。