尝试使用SystemParametersInfo时,我已经卡住了。 我使用德沃夏克键盘,所以我想做一个exe,我可以双击每当我想改变键盘布局。 我用C#使用SystemParametersInfo。 我可以检索当前的input语言就好了。 但是,当我尝试设置input语言时,我得到一个返回值为false,并且input语言不会更改。
预先感谢您的任何帮助。
这是我正在使用的代码:
class KeyboardSwitcher { [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref uint pvParam, uint fWinIni); private const uint SPI_GETDEFAULTINPUTLANG = 0x0059; private const uint SPI_SETDEFAULTINPUTLANG = 0x005A; private const uint SPIF_UPDATEINIFILE = 0x01; private const uint SPIF_SENDWININICHANGE = 0x02; private const uint DVORAK = 0xF0020409; private const uint QWERTY = 0x04090409; static void Main(string[] args) { uint currentLayout = 0; uint newLayout = 0; bool result = false; int error = 0; SystemParametersInfo(SPI_GETDEFAULTINPUTLANG, 0, ref currentLayout, 0); if(currentLayout != DVORAK) { newLayout = DVORAK; /*result = SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, 0, ref newLayout, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);*/ result = SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, 0, ref newLayout, SPIF_SENDWININICHANGE); error = Marshal.GetLastWin32Error(); } else { newLayout = QWERTY; /*result = SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, 0, ref newLayout, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);*/ result = SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, 0, ref newLayout, SPIF_SENDWININICHANGE); error = Marshal.GetLastWin32Error(); } Console.WriteLine(">>> Current Layout <<<"); Console.WriteLine("0x" +currentLayout.ToString("X")); Console.WriteLine(">>> New Layout <<<"); Console.WriteLine("0x" +newLayout.ToString("X")); Console.WriteLine("Change Successful >>> " +result); Console.WriteLine(error); Console.WriteLine(">>> Final Layout <<<"); uint finalLayout = 0; SystemParametersInfo(SPI_GETDEFAULTINPUTLANG, 0, ref finalLayout, 0); Console.WriteLine("0x" +finalLayout.ToString("X")); Console.WriteLine("Press any key to continue..."); Console.ReadKey(true); } }
更新:
我扔在Console.WriteLine(Marshal.GetLastWin32Error()); 与其余的打印语句,它返回0.在阅读注释之前,我也试图通过导入Kernel32.dll GetLastError(),它也返回0.谢谢你的回应。
更新2:我已经改变了我的代码来显示我的GetLastWin32Error()的用法。
这里是我将Dvorak设置为默认input语言的输出。
>>> Current Layout <<< 0xF0020409 >>> New Layout <<< 0x4090409 Change Successful >>> True Error Code >>> 0 >>> Final Layout <<< 0x4090409 Press any key to continue...
这是Qwerty设置为默认input语言时的输出。
>>> Current Layout <<< 0x4090409 >>> New Layout <<< 0xF0020409 Change Successful >>> True Error Code >>> 0 >>> Final Layout <<< 0xF0020409 Press any key to continue...
当我将每个布局设置为默认值时,我得到了布局的hex值使用SPI_GETDEFAULTINPUTLANG。 你认为它返回的价值可能不同于我需要发送的价值吗?
我已经对InputLanguage类进行了一些研究,我不相信它适合这种情况,因为DefaultInputLanguage属性没有setter,也没有其他方法来设置默认input语言。
更新3:当我将SystemParametersInfo的第四个参数更改为SPIF_SENDWININICHANGE时,它变得更接近工作。 SET的结果是True,并且当我背靠背运行程序时,它会来回切换语言。 所以这意味着Windows中的东西确实在改变。 但是,更改是新的反映在控制面板中,键盘实际上并没有改变。 我觉得我需要SPIF_UPDATEINIFILE来推动更改。 我使用的价值是正确的,不是吗? 我还更新了代码和输出,以便输出更加冗长。
要通知应用程序语言已更改,而不重新启动它,您需要发送应用程序窗口WM_INPUTLANGCHANGEREQUEST后跟WM_INPUTLANGCHANGE消息,其中lParam是语言环境标识符。