Domanda

OK, questa è una domanda un po 'strana.

Abbiamo un'applicazione touch-screen (ovvero nessuna tastiera). Quando gli utenti devono inserire del testo, l'applicazione mostra la tastiera virtuale, creata a mano in WinForms.

Realizzare queste cose a mano per ogni nuova lingua è il lavoro delle scimmie. Immagino che Windows debba avere queste informazioni sul layout della tastiera nascoste da qualche parte in qualche dll. Ci sarebbero comunque delle informazioni da Windows?

Altre idee benvenute (immagino che almeno generare la cosa da un file xml debba essere migliore che farlo a mano in VS).

(Nota: detto tutto ciò, noto che esiste una tastiera giapponese, una macchina a stati e tutto ..., quindi XML potrebbe non essere sufficiente)

AGGIORNAMENTO : serie piuttosto buone su questo argomento (credo) qui

È stato utile?

Soluzione

Microsoft Keyboard Layout Creator può caricare tastiere di sistema ed esportarle come .klc file . Dato che & # 8217; è scritto in .NET, puoi usare Reflector per vedere come funziona e usa la riflessione per guidarlo. Ecco un file zip di file .klc per le 187 tastiere in Windows 8 creato utilizzando il seguente codice C #. Nota che in origine l'ho scritto per Windows XP e ora con Windows 8 e la tastiera su schermo, è molto lento e sembra arrestare in modo anomalo la barra delle applicazioni: / Tuttavia, funziona :)

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

}

Fondamentalmente, ottiene un elenco di tutte le tastiere sul sistema, quindi per ognuna, lo carica in MSKLC, imposta il " Salva con nome " nome file, indica se sono già state configurate le proprietà personalizzate della tastiera e quindi simula un clic sul file - > Salva voce di menu.

Altri suggerimenti

Perché non usi la tastiera su schermo (osk.exe)? Sembra che tu abbia reinventato la ruota. E non il più semplice!

So dove sono i percorsi di questi file DLL:

Nel tuo registro, vedi:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts

dove ogni ramo ha un valore come "Layout File"="KBDSP.dll". La directory principale è

C:\Windows\System32

e

C:\Windows\SystemWOW64

Questi sono tutti i file di layout della tastiera che si trovano. Ad esempio, KBDUS.dll significa & Quot; tastiera per US & Quot ;.

Ho provato a sostituire il file DLL con la mia DLL personalizzata creata da MSKLC e ho trovato che carica automaticamente le immagini di mappatura del layout nella " Lingua " - " metodo di input " - " preview " ;:

 inserisci qui la descrizione dell'immagine

Quindi sappiamo che la mappatura è presente nella DLL.

È un fatto abbastanza noto che MSKLC non è in grado di importare fedelmente l'amplificatore &; riprodurre i layout di tastiera per tutti i file .DLL forniti da Windows & # 8211, in particolare quelli in Windows 8 & amp; sopra. E non serve a niente sapere dove si trovano quei file se non riesci a estrarre informazioni significative o utili da essi. Questo è documentato da Michael Kaplan sul suo blog (era uno sviluppatore di MSKLC) che vedo che hai collegato sopra.

Quando MSKLC incontra qualcosa che non comprende, quella parte viene rimossa. L'estrazione del layout usando MSKLC funzionerà con la maggior parte delle tastiere, ma ci sono alcuni & # 8211, ovvero la tastiera Cherokee e l'amplificatore giapponese &; Tastiere coreane (per citarne alcune, non sono sicuro di quante altre ce ne siano) & # 8211; per le quali il layout estratto NON rifletterà in modo accurato o completo l'amplificatore di utilizzo & Effettivo; caratteristiche della tastiera. La tastiera Cherokee ha incatenati tasti morti che MSKLC non supporta. E le tastiere dell'Estremo Oriente hanno tasti modificatori di cui MSKLC non è a conoscenza! & # 8211; ciò significa che mancano interi livelli / stati di spostamento che mancano!

Michael Kaplan fornisce un po 'di codice e sblocca alcuni dei segreti di MSLKC e del software di accompagnamento che può essere utilizzato per aggirare alcune di queste limitazioni, ma richiede una buona dose di fare le cose a mano & # 8211; esattamente cosa stai cercando di evitare! Inoltre, gli obiettivi di Michael sono volti a creare tastiere con funzionalità che MSKLC non può creare o comprendere, ma che funzionano in Windows (che è l'opposto di ciò che l'OP sta cercando di realizzare).

Sono sicuro che la mia soluzione arriva troppo tardi per essere utile all'OP, ma forse sarà utile in futuro a qualcuno in una situazione simile. Questa è la mia speranza e ragione per pubblicare questo.

Finora tutto ciò che ho fatto è spiegare che le altre risposte sono insufficienti. Anche il migliore non può e non può completamente & Amp; riprodurre accuratamente tutte le tastiere native di Windows e renderle in file sorgente KLC. Questo è davvero sfortunato e certamente non è colpa del suo autore perché è un pezzo di codice / script molto intelligente! Per fortuna lo script & Amp; i file sorgente (il cui collegamento può o non può ancora funzionare) è utile & amp; efficace per la maggior parte delle tastiere di Windows, nonché per tutte le tastiere personalizzate create da MSKLC.

Le tastiere che dispongono delle funzionalità avanzate che MSKLC non supporta sono state create dal DDK di Windows, ma tali funzionalità non sono documentate ufficialmente. Sebbene si possa imparare un po 'del loro potenziale studiando i file sorgente forniti con MSKLC.

Purtroppo l'unica soluzione che posso offrire è un software a pagamento di terze parti chiamato KbdEdit . Credo che sia l'unica soluzione attualmente disponibile in grado di decodificare fedelmente l'amplificatore &; ricreare una qualsiasi delle tastiere fornite da Windows & # 8211; anche se ci sono alcune funzionalità avanzate che nemmeno è in grado di riprodurre (come combinazioni di tasti / tasti di scelta rapida che eseguono speciali funzioni di lingua nativa; ad esempio: Ctrl + CapsLock per attivare KanaLock ( un livello modificatore giapponese.) KbdEdit riproduce fedelmente quel livello modificatore con MSKLC con strip strip, semplicemente non supporta questo metodo alternativo di attivazione dello stato shift se non si dispone di una tastiera giapponese con un tasto di blocco Kana. ti permetterà di convertire un tasto della tastiera in un tasto Kana (forse Scroll Lock?).

Fortunatamente, nessuna di quelle funzioni non supportate è applicabile nemmeno a una tastiera su schermo.

KbdEdit è un amplificatore & davvero potente; strumento straordinario, e ne è valsa la pena ogni centesimo che ho pagato! (E NON è qualcosa che direi praticamente di qualsiasi altro software a pagamento & # 8230;) Anche se KbdEdit è un software di terze parti, è necessario solo creare le tastiere, non usarle. Tutto di tlui le tastiere crea il lavoro in modo nativo su qualsiasi sistema Windows senza l'installazione di KbdEdit. Supporta fino a 15 stati modificatori e tre tasti modificatori di aggiunta, uno che è attivabile & # 8211; come CapsLock. Supporta anche i tasti morti concatenati e rimappando qualsiasi tasto sulla maggior parte delle tastiere.

Controlla le seguenti API di Windows

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

Controlla MSDN qui

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top