[.NET] 他のコントロールに押下キーの情報を渡す

アクティブでないウィンドウやコントロールに対してキーボードのキーを押したかのように情報を送るには、対象コントロールなどにフォーカスを当てて「SendKeys.Send」メソッド(または SendKeys.SendWait メソッド)を使うことによって送ることができます。

例えば、以下の例ではフォームがアクティブになっている状態でキーを押したときにテキストボックスに押したキー情報を送ってテキストを入力することができます。

private void form1_KeyPress(object sender, KeyPressEventArgs e)
{
  // アクティブなコントロールにキーを送るためフォーカスを当てる
  textBox1.Focus();
  SendKeys.SendWait(e.KeyChar.ToString());
}

フォームでキーが押されたときに Focus メソッドでテキストボックスにフォーカスを当て、SendKeys で押されたキーを送っています。送ったあとフォーカスを戻すのがベストだとは思いますが、必要に応じて入れてください。

基本的なコードはこれで OK なのですが、SendKeys では一部のコードが特殊な用途に使用されるキーであるため、このままでは送ることができません。対象キー、用途については以下の MSDN の SendKeys を参照してください。

特殊キーを通常の入力キーとして送るには中括弧({})で囲む必要があります。これを踏まえるとコードは以下のようになります。

private void form1_KeyPress(object sender, KeyPressEventArgs e)
{
  // アクティブなコントロールにキーを送るためフォーカスを当てる
  textBox1.Focus();
  switch (e.KeyChar)
  {
    case '^':
    case '+':
    case '%':
    case '~':
    case '(':
    case ')':
    case '{':
    case '}':
    case '[':
    case ']':
      // 特殊記号は中かっこで囲って送る
      SendKeys.SendWait("{" + e.KeyChar + "}");
      break;
    default:
      SendKeys.SendWait(e.KeyChar.ToString());
      break;
  }
}

これで一見完成のように見えるのですが、実は動かしてみると「^(カレット)」キーを押したときになぜか「&(アンパサンド)」で送られてしまいます。.NET Framework のバグかはわかりませんが、これでは完全とは言えないため別案を使います。

WSH (Windows Script Host) にも同様に SendKeys の仕組みがあり、こちらは正常にカレットが送るのでこれを使います。WSH を使うには以下の手順を行う必要がります。

  1. 参照設定の追加で、COM タブから「Windows Script Host Object Model」を追加する。
  2. 参照設定に追加された「IWshRuntimeLibrary」のプロパティを開き、「相互運用機能型の埋め込み」を False に設定する。

そのうえで以下のようにコードを修正します。#if の条件を入れていますが、WSH を使うか使わないかで分けているだけなので不要であれば消してください。

private void form1_KeyPress(object sender, KeyPressEventArgs e)
{
  // アクティブなコントロールにキーを送るためフォーカスを当てる
  textBox1.Focus();
  switch (e.KeyChar)
  {
    case '^':
#if true // Interop.IWshRuntimeLibrary を使ってよい場合
      (new IWshRuntimeLibrary.WshShellClass()).SendKeys("{^}");
      break;
#endif
    case '+':
    case '%':
    case '~':
    case '(':
    case ')':
    case '{':
    case '}':
    case '[':
    case ']':
      // 特殊記号は中かっこで囲って送る
      SendKeys.SendWait("{" + e.KeyChar + "}");
      break;
    default:
      SendKeys.SendWait(e.KeyChar.ToString());
      break;
  }
}
]]>

コメントを残す

メールアドレスが公開されることはありません。