سؤال

حسنا، هذا هو السؤال غريبا بعض الشيء.

لدينا تطبيق شاشة تعمل باللمس (أي، أي لوحة المفاتيح). عندما يحتاج المستخدمون لإدخال النص، وتطبيق يظهر لوحة المفاتيح الافتراضية - اليد المدمج في WinForms عناصر

وجعل هذه الأمور باليد لكل لغة جديدة هو العمل قرد. اعتقد انه النوافذ يجب أن يكون هذه المعلومات تخطيط لوحة المفاتيح يختبئ في مكان ما في بعض دلل. لن يكون هناك أي حال الحصول على هذه المعلومات من النوافذ؟

وأفكار أخرى مرحبا بك (الرقم الأول على الأقل توليد شيء من ملف xml ويجب أن يكون أفضل من فعل ذلك باليد في VS).

و(ملاحظة: بعد أن قلت كل ما، وألاحظ أن هناك لوحة مفاتيح يابانية، آلة الدولة وجميع ...، لذلك XML قد لا تكون كافية)

<قوية> UPDATE : في سلسلة جيدة حول هذا الموضوع (أعتقد) <وأ href = "http://www.siao2.com/2006/04/22/581107.aspx" يختلط = " noreferrer "> هنا

هل كانت مفيدة؟

المحلول

مايكروسوفت تخطيط لوحة المفاتيح الخالق يمكن تحميل لوحة مفاتيح نظام وتصديرها كما .klc ملفات . لأنه مكتوب في. NET يمكنك استخدام العاكس لنرى كيف يفعل ذلك، واستخدام انعكاس لقيادتها . وهنا الملفات .klc لوحات المفاتيح 187 في ويندوز 8 تم إنشاؤها باستخدام أدناه C # رمز. علما بأنني أصلا كتبت هذا لنظام التشغيل Windows XP، والآن مع ويندوز 8 ولوحة المفاتيح التي تظهر على الشاشة، وإن كان بطيئا حقا ويبدو أن تحطم شريط المهام: / ومع ذلك، فإنه لا عمل:)

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

}

والأساس، فإنه يحصل على قائمة بأسماء جميع لوحات المفاتيح على النظام، ثم لكل واحد، يحمل في MSKLC، يضع "حفظ باسم" اسم الملف، تبعد حوالي سواء كان ذلك بالفعل تكوين خصائص لوحة المفاتيح المخصصة، ومن ثم يحاكي انقر على ملف -> حفظ عنصر القائمة

نصائح أخرى

لماذا لا يتم استخدام لوحة المفاتيح التي تظهر على الشاشة (osk.exe)؟ تبدو وكأنك إعادة اختراع العجلة. وليس أسهل واحد!

وإنها لحقيقة معروفة إلى حد ما التي MSKLC غير قادر على استيراد بأمانة وإنتاج تخطيطات لوحة المفاتيح لجميع الملفات. DLL المقدمة من ويندوز، خصوصا تلك الموجودة في ويندوز 8 وأعلاه. وأنها لا تفعل أي شيء طيب أن نعرف أين تلك الملفات إذا لم تتمكن من انتزاع أي معلومات مفيدة أو مفيدة منها. تم توثيق ذلك عن طريق مايكل كابلان على بلوق (كان مطور من MSKLC) التي أرى أنك ربطت إليها أعلاه.

وعندما يصادف MSKLC أي شيء لا يفهم، تتم إزالة هذا الجزء. استخراج تخطيط استخدام وMSKLC العمل لمعظم لوحات المفاتيح، ولكن هناك عدد قليل، وهي لوحة المفاتيح شيروكي، ولوحات المفاتيح اليابانية والكورية (على سبيل المثال لا الحصر، وأنا لست متأكدا من عدد من هناك)، للحصول على أي المستخرجة لن تعكس بدقة تخطيط أو كليا الاستخدام الفعلي وميزات لوحة المفاتيح. وقد بالسلاسل لوحة المفاتيح شيروكي مفاتيح الميتة التي لا تدعم MSKLC. ولوحات المفاتيح الشرق الأقصى لها مفاتيح التعديل الذي MSKLC ليس على علم، وهذا يعني كامل ولايات طبقات / التحول التي هي في عداد المفقودين!

ومايكل كابلان تزود بعض رمز ويفتح بعض من أسرار MSLKC والبرامج المصاحبة التي يمكن استخدامها للالتفاف على بعض من هذه القيود ولكنه يتطلب قدرا كبيرا من فعل الأشياء باليد بالضبط ما كنت تحاول تجنب! بالإضافة إلى ذلك، تهدف أهداف مايكل في خلق لوحات المفاتيح مع الميزات التي MSKLC لا يمكن إنشاء أو فهم، ولكن التي لا تعمل في ويندوز (والذي هو عكس ما OP تحاول إنجاز).

وأنا واثق من أن بلدي الحل يأتي متأخرا جدا لتكون ذات فائدة لOP، ولكن ربما سيكون من المفيد في المستقبل لشخص في وضع مماثل. وهذا هو أملي والسبب في نشر هذا.

وحتى الآن كل ما قمت به هو توضيح أن إجابات أخرى غير كافية. حتى أفضل واحد لن ولا يمكن تماما وبدقة إنتاج كل من لوحات المفاتيح الأم ويندوز 'وجعلها في ملفات مصدر KLC. وهذا أمر مؤسف حقا، وأنها بالتأكيد ليست خطأ من صاحبه لأن هذا هو قطعة ذكي جدا من التعليمات البرمجية / النصي! الحمد لله النصي والملفات المصدر (الذي الارتباط قد أو قد لا تزال تعمل) هو مفيد وفعال لغالبية لوحات المفاتيح ويندوز '، فضلا عن أي لوحة مفاتيح مخصصة تم إنشاؤها من قبل MSKLC.

لوحات المفاتيح التي لديها الميزات المتقدمة التي MSKLC لا يدعم تم إنشاؤها بواسطة Windows DDK، ولكن لم يتم توثيق تلك الميزات رسميا. على الرغم من أن يمكن لأحد أن تعلم تماما قليلا عن إمكاناتهم من خلال دراسة الملفات المصدر تزويد MSKLC.

للأسف الحل الوحيد الذي يمكن أن تقدمه هو 3rd الطرف، البرمجيات المدفوعة دعا KbdEdit . وأعتقد أنه هو الحل الوحيد المتاح حاليا والتي هي قادرة فعلا على فك رموز بأمانة وإعادة أي من ويندوز المزودة لوحات المفاتيح، على الرغم من أن هناك عدد قليل من الميزات المتقدمة التي حتى أنه لا يمكن إعادة إنتاج (مثل مفاتيح مجموعات / مفاتيح الاختصار التي تؤدي الأم الخاصة وظائف، على سبيل المثال: السيطرة + كابسلوك لتفعيل KanaLock (طبقة التعديل اليابانية) KbdEdit لا تستنسخ بإخلاص أن طبقة التعديل الذي MSKLC مع قطاع بعيدا، فقط لا تدعم هذه الطريقة البديلة لتفعيل تلك الدولة التحول إذا لم تقم بذلك لديهم لوحة مفاتيح يابانية مع مفتاح القفل قانا. وعلى الرغم من أنها سوف تسمح لك لتحويل مفتاح على لوحة المفاتيح لمفتاح قانا (ربما انتقل لوك؟).

لحسن الحظ، فإن أيا من تلك الميزات غير معتمد، بل هي تنطبق على لوحة المفاتيح التي تظهر على الشاشة.

وKbdEdit هو أداة قوية حقا ومذهلة، وأنه كان يستحق كل بنس دفعت لذلك! (وهذا لا شيء أود أن أقول عن أي البرمجيات المدفوعة الأخرى تقريبا ...) على الرغم من KbdEdit هو برنامج 3rd الطرف، وهناك حاجة فقط لخلق لوحات المفاتيح، وليس لاستخدامها. كل من لوحات المفاتيح يخلق العمل أصلا على أي نظام ويندوز دون KbdEdit يتم تركيبها. ويدعم ما يصل إلى15 دولة التعديل وثلاثة مفاتيح التعديل بالإضافة إلى ذلك، واحد الذي هو مثل togglable كابسلوك. كما أنها تدعم بالسلاسل مفاتيح الميتة، والخارطه أي من مفاتيح على معظم أي لوحة المفاتيح.

يرجى الاختيار التالية ويندوز API

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

MSDN هنا

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top