2011-01-24 59 views
5

我必須爲我們公司的程序編寫屏幕鍵盤,該程序主要用於具有觸摸功能的工業PC。如何編寫本地化的屏幕鍵盤

我們不能使用Windows的默認鍵盤,因爲我們不需要鍵盤上的所有鍵。所以我被要求用C#編寫一個自定義的。

我已經找到this blog作爲參考,但我不確定如何開始。

我創建了一個小原型GUI,併爲每個鍵分配一個掃描碼,並將這些掃描碼轉換爲相關字符。並將它們發送給主動控件。但我不確定我應該使用什麼樣的掃描碼。

所以我的問題是,這是寫這樣一個OSK的正確方法,如果是我應該使用哪個掃描碼?任何鏈接?

我也不能確定如何處理轉變狀態...

編輯:

好吧,我做了些研究,並用OSK讀取當前想出了鍵盤佈局,甚至處理簡單的轉變狀態(轉換Alt Gr)。我寫了一個KeyButton類,它繼承自Button,此KeyButton具有ScanCode類型字節屬性,並且如果您爲其分配有效的掃描代碼,KeyButton將調用相關函數以獲取正確的文本。我使用了來自Michael Kaplan博客的功能,並進行了一些小改動。最後事實證明,我必須像他一樣做同樣的事情。

所以我的問題的答案是:是的,你必須在你的按鈕上使用掃描碼,然後從鍵盤佈局中獲得虛擬鍵和unicode。 Use these scancodes.

現在我得到的人物唯一剩下的就是發送這些。

+0

這是對OSK一般用法還是專門用於給定的軟件? (即,您是否將掃描代碼提供給Windows事件總線或將char代碼發送到winforms應用程序?)差異是巨大的。 – 2011-01-24 11:48:25

+0

對於我們的軟件,所以我想發送char代碼到文本框。但是我想使用鍵盤佈局,比如windows中默認的osk。 – MBulli 2011-01-24 13:31:24

回答

1

我覺得這很簡單,只需製作一系列按鈕併爲每個按鈕分配一個字母,並在按鈕內部單擊即可做一個簡單的方法。基於按鈕等

SendKeys.Send("A"); 

更改鍵

1

我寫的映射鍵碼字符WPF應用程序映射類。 可能會有幫助。

public class KeyMapper 
{ 
    /// <summary> 
    /// Map key code to character. 
    /// If key code cannot be mapped returns empty char. 
    /// </summary> 
    public static char MapKey(Key key, bool shiftPressed, string culture) 
    { 
     CheckCulture(culture); 
     int englishVirtuaCode = KeyInterop.VirtualKeyFromKey(key); 
     return EnglishVirtualCodeToChar(englishVirtuaCode, shiftPressed, culture); 
    } 

    private static void CheckCulture(string culture) 
    { 
     InputLanguage language = InputLanguage.FromCulture(new CultureInfo(culture)); 
     if (language == null) 
      throw new ArgumentException(string.Format("culture {0} does not exist.", culture)); 
    } 

    private static char EnglishVirtualCodeToChar(int enlishVirtualCode, bool shiftPressed, string culture) 
    { 
     var scanCode = KeyMappingWinApi.MapVirtualKeyEx((uint)enlishVirtualCode, 0, EnglishCultureHandle); 
     var vitualKeyCode = KeyMappingWinApi.MapVirtualKeyEx(scanCode, 1, GetCultureHandle(culture)); 
     byte[] keyStates = GetKeyStates(vitualKeyCode, shiftPressed); 
     const int keyInformationSize = 5; 
     var stringBuilder = new StringBuilder(keyInformationSize); 
     KeyMappingWinApi.ToUnicodeEx(vitualKeyCode, scanCode, keyStates, stringBuilder, stringBuilder.Capacity, 0, GetCultureHandle(culture)); 
     if (stringBuilder.Length == 0) 
      return ' '; 
     return stringBuilder[0]; 
    } 

    private static IntPtr EnglishCultureHandle 
    { 
     get { return GetCultureHandle("en-US"); } 
    } 

    private static IntPtr GetCultureHandle(string culture) 
    { 
     return InputLanguage.FromCulture(new CultureInfo(culture)).Handle; 
    } 

    /// <summary> 
    /// Gets key states for ToUnicodeEx function 
    /// </summary> 
    private static byte[] GetKeyStates(uint keyCode, bool shiftPressed) 
    { 
     const byte keyPressFlag = 0x80; 
     const byte shifPosition = 16; // position of Shift key in keys array 
     var keyStatses = new byte[256]; 
     keyStatses[keyCode] = keyPressFlag; 
     keyStatses[shifPosition] = shiftPressed ? keyPressFlag : (byte)0; 
     return keyStatses; 
    } 
} 

public class KeyMappingWinApi 
{ 
    [DllImport("user32.dll")] 
    public static extern uint MapVirtualKeyEx(uint uCode, uint uMapType, IntPtr dwhkl); 

    [DllImport("user32.dll")] 
    public static extern int ToUnicodeEx(uint wVirtKey, uint wScanCode, byte[] lpKeyState, 
     [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszBuff, int cchBuff, uint wFlags, IntPtr dwhkl); 

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