【问题标题】:can't get current keyboard layout无法获取当前的键盘布局
【发布时间】:2012-09-04 23:22:24
【问题描述】:

我已尝试使用 GetKeyboardLayoutName()GetKeyboardLayout() 来获取当前的键盘布局,但它们都为我提供了默认布局并且更改布局不会影响输出!

while(1)
{
    Sleep(5);
    for(int i = 8; i < 191; i++)
    {
        if(GetAsyncKeyState(i)&1 ==1)
        {
            TCHAR szKeyboard[KL_NAMELENGTH];
            GetKeyboardLayoutName(szKeyboard);

            if(GetAsyncKeyState(i)&1 ==1)
            {
                TCHAR szKeyboard[KL_NAMELENGTH];
                GetKeyboardLayoutName(szKeyboard);
                cout << szKeyboard << endl ;
            }
        }
    }
}

当默认布局设置为英语时,它总是给我“00000409”,而当我将布局更改为波斯语时,我希望它是“00000429”。

我在这里的第一个问题,我曾经通过搜索找到所有答案。但是现在,经过数小时的搜索却一无所获,我正在发疯……

【问题讨论】:

  • 不确定这会有所帮助.. 尝试 GetKeyboardLayoutList 以查看您想要的布局是否至少已加载.. msdn.microsoft.com/en-us/library/windows/desktop/…
  • @MohamedNuur:已经试过了,它已经加载了。
  • 我没有看到更改键盘布局的代码。我只能猜测它更改失败并且您没有检查它的错误代码。
  • 请注意,Windows 中的键盘布局是按进程设置的,因此请确保在运行检查之前更改正确进程的布局。
  • 实际上我想知道用户是否手动更改布局,尽管它没有以编程方式更改。为了获取当前进程的布局,我尝试了 GetKeyboardLayout(GetCurrentThreadId()) 并且我虽然它会工作。我仍然不知道这有什么问题。

标签: c++ winapi keyboard-layout


【解决方案1】:

您需要注意的一件事是 ::GetKeyboardLayout (..) 获取传递的线程标识符的 lang 作为参数。

每个输入线程可以有不同的输入语言环境。 例如,如果您将让 IE 放在前台并按 Alt+Shift,则 lang 会更改为 UK。 (可以在任务栏中看到)

现在,如果您将 Alt+Tab 切换到另一个窗口(将在前台),您将看到 lang 不必留在 UK。

所以你需要检查的是你传递的线程ID是什么。

看看这段代码,它会得到当前活动窗口的语言:

GUITHREADINFO Gti;
::ZeroMemory ( &Gti,sizeof(GUITHREADINFO));
Gti.cbSize = sizeof( GUITHREADINFO );
::GetGUIThreadInfo(0,&Gti);
DWORD dwThread = ::GetWindowThreadProcessId(Gti.hwndActive,0);
HKL lang = ::GetKeyboardLayout(dwThread);

要使用 GUITHREADINFO,您需要定义 WINVER 0x500。 把它放在所有包含之前的 stdafx.h 中。

#ifdef WINVER
#undef WINVER
#endif 
#define WINVER 0x500

来源:GetKeyboardLayout not returning correct language ID (WINXP)

【讨论】:

  • 谢谢兄弟,它就像 cahrm 一样工作 ;) 我曾经使用过 GetKeyboardLayout(GetCurrentThreadId()),我认为它会这样做......
【解决方案2】:

下面的代码很简单,运行良好。如果你写一个命令行程序,GetKeyboardLayoutAPI在windows cmd或者powershell下是不行的,你可以在babun(一个开源的windows shell)中测试一下。

#include <Windows.h>
int getInputMethod() {
  HWND hwnd = GetForegroundWindow();
  if (hwnd) {
    DWORD threadID = GetWindowThreadProcessId(hwnd, NULL);
    HKL currentLayout = GetKeyboardLayout(threadID);
    unsigned int x = (unsigned int)currentLayout & 0x0000FFFF;
    return ((int)x);
  }
  return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-24
    • 2013-07-19
    • 1970-01-01
    • 2021-10-21
    • 2019-12-09
    相关资源
    最近更新 更多