Pregunta

OK, esta es una pregunta un poco extraña.

Tenemos una aplicación de pantalla táctil (es decir, sin teclado). Cuando los usuarios necesitan ingresar texto, la aplicación muestra un teclado virtual, construido a mano en WinForms.

Hacer estas cosas a mano para cada nuevo idioma es un trabajo de mono. Me imagino que las ventanas deben tener esta información de diseño del teclado oculta en algún lugar de alguna dll. ¿Habría alguna forma de sacar esta información de Windows?

Otras ideas son bienvenidas (imagino que al menos generar el archivo a partir de un archivo xml tiene que ser mejor que hacerlo a mano en VS).

(Nota: habiendo dicho todo lo cual, noto que hay un teclado japonés, una máquina de estado y todo ..., por lo que XML podría no ser suficiente)

ACTUALIZACIÓN : series bastante buenas sobre este tema (creo) aquí

¿Fue útil?

Solución

Microsoft Keyboard Layout Creator puede cargar teclados del sistema y exportarlos como .klc archivos . Como & # 8217; s está escrito en .NET, puede usar Reflector para ver cómo funciona. y usa la reflexión para conducirlo. Aquí hay un archivo zip de archivos .klc para los 187 teclados en Windows 8 creado usando el siguiente código C #. Tenga en cuenta que originalmente escribí esto para Windows XP, y ahora con Windows 8 y el teclado en pantalla, es realmente lento y parece bloquear la barra de tareas: / Sin embargo, funciona :)

using System;
using System.Collections;
using System.IO;
using System.Reflection;

class KeyboardExtractor {

    static Object InvokeNonPublicStaticMethod(Type t, String name,
            Object[] args)
    {
        return t.GetMethod(name, BindingFlags.Static | BindingFlags.NonPublic)
            .Invoke(null, args);
    }

    static void InvokeNonPublicInstanceMethod(Object o, String name,
            Object[] args)
    {
        o.GetType().GetMethod(name, BindingFlags.Instance |
                BindingFlags.NonPublic) .Invoke(o, args);
    }

    static Object GetNonPublicProperty(Object o, String propertyName) {
        return o.GetType().GetField(propertyName,
                BindingFlags.Instance | BindingFlags.NonPublic)
            .GetValue(o);
    }

    static void SetNonPublicField(Object o, String propertyName, Object v) {
        o.GetType().GetField(propertyName,
                BindingFlags.Instance | BindingFlags.NonPublic)
            .SetValue(o, v);
    }

    [STAThread] public static void Main() {
        System.Console.WriteLine("Keyboard Extractor...");

        KeyboardExtractor ke = new KeyboardExtractor();
        ke.extractAll();

        System.Console.WriteLine("Done.");
    }

    Assembly msklcAssembly;
    Type utilitiesType;
    Type keyboardType;
    String baseDirectory;

    public KeyboardExtractor() {
        msklcAssembly = Assembly.LoadFile("C:\\Program Files\\Microsoft Keyboard Layout Creator 1.4\\MSKLC.exe");
        utilitiesType = msklcAssembly.GetType("Microsoft.Globalization.Tools.KeyboardLayoutCreator.Utilities");
        keyboardType = msklcAssembly.GetType("Microsoft.Globalization.Tools.KeyboardLayoutCreator.Keyboard");

        baseDirectory = Directory.GetCurrentDirectory();
    }

    public void extractAll() {

        DateTime startTime = DateTime.UtcNow;

        SortedList keyboards = (SortedList)InvokeNonPublicStaticMethod(
                utilitiesType, "KeyboardsOnMachine", new Object[] {false});

        DateTime loopStartTime = DateTime.UtcNow;

        int i = 0;
        foreach (DictionaryEntry e in keyboards) {
            i += 1;
            Object k = e.Value;

            String name = (String)GetNonPublicProperty(k, "m_stLayoutName");
            String layoutHexString = ((UInt32)GetNonPublicProperty(k, "m_hkl"))
                .ToString("X");

            TimeSpan elapsed = DateTime.UtcNow - loopStartTime;
            Double ticksRemaining = ((Double)elapsed.Ticks * keyboards.Count)
                        / i - elapsed.Ticks;
            TimeSpan remaining = new TimeSpan((Int64)ticksRemaining);
            String msgTimeRemaining = "";
            if (i > 1) {
                // Trim milliseconds
                remaining = new TimeSpan(remaining.Hours, remaining.Minutes,
                        remaining.Seconds);
                msgTimeRemaining = String.Format(", about {0} remaining",
                        remaining);
            }
            System.Console.WriteLine(
                    "Saving {0} {1}, keyboard {2} of {3}{4}",
                    layoutHexString, name, i, keyboards.Count,
                    msgTimeRemaining);

            SaveKeyboard(name, layoutHexString);

        }

        System.Console.WriteLine("{0} elapsed", DateTime.UtcNow - startTime);

    }

    private void SaveKeyboard(String name, String layoutHexString) {
        Object k = keyboardType.GetConstructors(
                BindingFlags.Instance | BindingFlags.NonPublic)[0]
            .Invoke(new Object[] {
                        new String[] {"", layoutHexString},
                    false});

        SetNonPublicField(k, "m_fSeenOrHeardAboutPropertiesDialog", true);
        SetNonPublicField(k, "m_stKeyboardTextFileName",
                String.Format("{0}\\{1} {2}.klc",
                    baseDirectory, layoutHexString, name));
        InvokeNonPublicInstanceMethod(k, "mnuFileSave_Click",
                new Object[] {new Object(), new EventArgs()});

        ((IDisposable)k).Dispose();
    }

}

Básicamente, obtiene una lista de todos los teclados en el sistema, luego, para cada uno, lo carga en MSKLC, establece & "; Guardar como &"; nombre de archivo, miente sobre si ya está configurada las propiedades personalizadas del teclado, y luego simula un clic en el Archivo - > Guardar elemento del menú.

Otros consejos

¿Por qué no usa el teclado en pantalla (osk.exe)? Parece que estás reinventando la rueda. ¡Y no es la más fácil!

Sé dónde está la ruta de estos archivos DLL:

En su registro, verá:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts

donde cada rama tiene algún valor como "Layout File"="KBDSP.dll". El directorio raíz es

C:\Windows\System32

y

C:\Windows\SystemWOW64

Esos son todos los archivos de distribución del teclado que se encuentran. Por ejemplo, KBDUS.dll significa & Quot; teclado para EE. UU. & Quot ;.

Traté de sustituir el archivo DLL con mi DLL personalizada hecha por MSKLC, y descubrí que carga las imágenes de mapeo de diseño automáticamente en " Language " - " método de entrada " - " vista previa " ;:

 ingrese la descripción de la imagen aquí

Entonces sabemos que el mapeo está allí en la DLL.

Es un hecho bastante conocido que MSKLC no puede importar fielmente & amp; reproducir diseños de teclado para todos los archivos .DLL suministrados por Windows & # 8211, especialmente aquellos en Windows 8 & amp; encima. Y no sirve de nada saber dónde están esos archivos si no puede extraer ninguna información significativa o útil de ellos. Esto está documentado por Michael Kaplan en su blog (fue un desarrollador de MSKLC) que veo que ha vinculado anteriormente.

Cuando MSKLC encuentra algo que no comprende, esa parte se elimina. Extraer el diseño usando MSKLC funcionará para la mayoría de los teclados, pero hay algunos & # 8211, a saber, el teclado Cherokee y el amplificador & Japonés; Teclados coreanos (por nombrar algunos, no estoy seguro de cuántos más hay) & # 8211; para lo cual el diseño extraído NO reflejará con precisión o completamente el uso real & Amp; características del teclado. El teclado Cherokee ha encadenado teclas muertas que MSKLC no admite. Y los teclados del Lejano Oriente tienen teclas modificadoras que MSKLC no conoce & # 8211; ¡eso significa capas completas / estados de cambio que faltan!

Michael Kaplan proporciona algo de código y desbloquea algunos de los secretos de MSLKC y el software que lo acompaña que puede usarse para sortear algunas de estas limitaciones, pero requiere una buena cantidad de cosas a mano & # 8211; exactamente qué estás tratando de evitar! Además, los objetivos de Michael apuntan a crear teclados con funciones que MSKLC no puede crear o comprender, pero que SI funcionan en Windows (que es lo contrario de lo que el OP está tratando de lograr).

Estoy seguro de que mi solución llega demasiado tarde para ser útil para el OP, pero tal vez sea útil en el futuro para alguien en una situación similar. Esa es mi esperanza y razón para publicar esto.

Hasta ahora, todo lo que he hecho es explicar que las otras respuestas son insuficientes. Incluso el mejor no puede y no puede completamente & Amp; Reproduce con precisión todos los teclados nativos de Windows y los convierte en archivos fuente KLC. ¡Esto es realmente desafortunado y ciertamente no es culpa de su autor porque es un código / script muy inteligente! Afortunadamente, el script & Amp; los archivos de origen (cuyo enlace puede o no funcionar) es útil & amp; efectivo para la mayoría de los teclados de Windows, así como para cualquier teclado personalizado creado por MSKLC.

Los teclados que tienen las funciones avanzadas que MSKLC no admite fueron creados por Windows DDK, pero esas funciones no están documentadas oficialmente. Aunque uno puede aprender bastante sobre su potencial al estudiar los archivos fuente provistos con MSKLC.

Lamentablemente, la única solución que puedo ofrecer es un software pago de terceros llamado KbdEdit . Creo que es la única solución actualmente disponible que es capaz de decodificar fielmente & Amp; recrear cualquiera de los teclados suministrados por Windows & # 8211; aunque hay algunas características avanzadas que incluso no puede reproducir (como combinaciones de teclas / teclas de acceso rápido que realizan funciones especiales en el idioma nativo; por ejemplo: Ctrl + CapsLock para activar KanaLock ( una capa modificadora japonesa). KbdEdit reproduce fielmente esa capa modificadora que MSKLC quita, simplemente no admite este método alternativo de activar ese estado de cambio si no tiene un teclado japonés con una tecla de bloqueo Kana. Aunque, te permitirá convertir una tecla de tu teclado en una tecla Kana (¿tal vez Scroll Lock?).

Afortunadamente, ninguna de esas funciones no compatibles es aplicable incluso a un teclado en pantalla.

KbdEdit es un amplificador & realmente poderoso; herramienta increíble, ¡y ha valido la pena cada centavo que pagué! (Y eso NO es algo que diría sobre prácticamente cualquier otro software pagado & # 8230;) Aunque KbdEdit es un software de terceros, solo es necesario para crear los teclados, no para usarlos. Todo tEl teclado crea trabajo de forma nativa en cualquier sistema Windows sin instalar KbdEdit. Admite hasta 15 estados modificadores y tres teclas modificadoras de adición, una que se puede alternar & # 8211; como CapsLock. También admite teclas muertas encadenadas y la reasignación de cualquiera de las teclas en casi cualquier teclado.

Verifique la siguiente API de Windows

 [DllImport("user32.dll")]
 private static extern long LoadKeyboardLayout(string pwszKLID, uint Flags);

Marque MSDN aquí

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top