2010-10-18 5 views
2

Si j'utilise le code suivant:Chaîne Convertir ou Char Keys objet

for (int i = 0; i < text.Length; i++) 
    { 
     char c = text[i]; 
     Keys k = (Keys)(byte)c; 
     MessageBox.Show(c.ToString() + "|" + k.ToString()); 
    } 

je peux obtenir une conversion correcte des lettres majuscules seulement. Le problème est que je dois aussi pouvoir reproduire des caractères en minuscules, et je reçois des erreurs de conversion. Par exemple, 'e' se convertit en 'NumPad5', où 'E' se convertit correctement en 'E'. Comment puis-je attaquer cela? Je vais prendre des chaînes d'entrée et créer des touches virtuelles pour un macro-joueur que j'essaie de développer.

+0

Vous pouvez faire un text.ToUpper() [i], au lieu du texte [i], ou ... Touches = (c> = ' a '&& c <=' z ')? (Keys.A + c - 'a'): (Keys) c; – Kit10

Répondre

5

Cela semble être la mauvaise approche. Avez-vous envisagé d'utiliser SendKeys?

+0

Je vous donnerais +1 million si je le pouvais. C'est beaucoup plus facile que je ne le pensais. J'ai juste utilisé 'SendKeys.SendWait (texte);' et il a agi exactement comme je le voulais! – ashurexm

+0

super, heureux je pourrais aider. :) – Jonathan

+0

SendKeys lève une exception si la fenêtre cible ne gère pas les commandes WM. – Kit10

1

L'énumération Keys n'est pas une copie directe des valeurs de caractère du caractère généré lorsque la touche est enfoncée. Parfois c'est le cas, mais parfois ce n'est pas le cas. La façon dont la valeur est codée pour chaque pression de touche est décrite dans le documentation:

Cette classe contient des constantes à utiliser pour le traitement de l'entrée au clavier. Les clés sont identifiées par des valeurs de clé, qui consistent en un code de clé et un ensemble de modificateurs combinés en une seule valeur entière. Les quatre chiffres de gauche d'une valeur de clé contiennent le code de clé (qui est identique à un code de clé virtuelle Windows). Les quatre chiffres de droite d'une valeur de clé contiennent des bits de modification pour les touches SHIFT, CONTROL et ALT.

1

La réponse est de créer une table de recherche inversée pour les caractères dont vous avez besoin. Le code pourrait être optimisé mais il est explicite. Vous pouvez ajouter des caractères spéciaux explicitement si nécessaire.

Vous pouvez également créer simultanément un dictionnaire pour aller dans l'autre sens également si cela vous convient. Les caractères multi-clés nécessiteraient une extension triviale mais ils ne sont pas directement mappés aux clés. Pour votre lecture attentive et l'extension possible devrait vous en avez besoin:

using System.Windows.Forms; 
static ImmutableDictionary<char, Keys> CharVKeyLookup; 
static void PopulateVKeyCharDictionary(){ 
    var keyboardStateNormal = new byte[255]; //All keys up 
    var keyboardStateShift = new byte[255]; 
    keyboardStateShift[(int)Keys.ShiftKey] = 0x80; 
    var charlookup = new Dictionary<char, Keys>(); 
    for (var i = 1; i < (int) Keys.OemClear; i++){ 
     var keys = (Keys) i; 
     //Verbose condition to ignore unnecessary conversions - probably a quicker way e.g. statically 
     if (keys == Keys.Enter || keys == Keys.Tab || keys == Keys.Space 
       || (keys >= Keys.D0 && keys <= Keys.D9) 
       || (keys >= Keys.A && keys <= Keys.Z) 
       || (keys >= Keys.Multiply && keys <= Keys.Divide) 
       || (keys >= Keys.Oem1 && keys <= Keys.Oem102)){ 
      var normal = KeyCodeToUnicode(keys); 
      var shift = KeyCodeToUnicode(keys, true); 
      if (normal.Item2 == 1) //Ignore wierdos - extend this if you need it 
       charlookup[normal.Item1[0]]=keys; 
      if (shift.Item2 ==1) 
       charlookup[shift.Item1[0]]=keys|Keys.Shift; //Incl shift mod 
     } 
    } 
    charlookup['\n'] = Keys.Return; 
    charlookup['\r'] = Keys.Return; 
    CharVKeyLookup = charlookup.ToImmutableDictionary(); 
} 
/// <returns>string if it exists and return code. -1=dead char, 0=no translation, 1=1 char, 2=special char </returns> 
public static Tuple<string, int> KeyCodeToUnicode(Keys key, byte[] keyboardState){ 
    var scanCode = MapVKToScanCode(key); 
    var result = new StringBuilder(10,10); 
    var language = InputLanguage.CurrentInputLanguage.Handle;//Or other method such as GetKeyboardLayout 
    var returnState = ToUnicodeEx(key, scanCode, keyboardState, result, 10, 0, language); 
    return new Tuple<string, int>(result.ToString(),returnState); 
} 
[DllImport("user32.dll")] 
internal static extern int ToUnicodeEx(Keys wVirtKey, uint wScanCode, byte[] lpKeyState, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszBuff, int cchBuff, uint wFlags, IntPtr dwhkl); 
[DllImport("user32.dll", CharSet = CharSet.Auto)] 
internal static extern IntPtr GetKeyboardLayout(int dwLayout); 
+0

C'est ce que je cherchais. Chose incroyable, merci, je vais y jeter un coup d'oeil. – AgentFire

+1

NP. C'est foutument comme l'enfer mais fonctionne bien. Ne pas suggérer que c'est la meilleure idée pour la plupart des applications, mais a été malade de voir les gens dire que ce n'était pas possible et cela étant marqué comme la «bonne» réponse. Je suppose que si vous ne savez pas à quel point il est réconfortant de penser que c'est impossible? –

Questions connexes