Фоновые сочетания клавиш, которые не распространяются на окна - PullRequest
0 голосов
/ 28 февраля 2012

Я сделал приложение, которое должно обрабатывать определенные нажатия клавиш, даже когда окно не активно, теперь у меня есть это, и оно прекрасно работает; однако обработанные ключи все еще распространяются на окна (не уверен, что мое приложение обрабатывает их в первую очередь, так что я могу быть в обратном направлении).

Есть ли способ получить его, чтобы мое приложение могло обрабатывать нажатия клавиш, которые я хочу, но не позволяет отправлять ключи в текущее приложение / windows.

EX) У меня в фоновом режиме открыто приложение, контролирующее цифровую клавиатуру для нажатий, каждый раз, когда я нажимаю цифровую клавишу на цифровой клавиатуре, я хочу добавить этот номер в текстовое поле для отображения. Теперь у меня открыт Chrome и курсор в адресной строке, я хочу иметь возможность нажимать цифровые клавиши, пока мое приложение обрабатывает их, но не отображать их в адресной строке chromes.

Спасибо.

Это в основном очень упрощенный регистратор ключей.

РЕДАКТИРОВАТЬ) Крючок для клавиатуры

#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);
}

}

Использование 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();
}

1 Ответ

1 голос
/ 29 февраля 2012

В вашем hookProc вы не должны вызывать return CallNextHookEx(Hook, Code, wParam, ref lParam);, если вы не хотите, чтобы WM_KEYS распространялся.

Если вы вызываете CallNextHookEx, сообщения будут распространяться.

Кстати, вы знаете, что используете глобальный хук, а не конкретный хук? Таким образом, вы фиксируете ВСЕ нажатия клавиш, а не только те, которые относятся к вашему приложению.

...