c# - 使用 RegisterHotKey 检测 Ctrl+V 但不拦截它

标签 c# pinvoke sendkeys hotkeys registerhotkey

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

我已经尝试了一些方法:(我成功地使用 RegisterHotKey 绑定(bind)了击键)

我有:

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, 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.
   */
}

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

一个理想的解决方案是,如果我的窗口没有首先拦截击键,只是使用react。

最佳答案

您可以通过使用 SetWindowsHookEx() 来利用 Hook 来做到这一点。

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

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

_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 应用程序来说明这一点。有关完整代码 list ,请参阅 http://pastebin.com/uCSvqwb4 .

关于c# - 使用 RegisterHotKey 检测 Ctrl+V 但不拦截它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6838540/

相关文章:

c# - 使用 Linq 方法返回时间

Python Selenium - 属性错误 : WebElement object has no attribute sendKeys in textarea

python - 如何在 Windows 7 登录窗口中使用 SendKeys?

c# - 使用 x509 证书签署 xml 文档

c# - 在窗体上注册 MouseDown 和 MouseMove

string - 如何 PInvoke 多字节 ANSI 字符串?

c# - 如何从 C# 调用具有 char[] 作为 OUT 参数的非托管函数?

c# - ComboBox_SetCurSel 位于哪个 DLL 中?

c# - 发送Keys特殊字符(){}+^ c#

c# - IsAssignableFrom 的隐式版本?