読者です 読者をやめる 読者になる 読者になる

kkAyatakaのメモ帳。

誰かの役に立つかもしれない備忘録。

WPFでHot Key

WPFでHot Keyを取り扱う方法です。登録自体はWin32を用いますが、仮想キーの取り扱いやWindow Handleの取得方法なども課題になります。

順番に。登録・解除はWin32

using System.Runtime.InteropServices;

[DllImport("User32.dll")]
private static extern bool RegisterHotKey(IntPtr wnd, int id, int modifiers, int vk);

[DllImport("User32.dll")]
private static extern bool UnregisterHotKey(IntPtr wnd, int id);

キーコードは組み込みのEnumを用い、関数を使ってRegisterHotKeyに渡す仮想キーを得ます。逆変換の関数もあるので、Hot Keyのマネージメントをするクラスのみ仮想キーに依存するようにするのが良いでしょう。

using System.Windows.Input;

ModifierKeys mod;
Key key;

var vkey = KeyInterop.VirtualKeyFromKey(key);
key = KeyInterop.KeyFromVirtualKey(vkey);

Window HandleとWindow Messageの受け取りは次のとおり。Windows Formsと違ってちょっと面倒。

using System.Windows.Interop;

var wnd = new Window();
wnd.Show();

// Show()の後で無いと取れません。
var handle = new WindowInteropHelper(wnd).Handle;
var src = HwndSource.FromHwnd(handle);
src.AddHook(MessageHook);

private IntPtr MessageHook(IntPtr hwnd, int msg, IntPtr wp, IntPtr lp, ref bool handle)
{
  if (msg == 0x0312) // WM_HOTKEY
  {
    handle = true;

    int id = wp.ToInt32();
    int vkey = ((lp.ToInt32() >> 16) & 0x0000FFFF);
    int mod  = ((lp.ToInt32() >>  0) & 0x0000FFFF);
  }
  return IntPtr.Zero;
}

以上を組み合わせれば実現できます。組み上げ方はいろいろあるとは思いますが、私はdelegateを登録できるようにして、使用しました。

public Boolean Register(ModifierKeys mod, Key key, HotKeyEventHandler handler);