2012-12-02 2 views
3

표준 .NET에는 ToAscii/ToUnicode 및 MapVirtualKey 함수가 있었기 때문에이 기능을 처리 할 수있었습니다. 그러나 동일한 기능이나 라이브러리가 Metro/WinRT로 가져 오지는 않았지만 마찬가지입니다. 실제로 Metro/WinRT에 노출 된 기능이나 라이브러리가 없다면 미국 이외의 국가에서는 맞춤 텍스트 입력 상자를 시장에 출시하기가 매우 어려울 것입니다. 특정 예 : 내 사용자 지정 컨트롤에서 프랑스어 키보드 사용자가 è, ù, é 또는 à 키를 누르면 올바른 문자로 변환 할 수 없습니다. 예를 들어, è는 VirtualKey.Number7에 대한 스캔 코드를 사용하며 키보드 레이아웃을 알 수있는 방법이 없거나 현재 키보드 레이아웃을 기반으로 스캔 코드를 쉽게 번역 할 수있는 방법이 없다는 것을 알 수 있습니다. 누군가 이것에 대한 정보가 있습니까?WinRT에서 VirtualKey를 미국 이외의 키보드 레이아웃 용 char로 변환하는 방법은 무엇입니까?

+0

'WM_CHAR'와 동일한 기능을 사용할 수 없습니까? 이미 번역 된 키를 제공하는 이벤트가 있어야합니다. 키를 문자로 변환하는 것은 복잡한 상태 저장 프로세스 (데드 키, IME, ...)이므로 키마다 간단한 매핑이 없습니다. – CodesInChaos

+0

사실, 적어도 KeyDown 및 OnKeyDown 이벤트에 대해서는 대답이 아니오 인 것처럼 보입니다. event.ToString()은 이벤트의 이름 인 event.Key.ToString()/event.VirtualKey를 출력합니다.ToString()은 VirtualKey 열거 형에 정의 된대로 int를 출력합니다. 입력 된 문자는 제공되지 않습니다. 이것에 대해 짜증나는 점은 TextBoxes 및 기타 컨트롤을 사용하여 다른 키보드 레이아웃이 앱에서 작동하지만 사용자 정의 컨트롤을 만들면 미국 이외의 키보드 레이아웃에 입력 한 내용을 쉽게 누출 할 수 없다는 것입니다. – user1741978

+0

'KeyDown'에는 이것이 없습니다. 놀라운 일이 아닙니다. 놀랍게도'KeyPress'/WM_CHAR가 부족합니다. – CodesInChaos

답변

0

가상 키를 하나의 문자 값 중 하나의 값으로 매핑하는 MapVirtualKey Win32 API 함수를 사용할 수 있습니다. MapVirtualKey가 현재 설정된 키보드 레이아웃을 사용하고있는 것으로 보입니다 (문서화되어 있지 않음). 지정된 레이아웃을 사용하려면 MapVirtualKeyEx를 사용할 수 있습니다.

MapVirtualKey는 Shift 키를 눌렀는지 여부를 고려하지 않습니다. Shift 키를 누르면 정보를 쉽게 얻으려면 GetKeyState를 사용할 수 있습니다 (불행히도 WinRT 팀은 수정 자 키의 상태를 쉽게 알 수 없었습니다). 불행하게도이 솔루션은 인증을 받아야 윈도우 스토어 앱에 적용 할 수 없습니다

[DllImport("user32.dll")] 
private static extern uint MapVirtualKey(uint uCode, uint uMapType); 

[DllImport("user32.dll")] 
private static extern short GetKeyState(uint nVirtKey); 

private const uint MAPVK_VK_TO_CHAR = 0x02; 

private const uint VK_SHIFT = 0x10; 

private char TranslateVirtualKeyIntoChar(VirtualKey key) 
{ 
    char c = (char)MapVirtualKey((uint)key, MAPVK_VK_TO_CHAR); 
    short shiftState = GetKeyState(VK_SHIFT); 
    if (shiftState < 0) 
    { 
     // Shift is pressed 
     c = char.ToUpper(c); 
    } 
    return c; 
} 

업데이트

: 여기

는 문자로 가상 키를 변환하는 방법의 예입니다. MapVirtualKey 및 GetKeyState 지원되지 않는 API가 사용되므로 인증에 실패합니다. 즉,이 솔루션은 WinRT에서 실행되지 않을 가능성이 높습니다.

+0

WinRT에서 사용할 수 있습니까? 가능성은 낮습니다. – CodesInChaos

+0

나는 그것을 점검하려고했다 : 불행하게도 그렇지 않다. 인증에 실패합니다. –

2

나는 그것이 당신이 찾고있는 것에 달려 있다고 생각합니다. 간단한 영문자 또는 숫자를 찾으려면 다음을 수행하면됩니다.

private static char? ToChar(VirtualKey key, bool shift) 
{ 
    // convert virtual key to char 
    if (32 == (int)key) 
     return ' '; 

    VirtualKey search; 

    // look for simple letter 
    foreach (var letter in "ABCDEFGHIJKLMNOPQRSTUVWXYZ") 
    { 
     if (Enum.TryParse<VirtualKey>(letter.ToString(), out search) && search.Equals(key)) 
      return (shift) ? letter : letter.ToString().ToLower()[0]; 
    } 

    // look for simple number 
    foreach (var number in "1234567890") 
    { 
     if (Enum.TryParse<VirtualKey>("Number" + number.ToString(), out search) && search.Equals(key)) 
      return number; 
    } 

    // not found 
    return null; 
} 

행운을 빈다.

1

WinRT의 경우 (예 : 문자 텍스트 상자에 만 선택) :

CoreWindow.GetForCurrentThread().CharacterReceived += TextBox_CharacterReceived; 
void TextBox_CharacterReceived(CoreWindow sender, CharacterReceivedEventArgs args) 
    { 
     char c = Convert.ToChar(args.KeyCode); 
     if (char.IsLetter(c)) 
     { 
      ... 
     } 
    } 

를 들어 드 문자 입력 취소 : CharacterReceived를

void TextBox_Paste(object sender, TextControlPasteEventArgs e) 
    { 
     e.Handled = true; 
    } 

를 수정 : 옵션

TextBox textBoxData; 

void TextBox_KeyDown(object sender, KeyRoutedEventArgs e) 
    { 
     textBoxData = sender as TextBox; 
     if (e.Key!=VirtualKey.Space) 
     e.Handled = true; 
    } 

를 :

if (char.IsLetter(c)) 
    { 
    textBoxData.Text += c; 
    textBoxData.SelectionStart = textBoxData.Text.Length; 
    } 

경고! TextBox에 MaxLength가 있으면 코드를 수정해야합니다 :

if (char.IsLetter(c) && textBoxData.Text.Length < textBoxData.MaxLength) 
관련 문제