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

kkAyatakaのメモ帳。

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

WPFでHotKeyBox

Windows

ホットキー用のコントロールを自前で作る際のポイント。TextBoxのオーバーライドとかは必要なくて、UserControlから十分作れそうな感じ。

ポイントはPreviewKeyDownで処理すること。KeyDownだとCtrl+Aで全選択されたり、特定のキーを拾えなかったりする。

this.textBox.PreviewKeyDown += textBox_PreviewKeyDown;

private void textBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
  e.Handled = true;
  
  var mod = e.KeyboardDevice.Modifiers;
  mod |= e.KeyboardDevice.IsKeyDown(Key.LWin) ? ModifierKeys.Windows : ModifierKeys.None;
  mod |= e.KeyboardDevice.IsKeyDown(Key.RWin) ? ModifierKeys.Windows : ModifierKeys.None;

  // 使えるキーは絞ったほうが良いかも 
  var key = IsValidKey(e.Key) ? e.Key : Key.None;

  // ...本来はこのあたりで、登録可能かチェックする
  
  // キーの押下状態からテキストを作る
  textBox.Text = GetHotKeyText(mod, key);
}

WPFだとイベントオブジェクトにKeyboardDeviceがあるのでキー状態を見るのに使える。Windows Formsだと代替するものが無いので、Win32GetKeyboardStateを使ってしまうのが楽だった。

標準だとWinキーが取れないので、キーボードの状態を調べて修飾キーに加えてやる。XPの時ほど空いてないけど、個人的にこれが無いと始まらない感じ。

このやり方でそれなりにうまく動くところまでは確認できているけど、厳密にチェックしていくと穴はあるかも。ただ、ある程度はフォローできそうだと思っているし、機能的にも十分かなーとは思ってます。