using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApp9
{
    //Microsoft Hook Document
    //https://docs.microsoft.com/en-us/windows/win32/winmsg/hooks

    public partial class Form1 : Form
    {
        private HookManager hookManager = new HookManager();

        public Form1()
        {
            InitializeComponent();

            this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form1_FormClosed);
            hookManager.SetHook();
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            hookManager.UnHook(); //프로그램이 종료될 때 반드시 후킹을 꺼줘야합니다.
        }
    }

    public class HookManager
    {
        #region WindowsAPI

        [DllImport("user32.dll")]
        private static extern int SetWindowsHookEx(int idHook, LowLevelKeyboardProc callback, int hInstance, uint threadId);

        [DllImport("user32.dll")]
        private static extern bool UnhookWindowsHookEx(int hInstance);

        [DllImport("user32.dll")]
        private static extern int CallNextHookEx(int idHook, int nCode, int wParam, ref HookStruct lParam);

        [DllImport("kernel32.dll")]
        private static extern int LoadLibrary(string lpFileName);

        private delegate int LowLevelKeyboardProc(int nCode, int wParam, ref HookStruct lParam);
        private LowLevelKeyboardProc lowLevelKeyboardProc = HookProc;

        #endregion

        //구조체 크기를 맞춰줘야 올바른 값을 받을 수 있습니다.
        public struct HookStruct
        {
            public int vkCode;
            int scanCode;
            public int flags;
            int time;
            int dwExtraInfo;
        }

        //WM_Keydown
        //https://wiki.winehq.org/List_Of_Windows_Messages
        const int WH_KEYBOARD_LL = 13; //저수준 특수키 관련 Alt + .. Ctrl + ..
        const int WM_KEYDOWN = 256;
        const int WM_KEYUP = 257;
        const int WM_SYSKEYDOWN = 260;
        const int WM_SYSKEYUP = 261;

        private static int hookId = 0;

        public void SetHook()
        {
            int hInstance = LoadLibrary("User32");
            hookId = SetWindowsHookEx(WH_KEYBOARD_LL, lowLevelKeyboardProc, hInstance, 0);
        }

        public void UnHook()
        {
            UnhookWindowsHookEx(hookId);
        }

        public static int HookProc(int code, int wParam, ref HookStruct lParam)
        {
            if (code >= 0)
            {
                switch (wParam)
                {
                    case WM_KEYDOWN:
                    case WM_KEYUP:
                    case WM_SYSKEYDOWN:
                    case WM_SYSKEYUP:

                        Keys key = (Keys)lParam.vkCode;

                        if ((key == Keys.Tab    && lParam.flags == 32) ||   // Alt+Tab
                            (key == Keys.Escape && lParam.flags == 32) ||   // Alt+Esc
                            (key == Keys.F4     && lParam.flags == 32) ||   // Alt+F4
                            (key == Keys.Escape && lParam.flags == 0)  ||   // Ctrl+Esc
                            (key == Keys.LWin   && lParam.flags == 1)  ||   // Left Windows Key 
                            (key == Keys.RWin   && lParam.flags == 1))      // Right Windows Key 
                        {
                            return 1; //Do not handle key events
                        }
                        break;
                }
            }

            return CallNextHookEx(hookId, code, (int)wParam, ref lParam);
        }
    }
}

 

+ Recent posts