使用RegisterHotKey检测Ctrl + V但不截取它

我需要检测用户何时按下Ctrl + V (无论窗口焦点如何 – 我的应用程序可能会被最小化)但我不能停止实际的粘贴操作。

我尝试了一些事情:(我成功绑定了RegisterHotKey的键击)

我有:

protected override void WndProc(ref Message m) { if (m.Msg == 0x312) hotKey(); base.WndProc(ref m); } 

我尝试过以下方法:

 void hotKey() { SendKeys.SendWait("^v"); //just puts 'v' instead of clipboard contents } 

 void hotKey() { SendKeys.SendWait(ClipBoard.GetText()); /* This works, but since Ctrl is still down, it triggers * all the shortcut keys for the app, eg if the keyboard * contains 's' then instead of putting 's' in the app, it * calls Ctrl+S which makes the app think the user wants * to save. */ } 

目前我唯一可行的解​​决方法是绑定不同的东西,例如Ctrl + B ,然后调用SendKeys.SendWait("^v"); 但这并不理想。

一个理想的解决方案是,如果我的窗口首先没有拦截击键,只是做出反应。

您可以通过使用SetWindowsHookEx()利用钩子来实现此目的。

 HHOOK WINAPI SetWindowsHookEx( __in int idHook, __in HOOKPROC lpfn, __in HINSTANCE hMod, __in DWORD dwThreadId ); 

基本上,您可以设置一个低级键盘钩子:

 _hookHandle = SetWindowsHookEx( WH_KEYBOARD_LL, KbHookProc, // Your keyboard handler (IntPtr)0, 0); // Set up system-wide hook. 

捕获系统范围的键盘事件。 但它也允许您将这些键盘事件传递给其他应用程序。 对于您的特定情况,您可以将KbHookProc定义为:

 private static int KbHookProc(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0) // This means we can intercept the event. { var hookStruct = (KbLLHookStruct)Marshal.PtrToStructure( lParam, typeof(KbLLHookStruct)); // Quick check if Ctrl key is down. // See GetKeyState() doco for more info about the flags. bool ctrlDown = GetKeyState(VK_LCONTROL) != 0 || GetKeyState(VK_RCONTROL) != 0; if (ctrlDown && hookStruct.vkCode == 0x56) // Ctrl+V { // Replace this with your custom action. Clipboard.SetText("Hi"); } } // Pass to other keyboard handlers. Makes the Ctrl+V pass through. return CallNextHookEx(_hookHandle, nCode, wParam, lParam); } 

我编写了一个快速而肮脏的WinForms应用程序来说明这一点。 有关完整的代码清单,请参阅http://pastebin.com/uCSvqwb4 。