6

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

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

4

2 回答 2

9

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

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

现在,如果您将 Alt+Tab 转到另一个窗口(将在前面),您将看到 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 未返回正确的语言 ID (WINXP)

于 2012-09-12T07:41:10.457 回答
2

The following code is simple and works fine. If you write a command line program, the GetKeyboardLayout API does't work in windows cmd or powershell, you can test it in babun(an open source 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;
}
于 2018-05-29T02:41:42.320 回答