使用RegisterHotKey检测Ctrl + V但不拦截它 [英] Detecting Ctrl+V with RegisterHotKey but not intercepting it
问题描述
我需要检测用户何时按下 Ctrl + V (无论窗口焦点如何-我的应用程序可能会被最小化),但是我不能停止实际的粘贴操作
I need to detect when a user presses Ctrl+V(regardless of window focus - my app will likely be minimised) but I must not stop the actual paste operation.
我尝试了一些事情:(我已经成功地通过RegisterHotKey绑定了击键)
I have tried a few things: (I am successfully binding to keystrokes with RegisterHotKey)
我有:
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x312)
hotKey();
base.WndProc(ref m);
}
并且我尝试了以下操作:
and I've tried the following:
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, e.g. 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");
,但这并不理想.
Currently the only working solution I have is to bind to something different, e.g. Ctrl+B and then call SendKeys.SendWait("^v");
however this isn't ideal.
一种理想的解决方案是,如果我的窗口首先没有拦截按键,只是做出了反应.
An ideal solution would be if my window didn't intercept the keystroke in the first place, just reacted.
推荐答案
您可以通过使用SetWindowsHookEx()来利用钩子来做到这一点.
You can do this by leveraging hooks using SetWindowsHookEx().
HHOOK WINAPI SetWindowsHookEx(
__in int idHook,
__in HOOKPROC lpfn,
__in HINSTANCE hMod,
__in DWORD dwThreadId
);
基本上,您可以设置一个低级键盘挂钩:
Basically, you can set up a low-level keyboard hook:
_hookHandle = SetWindowsHookEx(
WH_KEYBOARD_LL,
KbHookProc, // Your keyboard handler
(IntPtr)0,
0); // Set up system-wide hook.
捕获系统范围内的键盘事件.但是,它还可以使这些键盘事件传递给其他应用程序.对于您的特定情况,可以将KbHookProc
定义为:
to capture system-wide keyboard events. But it also allows you to make those keyboard events pass through to other apps. For your particular case, you can define KbHookProc
as:
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 .
I coded a quick and dirty WinForms app to illustrate this. For the full code listing, see http://pastebin.com/uCSvqwb4.
这篇关于使用RegisterHotKey检测Ctrl + V但不拦截它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!