无法获得当前的键盘布局

时间:2012-09-12 00:25:15

标签: c++ winapi keyboard-layout

我已尝试 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”。

我的第一个问题是,我过去只是通过搜索来找到我的所有答案。但是现在我经过几个小时的搜索并且什么也没得到,我开车疯了......

2 个答案:

答案 0 :(得分:8)

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

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

现在,如果您将Alt + Tab添加到另一个窗口(将在foregorund中),您将看到lang不必留在英国。

所以你需要检查的是你传递的线程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)

答案 1 :(得分:1)

以下代码很简单,工作正常。如果您编写命令行程序,GetKeyboardLayout API在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;
}
相关问题