2013-06-30 7 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 

И никаких проблем пока нет. Если пользователь набирает «a», удерживая сдвиг или с помощью переключателя «капот», он становится «A».

Однако, если пользователь решит ввести «!», Что равно «1» плюс сдвиг, я получаю только 1, потому что «1» в верхнем регистре по-прежнему «1».

Я немного поглядел в Интернете, прежде чем задавать этот вопрос, но все, что у меня было, это «Карта ключей самостоятельно». Это действительно единственный ответ? А также, что произойдет, если я сопоставил ключи, а затем пользователь с другой раскладкой клавиатуры попытался использовать мое приложение? Спасибо заранее.

+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 ToAscii (MSDN reference). Я не знаю каких-либо методов .NET framework, которые обертывают эти функции, поэтому может потребоваться использование P/Invoke.

Наряду с ToAscii вам может понадобиться ссылка на VkKeyScan, чтобы перевести ключ в virtual key code. Этот код ключа используется как параметр для ToAscii. Простой Р/заявления 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) эмулирует Сдвиг.

Мы можем определить вспомогательный метод, который принимает в качестве параметра символ, представляющий ключ, и выходы, ключ с сдвига депрессии:

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; 
} 

Calling этот метод будет возвращать характер, связанный с сдвига + базовый ключ для входного символа (где базовый ключ - физическая клавиша, введенная для ввода символа, например, - базовый ключ для !). Например, для американской клавиатуры GetModifiedKey('7') и GetModifiedKey('&') оба возвращают '&'. Возвращаемое значение будет использовать загруженную раскладку клавиатуры; например, на немецкой клавиатуре (где Shift + is /), вместо этого метод вернет /.

+0

Ах, спасибо большое! Это именно то, что мне нужно, и вы хорошо это объяснили. Изменить: Могу ли я получить объяснение по -1, введенному в unsigned int? Конечно, он не компилируется, но, возможно, что-то происходит под этим, о котором я не знаю. – KappaG3

+0

Извинения за ошибку - я отредактировал первую часть кода, чтобы уточнить проверку ошибок. В качестве объяснения, 'VkKeyScan' вернет -1 (0xffff), если нет ключа, который переводится на предоставленный символ (например,« ü »на американской клавиатуре). – drf

+0

Да, я так и думал. Еще раз спасибо за ответ! – KappaG3

Смежные вопросы