C# 切换(指定)输入法 您所在的位置:网站首页 win10怎么修改默认输入法为搜狗 C# 切换(指定)输入法

C# 切换(指定)输入法

2024-05-29 19:30| 来源: 网络整理| 查看: 265

一、前言:

    自动切换到指定输入法,虽然是个小功能,但对于程序的友好体验,却不是一个小问题。

   尤其是文字工作者,体验感非常不爽!

    言归正传!

    由于Windows10,11输入法框架的原因,C#想要做到切换指定的输入法,直接操作是做不到的。

    故而,我选择了取巧的方式,来达到这一目的。

二、编程逻辑:

    1.通过C#操作注册表,将指定的输入法,在程序打开时,设置成为默认的输入法。

     2.调用API,将程序当前的输入法,切换到默许输入法。

三、编程代码: using Microsoft.Win32; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApp7 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); [DllImport("kernel32.dll")] public static extern uint GetCurrentThreadId(); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetKeyboardLayout(uint idThread); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr LoadKeyboardLayout(string pwszKLID, uint Flags); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); [DllImport("Kernel32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetConsoleWindow(); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SetForegroundWindow(IntPtr intPtr); [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); public const uint WM_INPUTLANGCHANGEREQUEST = 0x0050; public const uint KLF_ACTIVATE = 1; const int WM_KEYDOWN = 0x100; // Key down message const int WM_CHAR = 0x102; private void Form1_Load(object sender, EventArgs e) { #region 设置搜狗五笔输入为系统默认输入法-第三版 RegistryKey Key = Registry.CurrentUser; //打开注册表输入法项 RegistryKey keySoft = Key.OpenSubKey("SOFTWARE\\Microsoft\\CTF\\SortOrder\\AssemblyItem\\0x00000804\\{34745C63-B2F0-4784-8B67-5E12C8701A31}", true); string[] arrNames = keySoft.GetSubKeyNames();//获取系统安装的输入数组 string[] clsids = new string[arrNames.Length];//创建 CLSID 数组,用于存储其值 string[] profiles = new string[arrNames.Length];//创建 Profile 数组,用于存储其值 int[] keyBoards = new int[arrNames.Length];//创建 KeyboardLayout 数组,用于存储其值 string[] fmainPaths = new string[arrNames.Length];//创建注册表中,输入法的完整路径数组 //输入法主要路径 string mainPath = "SOFTWARE\\Microsoft\\CTF\\SortOrder\\AssemblyItem\\0x00000804\\{34745C63-B2F0-4784-8B67-5E12C8701A31}\\"; string clsValue = "{E7EA138F-69F8-11D7-A6EA-00065B844310}";//【搜狗五笔输入法】的CLSID值 string swpValue = "{E7EA1390-69F8-11D7-A6EA-00065B844311}";//【搜狗五笔输入法】的 Profile 值 string defAssPath = "SOFTWARE\\Microsoft\\CTF\\Assemblies\\0x00000804\\{34745C63-B2F0-4784-8B67-5E12C8701A31}"; int layNum = 134481924; //获得所有输入法的 CLSID值、Profile值、KeyboardLayout值,及完整路径,并将其存储到相应数组中 for (int f = 0; f < arrNames.Length; f++) { fmainPaths[f] = mainPath + arrNames[f];//完整路径值获取、储存 RegistryKey ckey = Key.OpenSubKey(fmainPaths[f], true); clsids[f] = ckey.GetValue("CLSID").ToString();// CLSID 值获取、储存 profiles[f] = ckey.GetValue("Profile").ToString();// Profile 值获取、储存 keyBoards[f] = int.Parse(ckey.GetValue("KeyboardLayout").ToString());// KeyboardLayout 值获取、储存 ckey.Close(); } int pID = 0;//【搜狗五笔输入法】索引变量 //依据【搜狗五笔输入法】的 Profile 值进行判断,得到【搜狗五笔输入法】在系统输入法菜单中的索引值 for (int p = 0; p < profiles.Length; p++) { if (profiles[p] == swpValue) { pID = p; Console.WriteLine(pID);//输入出搜狗五笔输入法,在任务栏中的位置 break; } } if (pID != 0)//【搜狗五笔输入法】在系统输入法菜单中,不为默认输入法时执行 { RegistryKey defKey = Key.CreateSubKey(fmainPaths[0], RegistryKeyPermissionCheck.ReadWriteSubTree);//默认值操作 RegistryKey defAssKey = Key.CreateSubKey(defAssPath, RegistryKeyPermissionCheck.ReadWriteSubTree); //defKey.SetValue("CLSID", clsids[pID]); //defKey.SetValue("Profile", profiles[pID]); defKey.SetValue("CLSID", clsValue);//将【搜狗五笔输入法】CLSID 值,写入到默认输入法栏 defKey.SetValue("Profile", swpValue);//将【搜狗五笔输入法】Profile 值,写入到默认输入法栏 defKey.SetValue("KeyboardLayout", keyBoards[pID], RegistryValueKind.DWord);//将【搜狗五笔输入法】KeyboardLayout 值,写入到默认输入法栏 defAssKey.SetValue("Default", clsValue); defAssKey.SetValue("Profile", swpValue); defAssKey.SetValue("KeyboardLayout", layNum, RegistryValueKind.DWord); defAssKey.Close(); defKey.Close(); RegistryKey renKey = Key.CreateSubKey(fmainPaths[pID], RegistryKeyPermissionCheck.ReadWriteSubTree);//更新值 //将原输入法的CLSID、Profile、KeyboardLayout 值,更新到原【搜狗五笔输入法】在系统输入法菜单中,相应的位置。 renKey.SetValue("KeyboardLayout", keyBoards[0], RegistryValueKind.DWord); renKey.SetValue("CLSID", clsids[0]); renKey.SetValue("Profile", profiles[0]); renKey.Close(); Key.Close(); Console.WriteLine("运行到这里了!+1"); //以下程序仅供思路参考!不建议使用! /* #region 切换搜狗五笔输入法 // 获取搜狗输入法的键盘布局ID string sogouKLID = "134481924"; // 搜狗输入法的键盘布局ID // 获取当前前台窗口句柄 IntPtr foregroundWindow = GetForegroundWindow(); // 获取前台窗口所属进程ID GetWindowThreadProcessId(foregroundWindow, out uint processId); // 获取当前线程ID uint currentThreadId = GetCurrentThreadId(); // 获取当前线程的键盘布局 IntPtr currentLayout = GetKeyboardLayout(currentThreadId); Console.WriteLine(currentLayout.ToString()); // 如果当前键盘布局不是搜狗输入法,则切换到搜狗输入法 if (currentLayout.ToString() != sogouKLID) { // 加载搜狗输入法的键盘布局 IntPtr sogouLayout = LoadKeyboardLayout(sogouKLID, KLF_ACTIVATE); // 发送切换输入法的消息 PostMessage(foregroundWindow, WM_INPUTLANGCHANGEREQUEST, IntPtr.Zero, sogouLayout); } #endregion */ } if (pID == 0)//【搜狗五笔输入法】在系统输入法菜单中,为默认输入法时不执行 { Console.WriteLine("运行到这里了!"); Key.Close(); } #endregion } private void richTextBox1_Enter(object sender, EventArgs e) { //以下的代码有些鸡肋,目前还没有想到解决办法,先暂时保留! /* InputLanguage currentInputLanguage = InputLanguage.CurrentInputLanguage; Console.WriteLine(currentInputLanguage.LayoutName); if (currentInputLanguage.LayoutName != "Chinese")//通过输入法的名字进行判断,不可取!替代方案为GUID(暂时思绪) { //IntPtr targetHwnd= GetForegroundWindow(); // GetConsoleWindow()函数获取控制台窗口句柄 IntPtr targetHwnd = FindWindow(null, "Form1"); if (targetHwnd != IntPtr.Zero) { SendKeys.SendWait("%+Shift"); Thread.Sleep(200); // 等待操作系统处理消息 SendKeys.SendWait("%+Shift"); Console.WriteLine("当前输入模式为中文"); } }*/ } } }

以上的代码,在windows10、11,均可以将搜狗五笔输入法,设置成为默认输入法。

接下来的代码,是调用API,切换到默认输入法:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApp7 { public partial class Form2 : Form { public Form2() { InitializeComponent(); } // 导入user32.dll库文件 [DllImport("user32.dll")] public static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetForegroundWindow(); const int WM_INPUTLANGCHANGEREQUEST = 0x50; const int INPUTLANGCHANGE_FORWARD = 1; private void Form2_Load(object sender, EventArgs e) { IntPtr activeWindowHandle = GetForegroundWindow(); if (activeWindowHandle != IntPtr.Zero) { // 发送消息通知系统要求更改输入语言 SendMessage(activeWindowHandle, WM_INPUTLANGCHANGEREQUEST, new IntPtr(INPUTLANGCHANGE_FORWARD), IntPtr.Zero); Console.WriteLine("已成功将当前输入法切换至默认输入法"); } else { Console.WriteLine("无法确定当前活动窗口的句柄"); } } } }

第二篇代码,来自于百度AI,CSDN-AI,A小快,三个AI整理而来,可以作为单独的代码使用,不用与第一篇代码融合。

三、BUG整理:

1.第一篇代码,与第二篇代码,虽然可以融合在一起。但始终有两个BUG去不掉。

这个输入状态,是我想要的,可实际上却是下面的状态:

程序打开时,出现这个状态,我就要切换一下,有点不合初衷。

2.第二BUG,便是英文状态,即下图:

四、总结:     可以看出来,我的思路,虽然有一定的可行性,但其中还有几个关键点,需要突破。虽然这样的代码发出来,多少有些不负责。但考虑到,我的错误之处,也是有一定的参考价值,还是将其发出来,给你的成功路上,添上一块垫脚石。      目前,我使用的方法,是第二篇代码,虽然也有些问题,但还是勉强能用。      后续的思路,仍在完善之中!


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有