2017-06-01 5 views
2

私が取り組んでいるプロジェクトでは、キーの組み合わせを区別してキーボードにグローバルキーストロークを記録し、コントロールキー(左または右)を押したままにする必要があります。唯一可能な方法は、KeyPressではなくKeyDownKeyUpイベントを使用することです。しかし、どの文字が入力されたのかを記録する必要もあります。Shift + 1を!に変換してください。 C#のシンボル#

KeyPressイベントを使用すると、私はいつも正しい文字を取得しますが、KeyDownKeyUpイベントでは、キーの組み合わせに関係なくKeyCodeのみを提供します。解決策の1つは、Dictionaryを使用してShiftキーをマッピングすることですが、異なるローカライズされたキーボードには異なる記号があるため、国際的な環境には向いていません。たとえば、Shift-2は、USキーボードの場合は@シンボル、英国キーボードの場合は"シンボルです。

手動ですべてのキーボードレイアウトをマッピングせずに組み合わせを自動的に変換する方法があるのだろうか?

少し複雑ですがトピック以外の質問は、ユーザーがキーに異なる出力を与えるためにいくつかのソフトウェアキーマッピングプログラムを使用するかどうかです。たとえば、asを交換すると、aと入力するとsが出力され、その逆も同様です。世界的なフックのために何が起こるでしょうか?私はこの種のソフトウェアがインストールされていないので、私はそれをテストすることはできません、誰もそれを処理するいくつかの経験がありますか?

答えて

0

興味深い質問です。その後、 Keyboard Mapping in .NET

using System.Runtime.InteropServices; 
public static class User32Interop 
{ 
    public static char ToAscii(Keys key, Keys modifiers) 
    { 
     var outputBuilder = new StringBuilder(2); 
     int result = ToAscii((uint)key, 0, GetKeyState(modifiers), 
      outputBuilder, 0); 
     if (result == 1) 
      return outputBuilder[0]; 
     else 
      throw new Exception("Invalid key"); 
    } 

    private const byte HighBit = 0x80; 
    private static byte[] GetKeyState(Keys modifiers) 
    { 
     var keyState = new byte[256]; 
     foreach (Keys key in Enum.GetValues(typeof(Keys))) 
     { 
      if ((modifiers & key) == key) 
      { 
       try 
       { 
        keyState[(int) key] = HighBit; 
       } 
       catch { } 
      } 
     } 
     return keyState; 
    } 

    [DllImport("user32.dll")] 
    private static extern int ToAscii(uint uVirtKey, uint uScanCode, 
     byte[] lpKeyState, 
     [Out] StringBuilder lpChar, 
     uint uFlags); 
} 

そしてKeyDownイベントでこのようにそれを使用して::ドイツ語キーボードレイアウトで

private void Form1_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.KeyCode != Keys.ShiftKey) 
    { 
     if (e.Modifiers.ToString() == "Shift") 
     { 
      var c = User32Interop.ToAscii(e.KeyCode, Keys.ShiftKey); 
      MessageBox.Show(c.ToString()); 
     } 
    } 
} 

、この製「しばらく私はここからの回答を使用して正しいシフトされた値を得ることができました私が持っているキーボードのレイアウトは@ だから、あなたが必要とするものはかなりわかります。

これはサードパーティのキーマッパーではテストできませんので、試してみてください。

+0

ありがとうございました!私はToAscii()を早期に見ていましたが、解決策を研究していましたが、それは正しくできませんでした。私は修飾キーのビット、すなわち 'Keys.ShiftKey'と' Keys.Shift'を混乱させたようです。 –

+1

うん、私はShiftとShiftキーと同じ問題を抱えていた。これは、ToAsciiが必要とするものとイベント引数に含まれているものである。したがって、ToString()を使ってやや厄介な構造になってから、明示的にShiftKeyを渡します。あなたのプロジェクトに幸運。 – LocEngineer

関連する問題