2017-05-27 4 views
0

キーボードからユーザーの種類のテキストを取得しようとしています。私は英語のキーボードレイアウトを持っているとすべてうまく動作しているようですが、バスをロシア語に変更すると動作しません。私は使用しました現在の言語レイアウトのために押されたキーが検出されました。C#

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
    { 
     if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) 
     { 
      int vkCode = Marshal.ReadInt32(lParam); 
      if ((Keys)vkCode == Keys.Enter || (Keys)vkCode == Keys.Tab || (Keys)vkCode == Keys.LButton || (Keys)vkCode == Keys.RButton) 
       WriteNewLine(_text); 
      else 
      if (ShiftKey) 
       _text += GetCharsFromKeys((Keys)vkCode, true, false); 
      else 
       _text += GetCharsFromKeys((Keys)vkCode, false, false); 
     } 
     return CallNextHookEx(_hookID, nCode, wParam, lParam); 
    } 

この関数は、キーコードを取得します。ご覧のとおり、私は次の関数を呼び出します

static string GetCharsFromKeys(Keys keys, bool shift, bool altGr) 
    { 
     var buf = new StringBuilder(256); 
     var keyboardState = new byte[256]; 
     if (shift) 
      keyboardState[(int)Keys.ShiftKey] = 0xff; 
     if (altGr) 
     { 
      keyboardState[(int)Keys.ControlKey] = 0xff; 
      keyboardState[(int)Keys.Menu] = 0xff; 
     } 
     ToUnicode((uint)keys, 0, keyboardState, buf, 256, 0); 
     return buf.ToString(); 
    } 

実際のキーはどのユーザータイプを返します。しかし、ENGのキーボードレイアウトでのみ機能します。 国際的なキーボードレイアウト処理を追加する方法が分かっている場合は、plsに教えてください。 P.P.私が入力した場合:

Руский

を私が手:

Hecrbq

My keyboard

+1

@ニッカ私は知っている、これは私がtoUnicode関数を使用する理由です。それはのToUnicodeのドキュメントを見て対応するUnicode文字 –

+0

に指定された仮想キーコードとキーボードの状態を変換し、私はあなたが 'H'キーをヒットした場合、それは、言っているか理解とは思わない、そのキーコードは0x48であり、これはfunnily十分にユニコードでは0x0048ではなく、0x0420はРは –

+0

ですこれはスレッドローカルフックまたはシステム全体のフックですか?また、なぜWM_KEYDOWNの代わりにWM_CHARをトラップしないのですか? –

答えて

0

あなたはInstalledInputLanguagesCurrentInputLanguageを使用する必要があります。あなたが従うことができる例はhereです。リンクが消えた場合には、ここにコードをコピーします。このコードでは、ヨーロッパのキーボードの@シンボルエントリを認識するため、ニーズに合わせて調整する必要があります。

DllImport("user32.dll")]  
public static extern short VkKeyScanEx(char ch, IntPtr dwhkl); 

public static void GetKeyboardShortcutForChar(char c, InputLanguage lang, out Keys key, out bool shift)  
{  
    var keyCode = VkKeyScanEx(c, lang.Handle);  
    key = (Keys) (keyCode & 0xFF);  
    shift = (keyCode & 0x100) == 0x100;  
} 

[DllImport("user32.dll", CharSet = CharSet.Unicode)]  
public static extern int ToUnicodeEx(int wVirtKey, uint wScanCode, byte[] lpKeyState, StringBuilder pwszBuff, int cchBuff, uint wFlags, IntPtr dwhkl);  

public static char? FromKeys(int keys, bool shift, bool capsLock)  
{  
    var keyStates = new byte[256];  
    if (shift)  
     keyStates[16] = 0x80;  
    if (capsLock)  
     keyStates[20] = 0x80;  

    var sb = new StringBuilder(10);  
    int ret = User32.ToUnicodeEx(keys, 0, keyStates, sb, sb.Capacity, 0, InputLanguage.CurrentInputLanguage.Handle);  

    return ret == 1 ? (char?)sb[0] : null;  
} 
+0

私はそれをコピーしました。アイデアは、あなたがしたいことのためにあります。それはあなたのニーズを満たすためにそれを微調整する必要があります。それは私のコードではなく、私はそれをテストしていません。重要なことは、異なるキーボードを扱う方法を示すことです。コピー+貼り付けではありません。 – CodingYoshi

+0

これは面白いことですが、プログラムを実行する前にキーボードレイアウトをロシア語として設定した場合にのみ機能します。私はENGで始まるのであればそれだけで私が入力した内容の英語表現を返しますし、その逆 –

+0

私は誰かがロシアのレイアウトのキーボードを持っているので、場合、彼らはあなたのプログラムを開始する前に、彼らはそれを持っています罰金だと思うこと万力。アプリケーションを使用する間にキーボードを変更することはほとんどありません。 – CodingYoshi

関連する問題