ちょっと備忘録2

いつか整理します

public class HotKey
    : IDisposable
{
    public enum MOD_KEY : int
    {
        NONE = 0x0000,
        ALT = 0x0001,
        CONTROL = 0x0002,
        SHIFT = 0x0004,
    }

    private HotKeyForm form;

    public event EventHandler HotKeyPushEventHandler;

    public HotKey(MOD_KEY modKey, Keys key)
    {
        this.form = 
            new HotKeyForm(modKey, key,
                () =>
                {
                    var ev = this.HotKeyPushEventHandler;
                    if (ev != null)
                        ev(this, EventArgs.Empty);
                });
    }

    #region Dispose パターンの実装

    private bool disposed = false;

    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposed)
            return;

        if (disposing)
        {
            // Free any other managed objects here.
            this.form.Dispose();
        }

        // Free any unmanaged objects here.
        //
        disposed = true;
    }

    ~HotKey()
    {
        this.Dispose(false);
    }

    #endregion

    private class HotKeyForm
        : Form
    {
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        extern static int RegisterHotKey(IntPtr HWnd, int ID, MOD_KEY MOD_KEY, Keys KEY);

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        extern static int UnregisterHotKey(IntPtr HWnd, int ID);

        private const int WM_HOTKEY = 0x0312;
        private int id;
        private Action action;

        public HotKeyForm(MOD_KEY modKey, Keys key, Action action)
        {
            this.action = action;
            for (int i = 0x0000; i <= 0xbfff; i++)
            {
                if (RegisterHotKey(this.Handle, i, modKey, key) != 0)
                {
                    id = i;
                    break;
                }
            }
        }

        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);

            if (m.Msg == WM_HOTKEY)
            {
                if ((int)m.WParam == id)
                {
                    action();
                }
            }
        }

        protected override void Dispose(bool disposing)
        {
            UnregisterHotKey(this.Handle, id);
            base.Dispose(disposing);
        }

    }
}