.NET TIPS

Windowsアプリケーションで方向キーなどの特殊キーを処理するには?

デジタルアドバンテージ
2004/12/10

 「TIPS:コントロールに対するキー入力をフォームで処理するには?」では、フォームのKeyDownイベント・ハンドラで、コントロール上のキー入力を一括処理する方法を紹介した。

 しかし、例えばButtonコントロールにフォーカスがあるときに入力した[↑][↓][→][←]などの方向キーは、この方法では処理することができない。そこで、本稿ではそのようなキー入力を処理する方法を紹介する。

Buttonコントロールで方向キーが処理できない理由

 Buttonコントロールでの方向キーの入力が、通常のKeyDownなどのキー・イベントで処理できないということは、「方向キーが通常の入力キー(以降、普通入力キー)とは異なる」ことを意味する。Buttonコントロールの方向キーは「プリプロセス(=前処理)を必要とする特殊な入力キー」(以降、特殊入力キー)である。

 .NET Frameworkで構築されたWindowsアプリケーションでは、入力されたキーは、通常のKeyDownなどのキー・イベント処理の実行前に、「プリプロセス」と呼ばれる処理工程を通過する。このプリプロセスの工程で処理された入力キーは、基本的に、その後のKeyDownなどのキー・イベント処理が実行されない。

 これは、すでにプリプロセスで何らかの処理を実行済みなので、さらにその後でキー処理を行う必要がないからだ。例えば、Buttonコントロールで[↓]キーを押すと、Windowsアプリケーションはプリプロセス工程で自動的にフォーカス移動の処理を実行する。よって、その後でKeyDownイベントを処理する必要はなくなる。

 しかし、実際のアプリケーションでは、そのような通常のアプリケーション動作をカスタマイズしたい場合がある。例えば、通常のアプリケーション動作では[↓]キーでフォーカス移動すると、そのフォーカス移動先がGroupBoxコントロールなどにより設定されたグループ内でループするようになっているが、それをカスタマイズして、グループを越えてフォーカス移動するようにしたい場合などが挙げられる。

 そのような場合、次の2種類の方法のいずれかを選択できる。

  1. プリプロセス工程における処理をカスタマイズする
  2. 特殊入力キーを普通入力キーに変更する

 この2つの方法についてそれぞれ解説していこう。

 なお、プリプロセスにより処理される特殊入力キー(「ダイアログ・キー」と呼ばれる)は、方向キーのほかに、[PageUp][PageDown][Esc][Tab][Enter]などのキーがある(ただし特殊入力キーはコントロールにより異なる場合があるので注意が必要だ)。これらのキーを入力すると、特に何も実装しなくてもフォーム上でフォーカス移動などが可能なのは、プリプロセス工程で何らかの処理が実行されているおかげである。

1. プリプロセスにおける処理をカスタマイズする

 プリプロセスをカスタマイズするには、フォームのProcessDialogKeyメソッドをオーバーライドして、そのメソッド内でキー処理を行えばよい。もちろんフォームではなく、コントロールのProcessDialogKeyメソッドをオーバーライドしても同様の結果が得られる。

 次のコードは、実際に、フォームのProcessDialogKeyメソッドをオーバーライドした例である。この例では、方向キーでグループを越えたフォーカス移動を行うように、処理をカスタマイズしている。

protected override bool ProcessDialogKey(Keys keyData)
{
  switch (keyData)
  {
    case Keys.Down:
    case Keys.Right:
      this.SelectNextControl(
        this.ActiveControl, true, true, true, true);
      break;
    case Keys.Up:
    case Keys.Left:
      this.SelectNextControl(
        this.ActiveControl, false, true, true, true);
      break;
    default:
      return base.ProcessDialogKey(keyData);
      break;
  }
  return true;
}
ProcessDialogKeyメソッドをオーバーライドしたサンプル・プログラム(C#)
 
Protected Overrides Function ProcessDialogKey(ByVal keyData As Keys) As Boolean
  Select Case keyData
    Case Keys.Down
      Me.SelectNextControl( _
        Me.ActiveControl, True, True, True, True)
    Case Keys.Right
      Me.SelectNextControl( _
        Me.ActiveControl, True, True, True, True)
    Case Keys.Up
      Me.SelectNextControl( _
        Me.ActiveControl, False, True, True, True)
    Case Keys.Left
      Me.SelectNextControl( _
        Me.ActiveControl, False, True, True, True)
    Case Else
      Return MyBase.ProcessDialogKey(keyData)
  End Select
  Return True
End Function
ProcessDialogKeyメソッドをオーバーライドしたサンプル・プログラム(VB.NET)

 なお、ProcessDialogKeyメソッドはコントロール→フォームの順で呼ばれる。ProcessDialogKeyメソッドでは、独自にキーを処理した場合には、それを示すために戻り値でTrueを返すようにする。

 また、コントロールのProcessDialogKeyメソッドは、コントロールのPreProcessMessageメソッドから暗黙的に呼び出される。そのため、プリプロセス工程の最初のメソッドであるコントロールのPreProcessMessageメソッドをオーバーライドしても、同様にプリプロセス工程でのキー処理をカスタマイズできる。しかし、コントロールのProcessDialogKeyメソッドやPreProcessMessageメソッドをオーバーライドする方法を採用する場合、当然、コントロールの継承が必要になる。

2. 特殊入力キーを普通入力キーに変更する

 次にプリプロセスが必要な特殊入力キーを普通のキー入力に変更する方法を説明する。

 この方法では、コントロールのIsInputKeyメソッドをオーバーライドするため、コントロールの継承が必要になる。IsInputKeyメソッドはプリプロセス中に呼び出されるメソッドで、その戻り値でTrueを返すようにすると、そのキーは特殊入力キーではなく、普通入力キーとして取り扱われ、プリプロセス処理(例えば、ProcessDialogKeyメソッドの呼び出し)が行われずに、通常のキー・イベントが発生するようになる。

 次のコードは、実際に、ButtonコントロールのIsInputKeyメソッドをオーバーライドした例だ。この例では、方向キーが通常のキー・イベントで処理されるようにカスタマイズしている。これにより、方向キーの処理をKeyDownイベント・ハンドラで実装することが可能になる。

protected override bool IsInputKey(Keys keyData)
{
  switch (keyData)
  {
    case Keys.Down:
    case Keys.Right:
    case Keys.Up:
    case Keys.Left:
      break;
    default:
      return base.IsInputKey(keyData);
      break;
  }
  return true;
}
特殊入力キーを普通入力キーに変更するサンプル・プログラム(C#)
 
Protected Overrides Function IsInputKey(ByVal keyData As Keys) As Boolean
  Select Case keyData
    Case Keys.Down
    Case Keys.Right
    Case Keys.Up
    Case Keys.Left
    Case Else
      Return MyBase.IsInputKey(keyData)
  End Select
  Return True
End Function
特殊入力キーを普通入力キーに変更するサンプル・プログラム(VB.NET)

 以上の2つの方法の中でも、前者のProcessDialogKeyメソッドをオーバーライドする方法が、最も単純で実装も楽だろう。

特殊入力「文字」(Char)について

 なお、今回紹介したProcessDialogKeyメソッドやIsInputKeyメソッドに類似した名前のメソッドに次のものがある。

  • ProcessDialogCharメソッド
  • IsInputCharメソッド

 ProcessDialogCharメソッドは、今回のProcessDialogKeyメソッドと同様にプリプロセス工程で呼び出されるが、このメソッドはコントロールのニーモニック(=アクセス・キー)などのダイアログ文字を処理する(例えば、[Alt]+[T]キーなどのアクセス・キーは、このメソッドにより処理される)。入力されたキー(Keys列挙対の値。キー・コード)に対応する「文字」(Char構造体の値。文字コード)が、このような「プリプロセスが必要な特殊入力文字」の場合(つまり、IsInputCharメソッドの戻り値がFalseを返す場合)、ProcessDialogCharメソッドがその入力文字を処理する。ProcessDialogCharメソッドでは、文字を独自に処理した場合には、それを示すために戻り値でTrueを返すようにする。

 特殊入力文字を処理するためには、キー処理の場合と同じように、次の方法のいずれかを実装すればよい。

  1. プリプロセス工程における処理をカスタマイズする
  2. 特殊入力文字を普通入力文字に変更する

 1を行うには、フォームやコントロールのProcessDialogCharメソッドをオーバーライドすればよい。2を行うには、コントロールのIsInputCharメソッドをオーバーライドすればよい。End of Article

カテゴリ:Windowsフォーム 処理対象:キーボード
使用ライブラリ:Formクラス(System.Windows.Forms名前空間)
使用ライブラリ:Controlクラス(System.Windows.Forms名前空間)
使用ライブラリ:Keys列挙体(System.Windows.Forms名前空間)
関連TIPS:コントロールに対するキー入力をフォームで処理するには?
 
この記事と関連性の高い別の.NET TIPS
Windowsアプリケーションでキー処理が行われる順序は?
コントロールに対するキー入力をフォームで処理するには?
Windowsアプリケーションで[Enter]キーによるフォーカス移動を行うには?
AcceptButtonプロパティ設定時にテキストボックス内で改行を行うには?
Windowsアプリのコントロールで[Tab]キーによるフォーカスを与えないようにするには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間