我的键盘钩子捕获了所有键

时间:2016-06-17 06:33:24

标签: c#

using System;

using System.ComponentModel;

using System.Diagnostics;

using System.Runtime.InteropServices;

using System.Windows.Forms;

namespace ScreenYos
{
public class KeyboardHook : IDisposable
{
    private bool Global = false;

    public delegate void LocalKeyEventHandler(Keys key, bool Printscreen);

    public event LocalKeyEventHandler KeyDown;
    public event LocalKeyEventHandler KeyUp;

    public delegate int CallbackDelegate(int Code, int W, int L);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct KBDLLHookStruct
    {
        public Int32 vkCode;
        public Int32 scanCode;
        public Int32 flags;
        public Int32 time;
        public Int32 dwExtraInfo;
    }

    [DllImport("user32", CallingConvention = CallingConvention.StdCall)]
    private static extern int SetWindowsHookEx(HookType idHook, CallbackDelegate lpfn, int hInstance, int threadId);

    [DllImport("user32", CallingConvention = CallingConvention.StdCall)]
    private static extern bool UnhookWindowsHookEx(int idHook);

    [DllImport("user32", CallingConvention = CallingConvention.StdCall)]
    private static extern int CallNextHookEx(int idHook, int nCode, int wParam, int lParam);

    [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall)]
    private static extern int GetCurrentThreadId();

    public enum HookType : int
    {
        WH_JOURNALRECORD = 0,
        WH_JOURNALPLAYBACK = 1,
        WH_KEYBOARD = 2,
        WH_GETMESSAGE = 3,
        WH_CALLWNDPROC = 4,
        WH_CBT = 5,
        WH_SYSMSGFILTER = 6,
        WH_MOUSE = 7,
        WH_HARDWARE = 8,
        WH_DEBUG = 9,
        WH_SHELL = 10,
        WH_FOREGROUNDIDLE = 11,
        WH_CALLWNDPROCRET = 12,
        WH_KEYBOARD_LL = 13,
        WH_MOUSE_LL = 14
    }

    private int HookID = 0;
    private CallbackDelegate TheHookCB = null;

    public KeyboardHook(bool Global)
    {
        this.Global = Global;
        TheHookCB = new CallbackDelegate(KeybHookProc);
        if (Global)
        {
            HookID = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, TheHookCB,
                0, 
                0); 
        }
        else
        {
            HookID = SetWindowsHookEx(HookType.WH_KEYBOARD, TheHookCB,
                0, 
                GetCurrentThreadId()); 
        }
    }

    private bool IsFinalized;

    ~KeyboardHook()
    {
        if (!IsFinalized)
        {
            UnhookWindowsHookEx(HookID);
            IsFinalized = true;
        }
    }

    public void Dispose()
    {
        if (!IsFinalized)
        {
            UnhookWindowsHookEx(HookID);
            IsFinalized = true;
        }
    }


    private int KeybHookProc(int Code, int W, int L)
    {
        KBDLLHookStruct LS = new KBDLLHookStruct();
        if (Code < 0)
        {
            return CallNextHookEx(HookID, Code, W, L);
        }
        try
        {
            if (!Global)
            {
                if (Code == 3)
                {
                    IntPtr ptr = IntPtr.Zero;

                    int keydownup = L >> 30;
                    if (keydownup == 0)
                    {
                        if (KeyDown != null)
                            KeyDown((Keys) W, GetPrintscreenPressed());
                    }
                    if (keydownup == -1)
                    {
                        if (KeyUp != null) KeyUp((Keys) W, GetPrintscreenPressed());
                    }
                    //System.Diagnostics.Debug.WriteLine("KeyDown: " + (Keys)W);
                }
            }
            else
            {
                KeyEvents kEvent = (KeyEvents) W;

                Int32 vkCode = Marshal.ReadInt32((IntPtr) L);

                if (kEvent != KeyEvents.KeyDown && kEvent != KeyEvents.KeyUp && kEvent != KeyEvents.SKeyDown &&
                    kEvent != KeyEvents.SKeyUp)
                {
                }
                if (kEvent == KeyEvents.KeyDown || kEvent == KeyEvents.SKeyDown)
                {
                    if (KeyDown != null)
                        KeyDown((Keys) vkCode, GetPrintscreenPressed());
                }
                if (kEvent == KeyEvents.KeyUp || kEvent == KeyEvents.SKeyUp)
                {
                    if (KeyUp != null) KeyUp((Keys) vkCode, GetPrintscreenPressed());
                }
            }
        }
        catch (Exception e)
        {
            //Console.WriteLine(e.Message);
        }

        return CallNextHookEx(HookID, Code, W, L);

    }

    public enum KeyEvents
    {
        KeyDown = 0x0100,
        KeyUp = 0x0101,
        SKeyDown = 0x0104,
        SKeyUp = 0x0105
    }

    [DllImport("user32.dll")]
    public static extern short GetKeyState(Keys nVirtKey);

    public static bool GetPrintscreenPressed()
    {
        int state = GetKeyState(Keys.PrintScreen);
        if (state > 1 || state < -1) return true;
        return false;
    }
}

}

我的用法:

    private static void Kh_KeyDown(Keys key, bool Printscreen)
    {
        if (new Form1().ShowDialog() == DialogResult.OK)
        {
        Application.Run(new Form1());
        }
    }

因此程序在系统托盘中运行,代码的目标是全局捕获键,当按下printscreen时运行Form1但它会捕获每个键,无论按什么键,它都运行form1。

1 个答案:

答案 0 :(得分:0)

我认为这是因为你初始化了KeyDown上所有Key的一般回调。

您必须在调用事件时按Keys.PrintScreen进行过滤

在Eventhandler中按Keys.PrintScreen过滤。

private static void Kh_KeyDown(Keys key, bool Printscreen)
{
    if (key == Keys.PrintScreen && new Form1().ShowDialog() == DialogResult.OK)
    {
        Application.Run(new Form1());
    }
}

托马斯