ホットキーへ登録する

過去のブログのアーカイブ
この記事は前身のブログのアーカイブを引き継いだものです. 画像が正しく表示できないなど,コンテンツの表示に問題がある恐れがあります.

C/VB.NETでホットキーへ簡単に登録できるライブラリを作ってみた。ホットキーへの登録自体は簡単なものの、汎用性の高いクラスを作るとなると少々面倒になるのでライブラリ化にしてみました。コンソールでも使うことができ、フォームを作らなくても単体で動作します。

ソースコード

WinAPIコード

適当なクラスへ入れてください。HotKeyクラスの中に入れても問題ありません

public partial class NativeMethod{    // ホットキー    [DllImport("user32.dll")]    public static extern int RegisterHotKey(IntPtr HWnd, int ID, int MOD_KEY, int KEY);    [DllImport("user32.dll")]    public static extern int RegisterHotKey(IntPtr HWnd, int ID, MOD MOD_KEY, Keys KEY);    [DllImport("user32.dll")]    public static extern int UnregisterHotKey(IntPtr HWnd, int ID);}

ソースコード本体

かなり長いです。ダウンロードすることもできます。名前空間は適当にいじってどうぞ[wpdm_file id=7]

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows.Forms;using WinAPI.Const;namespace WinAPI.Manager{    public class HotKey : IDisposable    {        private HotkeyForm hWnd = null;        public int ID { get; private set; }        public Keys Keys { get; private set; }        public bool Enabled { get; private set; }        public event EventHandler HotkeyEvent;        private HotKey() { }        public HotKey(Keys key)        {            this.Keys = key;            Register();        }        ~HotKey()        {            this.Dispose();        }        public void Dispose(){            this.Unregister();        }        private void Register() {            if (hWnd == null)            {                hWnd = new HotkeyForm();                hWnd.CreateHandle(new CreateParams());            }            if (!this.Enabled)            {                MOD modifiers = 0;                if ((this.Keys & Keys.Alt) == Keys.Alt)                    modifiers = modifiers | MOD.MOD_ALT;                if ((this.Keys & Keys.Control) == Keys.Control)                    modifiers = modifiers | MOD.MOD_CONTROL;                if ((this.Keys & Keys.Shift) == Keys.Shift)                    modifiers = modifiers | MOD.MOD_SHIFT;                Keys k = this.Keys & ~Keys.Control & ~Keys.Shift & ~Keys.Alt;                this.ID = (new Random()).Next(0x1000, 0xbfff);                NativeMethod.RegisterHotKey(hWnd.Handle, this.ID, modifiers, k);                this.Enabled = true;                hWnd.Handler += this.hWndHotkeyEvent;            }        }        private void Unregister()        {            if (this.Enabled)            {                NativeMethod.UnregisterHotKey(hWnd.Handle, this.ID);                this.ID = 0;                this.Enabled = false;                hWnd.Handler -= this.hWndHotkeyEvent;            }        }                private void hWndHotkeyEvent(int id)        {            if (this.ID == id && HotkeyEvent != null)            {                HotkeyEvent(this, EventArgs.Empty);            }        }        internal class HotkeyForm : NativeWindow        {            internal HotkeyForm()            {            }            internal delegate void HotkeyHandler(int id);            internal event HotkeyHandler Handler;            protected override void WndProc(ref Message m)            {                if (m.Msg == (int)WM.WM_HOTKEY)                {                    if (Handler != null)                        Handler((int)m.WParam);                }                base.WndProc(ref m);            }        }    }}

 使い方

F11を押したらコンソールに「Push HotKey」と表示するサンプル

HotKey ScreenHotkey = new HotKey(Keys.F11);ScreenHotkey.HotkeyEvent += (sender, e) =>     {        Console.WriteLine("Push HotKey");    };

たったの5行で動作部分までかけちゃいました。クラスを初期化した時点でホットキーへ登録されます。

仕組み

ホットキーへの登録はRegisterHotKeyを、ホットキーの削除はUnregisterHotKeyを使えばいいだけなのですが、ホットキーが押されたという通知はWndProcで渡されるため、ウィンドウを作ってあげる必要が出てきます。そのため、ほとんどのホットキーに関するサンプルソースコードではコンポーネントだったりコントロールとして作っています。ですが、私のこの方法だと専用のメッセージのみのウィンドウを生成してやるため、コンソールでも動作するというわけです。ただし、コンソールで動作させる場合は念のためMainメソッドにSTAThreadAttributeを付ける必要があります。main-staまた、ホットキーのIDは自動生成です。乱数で適当に決めています。なお、IDisposableインターフェースを実装しているため、破棄処理が確実にできるので安心して使うことができます。