WPF 切换输入法功能

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ExameClient.Common
{
    public class TypewrititngHelper
    {
        /// <summary>
        /// 是否是win7和xp系统
        /// </summary>
        /// <returns></returns>
        public static bool IsWin7OrXP()
        {
            bool result = false;
            try
            {
                string version = System.Environment.OSVersion.Version.ToString();
                string str = version.Substring(0, version.IndexOf(".") + 2);
                if (Convert.ToDouble(str) < 6.2)
                {
                    result = true;
                }
            }
            catch
            {
                result = false;
            }

            return result;
        }

        /// <summary>
        /// 绑定输入法选择下拉框
        /// </summary>
        /// <param name="comboBox"></param>
        public static void BindTypewriteingList(System.Windows.Controls.ComboBox comboBox)
        {
            comboBox.Items.Clear();
            if (IsWin7OrXP())
            {
                InputLanguageCollection ilc = InputLanguage.InstalledInputLanguages;
                foreach (InputLanguage il in ilc)
                {
                    comboBox.Items.Add(il.LayoutName);
                }

                comboBox.SelectedIndex =
                    InputLanguage.InstalledInputLanguages.IndexOf(InputLanguage.CurrentInputLanguage);
            }
            else
            {
                IList<short> langIDs = TSFWrapper.GetLangIDs();
                if (langIDs.Count > 0)
                {
                    string[] list = TSFWrapper.GetInputMethodList(langIDs[0]);
                    foreach (string desc in list)
                    {
                        comboBox.Items.Add(desc);
                    }

                    comboBox.SelectedItem = TSFWrapper.GetCurrentInputMethodDesc(langIDs[0]);
                }
            }

        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;

namespace ExameClient.Common
{
    public interface ITSFHelper
    {
        short[] GetLangIDS();
        bool ActiveInputMethodWithDesc(short langID, string desc);
        string[] GetInputMethodList(short langID);
        string GetCurrentInputMethodDesc(short langID);
        bool DeActiveInputMethod(short langID);
    }
    public class TSFHelper : ITSFHelper
    {
        public short[] GetLangIDS()
        {
            return TSFWrapper.GetLangIDs();
        }
        public bool ActiveInputMethodWithDesc(short langID, string desc)
        {
            return TSFWrapper.ActiveInputMethodWithDesc(langID, desc);
        }
        public string[] GetInputMethodList(short langID)
        {
            return TSFWrapper.GetInputMethodList(langID);
        }
        public string GetCurrentInputMethodDesc(short langID)
        {
            return TSFWrapper.GetCurrentInputMethodDesc(langID);
        }
        public bool DeActiveInputMethod(short langID)
        {
            return TSFWrapper.DeActiveInputMethod(langID);
        }
    }

    public static class TSFWrapper
    {
        public static short[] GetLangIDs()
        {
            List<short> langIDs = new List<short>();
            ITfInputProcessorProfiles profiles;
            if (TSF_NativeAPI.TF_CreateInputProcessorProfiles(out profiles) == 0)
            {
                IntPtr langPtrs;
                int fetchCount = 0;
                if (profiles.GetLanguageList(out langPtrs, out fetchCount) == 0)
                {
                    for (int i = 0; i < fetchCount; i++)
                    {
                        short id = Marshal.ReadInt16(langPtrs, sizeof(short) * i);
                        langIDs.Add(id);
                    }
                }
                Marshal.ReleaseComObject(profiles);
            }
            return langIDs.ToArray();
        }
        public static bool ActiveInputMethodWithDesc(short langID, string desc)
        {
            ITfInputProcessorProfiles profiles;
            if (TSF_NativeAPI.TF_CreateInputProcessorProfiles(out profiles) == 0)
            {
                try
                {
                    IEnumTfLanguageProfiles enumerator = null;
                    if (profiles.EnumLanguageProfiles(langID, out enumerator) == 0)
                    {
                        if (enumerator != null)
                        {
                            TF_LANGUAGEPROFILE[] langProfile = new TF_LANGUAGEPROFILE[1];
                            int fetchCount = 0;
                            while (enumerator.Next(1, langProfile, out fetchCount) == 0)
                            {
                                IntPtr ptr;
                                if (profiles.GetLanguageProfileDescription(ref langProfile[0].clsid, langProfile[0].langid, ref langProfile[0].guidProfile, out ptr) == 0)
                                {
                                    bool enabled;
                                    if (profiles.IsEnabledLanguageProfile(ref langProfile[0].clsid, langProfile[0].langid, ref langProfile[0].guidProfile, out enabled) == 0)
                                    {
                                        if (enabled)
                                        {
                                            string s = Marshal.PtrToStringBSTR(ptr);
                                            if (s.Equals(desc))
                                                return profiles.ActivateLanguageProfile(ref langProfile[0].clsid, langProfile[0].langid, ref langProfile[0].guidProfile) == 0;
                                        }
                                    }
                                    Marshal.FreeBSTR(ptr);
                                    //Marshal.FreeCoTaskMem(ptr);
                                }
                            }
                        }
                    }
                }
                finally
                {
                    Marshal.ReleaseComObject(profiles);
                }
            }
            return false;
        }
        public static string[] GetInputMethodList(short langID)
        {
            List<string> imeList = new List<string>();
            ITfInputProcessorProfiles profiles;
            if (TSF_NativeAPI.TF_CreateInputProcessorProfiles(out profiles) == 0)
            {
                try
                {
                    IEnumTfLanguageProfiles enumerator = null;
                    if (profiles.EnumLanguageProfiles(langID, out enumerator) == 0)
                    {
                        if (enumerator != null)
                        {
                            TF_LANGUAGEPROFILE[] langProfile = new TF_LANGUAGEPROFILE[1];
                            int fetchCount = 0;
                            while (enumerator.Next(1, langProfile, out fetchCount) == 0)
                            {
                                IntPtr ptr;
                                if (profiles.GetLanguageProfileDescription(ref langProfile[0].clsid, langProfile[0].langid, ref langProfile[0].guidProfile, out ptr) == 0)
                                {
                                    bool enabled;
                                    if (profiles.IsEnabledLanguageProfile(ref langProfile[0].clsid, langProfile[0].langid, ref langProfile[0].guidProfile, out enabled) == 0)
                                    {
                                        if (enabled)
                                            imeList.Add(Marshal.PtrToStringBSTR(ptr));
                                    }
                                }
                                Marshal.FreeBSTR(ptr);
                                //in windows 2008, it will crash.
                                //Marshal.FreeCoTaskMem(ptr);
                            }
                        }
                    }
                }
                finally
                {
                    Marshal.ReleaseComObject(profiles);
                }
            }
            return imeList.ToArray();
        }
        public static string GetCurrentInputMethodDesc(short langID)
        {
            ITfInputProcessorProfiles profiles;
            if (TSF_NativeAPI.TF_CreateInputProcessorProfiles(out profiles) == 0)
            {
                try
                {
                    Guid clsid;
                    Guid profileid;
                    Guid catid = new Guid(TSF_NativeAPI.GUID_TFCAT_TIP_KEYBOARD.ToByteArray());
                    if (profiles.GetDefaultLanguageProfile(langID, ref catid, out clsid, out profileid) == 0)
                    {
                        if (profiles.GetActiveLanguageProfile(ref clsid, out langID, out profileid) == 0)
                        {
                            IntPtr ptr;
                            try
                            {
                                if (profiles.GetLanguageProfileDescription(ref clsid, langID, ref profileid, out ptr) == 0)
                                {
                                    string s = Marshal.PtrToStringBSTR(ptr);
                                    Marshal.FreeBSTR(ptr);
                                    //in windows 2008 , it will carsh.
                                    //Marshal.FreeCoTaskMem(ptr);
                                    return s;
                                }
                            }
                            catch (Exception ex)
                            {
                                int i = 0;
                            }
                        }
                    }
                }
                finally
                {
                    Marshal.ReleaseComObject(profiles);
                }
            }
            return string.Empty;
        }

        public static bool DeActiveInputMethod(short langID)
        {
            List<string> imeList = new List<string>();
            ITfInputProcessorProfiles profiles;
            if (TSF_NativeAPI.TF_CreateInputProcessorProfiles(out profiles) == 0)
            {
                try
                {
                    Guid clsid = Guid.Empty;
                    return profiles.ActivateLanguageProfile(ref clsid, langID, ref clsid) == 0;
                }
                finally
                {
                    Marshal.ReleaseComObject(profiles);
                }
            }
            return false;
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct TF_LANGUAGEPROFILE
    {
        internal Guid clsid;
        internal short langid;
        internal Guid catid;
        [MarshalAs(UnmanagedType.Bool)]
        internal bool fActive;
        internal Guid guidProfile;
    }
    [ComImport, SecurityCritical, SuppressUnmanagedCodeSecurity,
 Guid("1F02B6C5-7842-4EE6-8A0B-9A24183A95CA"),
     InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ITfInputProcessorProfiles
    {
        [SecurityCritical]
        void Register(); //non-implement!! may be is wrong declaration.
        [SecurityCritical]
        void Unregister(); //non-implement!! may be is wrong declaration.
        [SecurityCritical]
        void AddLanguageProfile(); //non-implement!! may be is wrong declaration.
        [SecurityCritical]
        void RemoveLanguageProfile(); //non-implement!! may be is wrong declaration.
        [SecurityCritical]
        void EnumInputProcessorInfo(); //non-implement!! may be is wrong declaration.
        [SecurityCritical]
        int GetDefaultLanguageProfile(short langid, ref Guid catid, out Guid clsid, out Guid profile);
        [SecurityCritical]
        void SetDefaultLanguageProfile(); //non-implement!! may be is wrong declaration.
        [SecurityCritical]
        int ActivateLanguageProfile(ref Guid clsid, short langid, ref Guid guidProfile);
        [PreserveSig, SecurityCritical]
        int GetActiveLanguageProfile(ref Guid clsid, out short langid, out Guid profile);
        [SecurityCritical]
        int GetLanguageProfileDescription(ref Guid clsid, short langid, ref Guid profile, out IntPtr desc);
        [SecurityCritical]
        void GetCurrentLanguage(out short langid); //non-implement!! may be is wrong declaration.
        [PreserveSig, SecurityCritical]
        int ChangeCurrentLanguage(short langid); //non-implement!! may be is wrong declaration.
        [PreserveSig, SecurityCritical]
        int GetLanguageList(out IntPtr langids, out int count);
        [SecurityCritical]
        int EnumLanguageProfiles(short langid, out IEnumTfLanguageProfiles enumIPP);
        [SecurityCritical]
        int EnableLanguageProfile();
        [SecurityCritical]
        int IsEnabledLanguageProfile(ref Guid clsid, short langid, ref Guid profile, out bool enabled);
        [SecurityCritical]
        void EnableLanguageProfileByDefault(); //non-implement!! may be is wrong declaration.
        [SecurityCritical]
        void SubstituteKeyboardLayout(); //non-implement!! may be is wrong declaration.
    }
    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
  Guid("3d61bf11-ac5f-42c8-a4cb-931bcc28c744")]
    internal interface IEnumTfLanguageProfiles
    {
        void Clone(out IEnumTfLanguageProfiles enumIPP);
        [PreserveSig]
        int Next(int count, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]
TF_LANGUAGEPROFILE[] profiles, out int fetched);
        void Reset();
        void Skip(int count);
    }
    internal static class TSF_NativeAPI
    {
        public static readonly Guid GUID_TFCAT_TIP_KEYBOARD;
        static TSF_NativeAPI()
        {
            GUID_TFCAT_TIP_KEYBOARD = new Guid(0x34745c63, 0xb2f0,
 0x4784, 0x8b, 0x67, 0x5e, 0x12, 200, 0x70, 0x1a, 0x31);
        }
        [SecurityCritical, SuppressUnmanagedCodeSecurity, DllImport("msctf.dll")]
        public static extern int TF_CreateInputProcessorProfiles(out ITfInputProcessorProfiles profiles);
    }
}

 

posted @ 2020-06-15 14:04  _York  阅读(81)  评论(0编辑  收藏