【问题标题】:Change input method on windows using c++ and windows API使用 c++ 和 windows API 在 windows 上更改输入法
【发布时间】:2021-01-09 00:03:51
【问题描述】:

我想在 C++ 中结合 windows API 编写一些代码,以更改 windows 上的输入法(键盘输入语言)。

这是我的第一次尝试:

#include <iostream>
#include <windows.h>

int main() {
    int arr_size = GetKeyboardLayoutList(0, NULL);

    HKL hkl_array[arr_size];  // The array to hold input locale identifies found in the system(HKL)

    // Initialize the array to all zeros
    for (int i = 0; i <= arr_size - 1; i++) {
        hkl_array[i] = nullptr;
    }

    int lang_found = GetKeyboardLayoutList(arr_size, hkl_array);  // Get all the HKLs in the array

    for (int i = 0; i <= lang_found - 1; ++i) {
        // Print all the HKLs found
        std::cout << i + 1 << ". " << hkl_array[i] << std::endl;
    }

    std::cout << "Function return: " << ActivateKeyboardLayout(hkl_array[0], KLF_SETFORPROCESS);

    return 0;
}

当我以英语作为当前语言运行上述代码时:

1. 0x4080408
2. 0x4090409

Function return: 0x4090409

(0x4080408 is Greek and 0x4090409 is English)

根据ActivateKeyboardLayoutdocumentation,返回值是HKL类型,如果函数成功,返回值是之前输入的语言环境标识符。否则,它为零。在我的例子中,该函数显然没有错误地运行,因为它返回的输入语言环境标识符是英语女巫是假设更改之前的语言。语言虽然没有变化。如果我从希腊语开始并尝试更改为英语,我会得到类似的结果。

我在 flag 参数中尝试了不同的值,但没有成功。它总是一样的。我也试过使用 LoadKeyboardLayoutA 如下:

#include <iostream>
#include <windows.h>

int main(){
    LPCSTR language_select = "00000408";  // Code for greek
    std::cout << LoadKeyboardLayoutA(language_select, KLF_ACTIVATE);

    return 0;
}

当我以英语作为当前语言运行上述代码时:

0x4080408

根据LoadKeyboardLayoutAdocumentation,如果函数成功,则返回类型为HKL,返回值为函数参数中指定的名称对应的输入语言环境标识符(language_select) .所以这似乎也运行良好,但语言改变没有运气。我还尝试了 language_select = "00000809"(英国英语),结果是英国英语刚刚添加到语言列表中,因为我没有安装它。

最后,我尝试使用 LoadKeyboardLayoutA 和 HKL 参数调用 ActivateKeyboardLayout,如下所示

#include <iostream>
#include <windows.h>

int main() {
    LPCSTR language_select = "00000408";  // Code for greek
    std::cout << ActivateKeyboardLayout(LoadKeyboardLayoutA(language_select, KLF_ACTIVATE), KLF_SETFORPROCESS);

    return 0;
}

当我以英语作为当前语言运行上述代码时:

0x4080408

这再次看起来很正常,但语言中没有机会。我在 Windows 10 20H2 OS Build 19042.685 上运行它,并且我使用 CLion 作为 IDE(我认为这并不重要,但以防万一有人需要信息)。我做错了什么?

【问题讨论】:

  • 您是要更改当前进程或系统的键盘布局吗?
  • @namesis 我希望它具有与按 Windows 键 + 空格或 Shift + Alt 时相同的行为。为了清楚起见,更改键盘布局只会更改键盘类型正确的语言?

标签: c++ winapi


【解决方案1】:

ActivateKeyboardLayout 函数文档的第一句话指出:“为调用线程或当前进程设置输入区域设置标识符(以前称为键盘布局句柄)。”。由于您从未在程序中读取输入,因此您不会观察到它的效果。它不会改变系统的键盘布局。

在 Windows 上,每个线程都有自己的键盘布局。要更改特定窗口的键盘布局,您需要向其发送WM_INPUTLANGCHANGEREQUEST 消息:

SendMessageW(<windowHandle>, WM_INPUTLANGCHANGEREQUEST, 0, LoadKeyboardLayoutW(language_select, KLF_ACTIVATE));

【讨论】:

  • 我通过这样做SendMessageW(HWND_BROADCAST, WM_INPUTLANGCHANGEREQUEST, 0, reinterpret_cast&lt;LPARAM&gt;(LoadKeyboardLayoutA(language, KLF_ACTIVATE))); 设法让它为系统工作,而不是通过HWND_BROADCAST 传递特定的窗口句柄,因此系统的输入法发生了变化。此外,我的编译器需要转换为 LPARAM 才能运行。
  • 如果您从 SendMessageW 更改为 SendMessageA,您可能会在没有演员的情况下逃脱。 WinAPI 分为以 A 结尾并接受普通字符串(由 1 字节字符组成)或 W 并接受宽字符串(由 2 字节字符组成)的函数。
  • @namesis 我实际上尝试过,但我得到了同样的错误。 Clion 的 IntelliSense 实际上建议了演员阵容,所以我同意了。我认为这不是问题,因为它可以正常工作。
猜你喜欢
  • 2012-04-01
  • 2019-02-15
  • 2023-03-16
  • 2011-03-20
  • 2018-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多