简体   繁体   English

不会传播到Windows的后台键盘快捷键

[英]Background keyboard shortcuts that do not propagate to windows

I made an application that needs to handle specific keyboard presses even when the window is not active, now I have this and it works great; 我制作了一个即使在窗口不活动时也需要处理特定键盘按键的应用程序,现在我有了它并且效果很好。 however the handled keys are still being propagated to windows (not sure if my app is handling them first, so I may be backwards about that). 但是,已处理的密钥仍会传播到Windows(不确定我的应用程序是否首先处理它们,因此我可能对此有所退步)。

Is there any way to have it so my app can handle the key presses I want but not have the keys be sent to the current application/windows. 有什么办法可以让我的应用程序处理我想要的按键,但是没有将按键发送到当前的应用程序/窗口。

EX) I have my app open in the background monitoring the number pad for presses, every time I press a number key on the number pad I want to add that number to a text box for display purposes. 例)我每次在后台按数字键盘上的数字键时,都会在后台打开我的应用程序,监视数字键盘的压力,以便将该数字添加到文本框中以进行显示。 Now I have chrome open and have the cursor in the address bar, I want to be able to press the number keys while having my app handle them but not having them show up in chromes address bar. 现在,我打开了chrome浏览器,并将光标放在地址栏中,我希望能够在让我的应用程序处理数字键的同时按下数字键,但又不想让它们显示在chromes地址栏中。

Thanks. 谢谢。

This is basically a very simplistic key logger. 这基本上是一个非常简单的按键记录器。

EDIT) Keyboard Hook 编辑)键盘挂钩

#endregion
using System;
using System.Text;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;   

public class GlobalKeyboardHook
{
[DllImport("user32.dll")]
static extern int CallNextHookEx(IntPtr hhk, int code, int wParam, ref keyBoardHookStruct lParam);
[DllImport("user32.dll")]
static extern IntPtr SetWindowsHookEx(int idHook, LLKeyboardHook callback, IntPtr hInstance, uint theardID);
[DllImport("user32.dll")]
static extern bool UnhookWindowsHookEx(IntPtr hInstance);
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string lpFileName);

public delegate int LLKeyboardHook(int Code, int wParam, ref keyBoardHookStruct lParam);

public struct keyBoardHookStruct
{
    public int vkCode;
    public int scanCode;
    public int flags;
    public int time;
    public int dwExtraInfo;
}

const int WH_KEYBOARD_LL = 13;
const int WM_KEYDOWN = 0x0100;
const int WM_KEYUP = 0x0101;
const int WM_SYSKEYDOWN = 0x0104;
const int WM_SYSKEYUP = 0x0105;

LLKeyboardHook llkh;
public List<Keys> HookedKeys = new List<Keys>();

IntPtr Hook = IntPtr.Zero;

public event KeyEventHandler KeyDown;
public event KeyEventHandler KeyUp;

public GlobalKeyboardHook()
{
    llkh = new LLKeyboardHook(HookProc);
    hook();
}
~GlobalKeyboardHook()
{ unhook(); }

public void hook()
{
    IntPtr hInstance = LoadLibrary("User32");
    Hook = SetWindowsHookEx(WH_KEYBOARD_LL, llkh, hInstance, 0);
}

public void unhook()
{
    UnhookWindowsHookEx(Hook);
}

public int HookProc(int Code, int wParam, ref keyBoardHookStruct lParam)
{
    if (Code >= 0)
    {
        Keys key = (Keys)lParam.vkCode;
        if (HookedKeys.Contains(key))
        {
            KeyEventArgs kArg = new KeyEventArgs(key);
            if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null))
                KeyDown(this, kArg);
            else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null))
                KeyUp(this, kArg);
            if (kArg.Handled)
                return 1;
        }
    }
    return CallNextHookEx(Hook, Code, wParam, ref lParam);
}

}

Usage of GlobalKeyboardHook GlobalKeyboardHook的用法

GlobalKeyboardHook gHook;
private void Form1_Load(object sender, EventArgs e)
{
   gHook = new GlobalKeyboardHook(); // Create a new GlobalKeyboardHook
   // Declare a KeyDown Event
   gHook.KeyDown += new KeyEventHandler(gHook_KeyDown);
   // Add the keys you want to hook to the HookedKeys list
   foreach (Keys key in Enum.GetValues(typeof(Keys)))
       gHook.HookedKeys.Add(key);
}

// Handle the KeyDown Event
public void gHook_KeyDown(object sender, KeyEventArgs e)
{
   textBox1.Text += ((char)e.KeyValue).ToString();
}

private void button1_Click(object sender, EventArgs e)
{
   gHook.hook();
}

private void button2_Click(object sender, EventArgs e)
{
   gHook.unhook();
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
   gHook.unhook();
}

In your hookProc, you must not call return CallNextHookEx(Hook, Code, wParam, ref lParam); 在hookProc中,不得调用return CallNextHookEx(Hook, Code, wParam, ref lParam); if you dont want the WM_KEYS to propagate. 如果您不希望WM_KEYS传播。

If you do call CallNextHookEx, the messages will be propagated. 如果您致电CallNextHookEx,则消息将被传播。

Btw, you are aware that you are using a Global hook, and not a thread specific hook ? 顺便说一句,您知道您使用的是全局钩子,而不是特定于线程的钩子? So you are capturing ALL key presses, and not only the ones relative to your app. 因此,您将捕获所有按键,而不仅仅是与您的应用程序相关的按键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM