2017-05-27 34 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鍵盤佈局。 如果你知道如何添加國際鍵盤佈局處理,請讓我知道。 P.S.當我輸入:

Руский

我得到:

Hecrbq

My keyboard

+1

@NickA我知道,這就是爲什麼我使用unnicode函數。它將指定的虛擬鍵碼和鍵盤狀態轉換爲相應的Unicode字符 –

+0

查看ToUnicode的文檔,我不認爲你理解它的意思,如果你點擊'H'鍵,它的鍵碼是0x48,它有趣的是unicode中的0x0048,而不是0x0420像Р是 –

+0

這是針對線程本地鉤子還是系統鉤子?另外,爲什麼不捕獲WM_CHAR而不是WM_KEYDOWN? –

回答

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