2013-06-30 53 views
3

我會試着更好地解釋我的意思,我也將盡力保持這個問題不受語言,如果有,雖然辦法做什麼,我想在C#中,而無需引用任何它會是不錯。不管怎麼說,如何獲得通過保持輪班獲得的字符?

我處理鍵盤輸入,並將其轉換爲字符串。一切都好。我得到了Shift和CapsLock鍵的狀態,然後EXOR它,以便我可以計算出結果字符串的外殼。

bool shift = KeyDown(SHIFT_KEY) 
bool capslock = KeyToggled(CAPSLOCK) 
bool stringCasing = shift^capslock //if both are true/false, the string will be lowercase. Otherwise uppercase. 

foreach Key k in [list of keys passed as parameter] 
    char c = (char)k 
    if stringCasing 
      c = Char.ToUpper(c) 
    else 
      c = Char.ToLower(c) 
end foreach 

現在沒有問題。如果用戶在按住shift或切換大寫鎖定的同時鍵入「a」,則會變成「A」。

然而,如果用戶決定輸入「!」,這是「1」加shift我只得到1,因爲「1」大寫仍然是「1」。

我看着在網絡上有點問這個問題之前,但我得到的是「自己Map中的鍵」。這真的是唯一的答案嗎?而且,如果我映射鍵然後具有不同鍵盤佈局的用戶試圖使用我的應用程序會發生什麼? 在此先感謝。

+0

你是怎麼處理鍵盤輸入的? KeyCode在事件處理程序中不可用嗎? –

+0

我正在建立在XNA的輸入類上,它與PInvoking GetKeyState差不多。基本上,我可以訪問的是所有虛擬鍵及其相對狀態的列表。例如,我的KeyCode爲1,但不適用於! (承認它存在VK?) – KappaG3

+1

這很難 - 這個線程可能會有所幫助,但它基本上是你說的話會在你的問題的情況下。你必須自己去做。不知道如何處理不同的鍵盤/佈局。 http://www.gamedev.net/topic/457783-xna-getting-text-from-keyboard/#entry4040153 –

回答

7

這可以通過Win32函數ToAsciiMSDN reference)來實現。我不知道任何包裝這些函數的.NET框架方法,因此可能需要使用P/Invoke。

隨着ToAscii,您可能需要參考VkKeyScan將密鑰轉換爲virtual key code。該密鑰代碼被用作ToAscii的參數。簡單的P/Invoke聲明這些方法遵循:

[DllImport("user32.dll")] 
    static extern short VkKeyScan(char c); 

    [DllImport("user32.dll", SetLastError=true)] 
    static extern int ToAscii(
     uint uVirtKey, 
     uint uScanCode, 
     byte[] lpKeyState, 
     out uint lpChar, 
     uint flags 
     ); 

注到ToAscii第三個參數是一個256個元素的數組引用的每個鍵的狀態;值0x80(高位設置)表示已設置密鑰。設置元素0x10(Shift的虛擬鍵碼)模擬Shift被按下。

然後,我們可以定義一個輔助方法,它作爲一個參數代表的關鍵角色,並輸出該鍵與鬱悶:

public static char GetModifiedKey(char c) 
{ 
    short vkKeyScanResult = VkKeyScan(c); 

    // a result of -1 indicates no key translates to input character 
    if (vkKeyScanResult == -1) 
     throw new ArgumentException("No key mapping for " + c); 

    // vkKeyScanResult & 0xff is the base key, without any modifiers 
    uint code = (uint)vkKeyScanResult & 0xff; 

    // set shift key pressed 
    byte[] b = new byte[256]; 
    b[0x10] = 0x80; 

    uint r; 
    // return value of 1 expected (1 character copied to r) 
    if (1 != ToAscii(code, code, b, out r, 0)) 
     throw new ApplicationException("Could not translate modified state"); 

    return (char)r; 
} 

調用此方法將返回轉移相關聯的字符用於輸入字符 +基鍵(其中,基本密鑰是被按下以輸入字符的物理鍵,例如,爲!基本密鑰)。例如,對於美式鍵盤,GetModifiedKey('7')GetModifiedKey('&')都將返回'&'。返回值將使用加載的鍵盤佈局;例如,在德語鍵盤上(Shift + 是/),則該方法將改爲返回/

+0

啊,非常感謝!這正是我需要的,而且你解釋得很好。編輯:我可以得到一個解釋-1轉換爲無符號整型?當然它不會編譯,但也許有一些我不知道的內容。 – KappaG3

+0

錯誤的道歉 - 我重構了代碼的第一部分以澄清錯誤檢查。作爲解釋,如果沒有鍵轉換爲所提供的字符(例如,美國鍵盤上的'ü'),則'VkKeyScan'將返回-1(0xffff)。 – drf

+0

是的,我是這麼認爲的。再次感謝您的答案! – KappaG3