5

私は自分のプロジェクトにこのキーボードフックを使用しています。SHIFT修飾キーを押したままSendKeys.Send()を使用して小文字を送信できません。たとえば、ユーザーがKボタン「a」SHIFTを押した場合は送信する必要があり、 +を押した場合はK「b」を送信する必要があります。コードは次のとおりです。

void gkh_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.K)
    {
        if (Control.ModifierKeys == Keys.Shift)
            SendKeys.Send("b");
        else
            SendKeys.Send("a");
    }
    e.Handled == true;   
}

ただし、 「b」の代わりに「B」(大文字)を送信します。つまり、キーは送信されたキーストローク「b」を大文字に変更します。これは、Keys.Shiftをフックに追加した後でも発生します。SHIFT

e.SupressKeyPressSendKeys( "b" .toLower())を使用したり、上記のコードをKeyUpイベントに配置したりするなど、多くのアプローチを試しました。

plsは私を助けます、私は非常にイライラしています、私のアプリケーション開発はこの時点で打たれています。

4

1 に答える 1

4

キーがまだ押されている間にキーを送信しているShiftため、大文字になります。キーの押下とともにキーの押下
をキャンセルする方法を理解する必要があります。ShiftK

使用しているグローバル フックのサンプルは、少しむき出しです。また、どの修飾キーが押されているかを報告する必要があります。残念ながら、その機能は実装されていないようです。

そもそも、なぜキーボード フックを使用する必要があるのでしょうか。フォームにフォーカスがないときに発生する重要なイベントを本当に処理する必要がありますか? もしそうなら、なぜ世界で を使うのSendKeyでしょうか? 現在アクティブなアプリケーションが、送信したキー プレスで何をしようとしているのかをどのように知ることができますか?

これは、代わりに、フォームのProcessCmdKeyメソッドのオーバーライドでより適切に処理されるもののように見えます。例えば:

  protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
  {
     if (keyData == (Keys.K | Keys.Shift))
     {
        SendKeys.Send("b");
        return true;  // indicate that you handled the key
     }
     else if (keyData == Keys.K)
     {
        SendKeys.Send("a");
        return true;  // indicate that you handled the key
     }

     // call the base class to handle the key
     return base.ProcessCmdKey(ref msg, keyData);
  }

編集:あなたのコメントは、フォームにフォーカスがないときに発生する重要なイベントを実際に処理する必要があることを示唆しています。単にキー以上のものを処理する必要があると仮定するとK、グローバル フックを使用してこれを行う必要があります。

前に述べたように、問題は、 を使用してキーをShift送信している間、ユーザーがまだキーを押し続けていることです。これにより、小文字ではなく大文字の B として登録されます。したがって、解決策は明らかです。オペレーティング システムによって処理されないように、キーの押下をキャンセルする方法を見つける必要がありますもちろん、キーイベントを食べた場合は、それを追跡する方法を考え出す必要もあります。これにより、アプリケーションはキーイベントがいつ押されたかを認識し、それに応じて動作できるようになります。BSendInputShift

クイック検索では、キーに関して同様の質問が既に尋ねられ、回答されていることがわかりWindows logoます。

特に、グローバル フックによって発生したイベントを処理するコードを次のように記述する必要がありKeyDownます (少なくとも、このコードは、私が作成したグローバル フック クラスで動作します。あなたのクラスでも動作するはずですが、実際には動作しませんでした)。テストしました):

// Private flag to hold the state of the Shift key even though we eat it
private bool _shiftPressed = false;

private void gkh_KeyDown(object sender, KeyEventArgs e)
{
   // See if the user has pressed the Shift key
   // (the global hook detects individual keys, so we need to check both)
   if ((e.KeyCode == Keys.LShiftKey) || (e.KeyCode == Keys.RShiftKey))
   {
      // Set the flag
      _shiftPressed = true;

      // Eat this key event
      // (to prevent it from being processed by the OS)
      e.Handled = true;
   }


   // See if the user has pressed the K key
   if (e.KeyCode == Keys.K)
   {
      // See if they pressed the Shift key by checking our flag
      if (_shiftPressed)
      {
         // Clear the flag
         _shiftPressed = false;

         // Send a lowercase letter B
         SendKeys.Send("b");
      }
      else
      {
         // Shift was not pressed, so send a lowercase letter A
         SendKeys.Send("a");
      }

      // Eat this key event
      e.Handled = true;
   }
}
于 2011-03-26T15:26:24.237 に答える