使用RegisterHotKey检测Ctrl + V但不拦截它 [英] Detecting Ctrl+V with RegisterHotKey but not intercepting it

查看:237
本文介绍了使用RegisterHotKey检测Ctrl + V但不拦截它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要检测用户何时按下 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆