无法获得当前的键盘布局

EmJ*_*ash 6 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 ;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当默认布局设置为英语时,它总是给我"00000409",而当我将布局更改为Farsi时,我希望它为"00000429".

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

Moh*_*ghi 8

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

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

现在,如果你将Alt + Tab改为另一个窗口(将在foregorund中),你会看到lang不必留在英国.

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

看看这段代码,它将为您提供当前活动窗口的lang:

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

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

#ifdef WINVER
#undef WINVER
#endif 
#define WINVER 0x500
Run Code Online (Sandbox Code Playgroud)

source:GetKeyboardLayout没有返回正确的语言ID(WINXP)