gpt4 book ai didi

c# - 帮助使用 SystemParametersInfo

转载 作者:可可西里 更新时间:2023-11-01 09:35:16 27 4
gpt4 key购买 nike

我在尝试使用 SystemParametersInfo 时卡住了。我使用 Dvorak 键盘,所以我试图制作一个 exe,只要我想更改键盘布局,就可以双击它。我在 C# 中使用 SystemParametersInfo。我可以很好地检索当前的输入语言。但是,当我尝试设置输入语言时,返回值为 false,并且输入语言没有改变。

提前感谢您的帮助。

这是我使用的代码:

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 设置为默认输入语言时的输出。

>>> Current Layout <<<
0xF0020409
>>> New Layout <<<
0x4090409
Change Successful >>> True
Error Code >>> 0
>>> Final Layout <<<
0x4090409
Press any key to continue...

这是我将 Qwerty 设置为默认输入语言时的输出。

>>> Current Layout <<<
0x4090409
>>> New Layout <<<
0xF0020409
Change Successful >>> True
Error Code >>> 0
>>> Final Layout <<<
0xF0020409
Press any key to continue...

当我将每个布局设置为默认值时,我使用 SPI_GETDEFAULTINPUTLANG 得到了布局的十六进制值。您认为它返回的值可能与我需要发送的值不同吗?

我对 InputLanguage 类做了一些研究,我认为它不适合这种情况,因为 DefaultInputLanguage 属性没有 setter ,也没有其他方法来设置默认输入语言。

更新 3:当我将 SystemParametersInfo 的第四个参数更改为 SPIF_SENDWININICHANGE 时,它变得更接近工作。 SET 的结果是 True,当我来回运行程序时,它会来回切换语言。所以这意味着 Windows 中的一些东西确实正在被改变。但是,更改是新的反射(reflect)在控制面板中,键盘实际上并没有改变。我觉得我确实需要 SPIF_UPDATEINIFILE 来插入更改。我使用的值是正确的,不是吗?我还更新了代码和输出,使输出更加冗长。

最佳答案

要在不重新启动的情况下通知应用程序语言已更改,您需要向应用程序窗口发送一个 WM_INPUTLANGCHANGEREQUEST,然后是一个 WM_INPUTLANGCHANGE 消息,其中 lParam 是区域设置标识符。

关于c# - 帮助使用 SystemParametersInfo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9669352/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com