코딩/C#

[C#] Global Keyboard Hooking

버딩 2017. 3. 23. 18:40
반응형
class globalKeyboardHook
{
    #region Constant, Structure and Delegate Definitions
    /// 
    /// defines the callback type for the hook
    /// 
    public delegate int keyboardHookProc(int code, int wParam, ref keyboardHookStruct lParam);
    private static keyboardHookProc callbackDelegate;

    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 = 0x100;
    const int WM_KEYUP = 0x101;
    const int WM_SYSKEYDOWN = 0x104;
    const int WM_SYSKEYUP = 0x105;
    #endregion

    #region Instance Variables
    /// 
    /// The collections of keys to watch for
    /// 
    public List HookedKeys = new List();
    /// 
    /// Handle to the hook, need this to unhook and call the next hook
    /// 
    IntPtr hhook = IntPtr.Zero;
    #endregion

    #region Events
    /// 
    /// Occurs when one of the hooked keys is pressed
    /// 
    public event KeyEventHandler KeyDown;
    /// 
    /// Occurs when one of the hooked keys is released
    /// 
    public event KeyEventHandler KeyUp;
    #endregion

    #region Constructors and Destructors
    /// 
    /// Initializes a new instance of the  class and installs the keyboard hook.
    /// 
    public globalKeyboardHook()
    {
        hook();
    }

    /// 
    /// Releases unmanaged resources and performs other cleanup operations before the
    ///  is reclaimed by garbage collection and uninstalls the keyboard hook.
    /// 
    ~globalKeyboardHook()
    {
        unhook();
    }
    #endregion

    #region Public Methods
    /// 
    /// Installs the global hook
    /// 
    public void hook()
    {
        if (callbackDelegate != null) throw new InvalidOperationException("Can't hook more than once");
        IntPtr hInstance = LoadLibrary("User32");
        callbackDelegate = new keyboardHookProc(hookProc);
        hhook = SetWindowsHookEx(WH_KEYBOARD_LL, callbackDelegate, hInstance, 0);
        if (hhook == IntPtr.Zero) throw new Win32Exception();
    }

    /// 
    /// Uninstalls the global hook
    /// 
    public void unhook()
    {
        if (callbackDelegate == null) return;
        bool ok = UnhookWindowsHookEx(hhook);
        if (!ok) throw new Win32Exception();
        callbackDelegate = null;
        //UnhookWindowsHookEx(hhook);
    }

    /// 
    /// The callback for the keyboard hook
    /// 
    /// The hook code, if it isn't >= 0, the function shouldn't do anyting
    /// The event type
    /// The keyhook event information
    /// 
    public int hookProc(int code, int wParam, ref keyboardHookStruct lParam)
    {
        if (code >= 0)
        {
            Keys key = (Keys)lParam.vkCode;
            if (HookedKeys.Contains(key))
            {
                KeyEventArgs kea = new KeyEventArgs(key);
                if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null))
                {
                    KeyDown(this, kea);
                }
                else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null))
                {
                    KeyUp(this, kea);
                }
                if (kea.Handled)
                    return 1;
            }
        }
        return CallNextHookEx(hhook, code, wParam, ref lParam);
    }
    #endregion

    #region DLL imports
    /// 
    /// Sets the windows hook, do the desired event, one of hInstance or threadId must be non-null
    /// 
    /// The id of the event you want to hook
    /// The callback.
    /// The handle you want to attach the event to, can be null
    /// The thread you want to attach the event to, can be null
    /// a handle to the desired hook
    [DllImport("user32.dll")]
    static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId);

    /// 
    /// Unhooks the windows hook.
    /// 
    /// The hook handle that was returned from SetWindowsHookEx
    /// True if successful, false otherwise
    [DllImport("user32.dll")]
    static extern bool UnhookWindowsHookEx(IntPtr hInstance);

    /// 
    /// Calls the next hook.
    /// 
    /// The hook id
    /// The hook code
    /// The wparam.
    /// The lparam.
    /// 
    [DllImport("user32.dll")]
    static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref keyboardHookStruct lParam);

    /// 
    /// Loads the library.
    /// 
    /// Name of the library
    /// A handle to the library
    [DllImport("kernel32.dll")]
    static extern IntPtr LoadLibrary(string lpFileName);
    #endregion
}
//
선언
globalKeyboardHook gkh = new globalKeyboardHook();

void gkh_KeyUp(object sender, KeyEventArgs e)
{
    e.Handled = true;
}

void gkh_KeyDown(object sender, KeyEventArgs e)
{
    e.Handled = true;
}

//폼로드에 이벤트 선언
gkh.HookedKeys.Add(Keys.Down);
gkh.HookedKeys.Add(Keys.Up);
gkh.KeyDown += new KeyEventHandler(gkh_KeyDown);
gkh.KeyUp +=new KeyEventHandler(gkh_KeyUp);
메인
반응형
댓글수0