LoginSignup
7

More than 5 years have passed since last update.

C#でSetWindowsHookEx(KEYBOARD_LL,...)をしてみる。

Posted at
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace Testhook
{
    static class TestHook{
        [STAThread]
            static void Main(string[] args)
            {
                Application.Run(new MainForm());
            }
    }

    class MainForm : Form{
        public delegate int HookHandler(int code, IntPtr message, IntPtr state);

        [DllImport("user32.dll", SetLastError = true)]
            public static extern IntPtr SetWindowsHookEx(int hookType, HookHandler hookDelegate, IntPtr module, uint threadId);

        [DllImport("user32.dll", SetLastError = true)]
            public static extern bool UnhookWindowsHookEx(IntPtr hook);

        [DllImport("user32.dll")]
            public static extern int CallNextHookEx(IntPtr hook, int code, IntPtr message, IntPtr state);

        [StructLayout(LayoutKind.Sequential)]
            public class KBDLLHOOKSTRUCT
            {
                public uint vkCode;
                public uint scanCode;
                public KBDLLHOOKSTRUCTFlags flags;
                public uint time;
                public UIntPtr dwExtraInfo;
            }

        [Flags]
            public enum KBDLLHOOKSTRUCTFlags : uint {
                LLKHF_EXTENDED = 0x01,
                LLKHF_INJECTED = 0x10,
                LLKHF_ALTDOWN = 0x20,
                LLKHF_UP = 0x80,
            }

        HookHandler hookDelegate;
        IntPtr hook;

        public MainForm()
        {
            const int KEYBOARD_LL = 13;
            hookDelegate = new HookHandler(OnHook);
            IntPtr hMod = Marshal.GetHINSTANCE( System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]);
            hook = SetWindowsHookEx(KEYBOARD_LL, hookDelegate, hMod, 0);
            if (hook == IntPtr.Zero){
                int errorCode = Marshal.GetLastWin32Error();
                throw new Win32Exception(errorCode);
            }
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
            if (hook != IntPtr.Zero)
            {
                UnhookWindowsHookEx(hook);
            }
        }

        int OnHook(int nCode, IntPtr wParam, IntPtr lParam)
        {
            KBDLLHOOKSTRUCT kb = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));

            Console.WriteLine("vkCode={0}", kb.vkCode);

            return CallNextHookEx(hook, nCode, wParam, lParam);
        }
    }
}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7