简体   繁体   English

无法获得当前的键盘布局

[英]can't get current keyboard layout

I have tried GetKeyboardLayoutName() and GetKeyboardLayout() for getting the current keyboard layout, but they both give me the default layout and changing the layout doesn't affect the output! 我已经尝试了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 ;
            }
        }
    }
}

It always gives me "00000409" when the default layout is set to English, while I expect it to be "00000429" when I change the layout to Farsi. 当默认布局设置为英语时,它总是给我“00000409”,而当我将布局更改为波斯语时,我希望它为“00000429”。

My first question here, I used to find all my answers by just searching. 我在这里的第一个问题,我过去通过搜索找到了我的所有答案。 But right now I'm driving crazy after hours of searching around and getting nothing... 但是现在我经过几个小时的搜索并且什么也没得到......

one thing that you need to notice is that ::GetKeyboardLayout (..) gets the lang for the passed thread identifer as a param. 你需要注意的一件事是:: GetKeyboardLayout(..)获取传递的线程标识符的lang作为参数。

each input thread can have different input locale lang. 每个输入线程可以具有不同的输入语言环境。 for instance if you put lets IE in the foreground and press Alt+Shift the lang changes to UK. 例如,如果你将让IE放在前台并按Alt + Shift,则lang会更改为UK。 ( you can see it in the taskbar ) (你可以在任务栏中看到它)

now if you will Alt+Tab to another window ( which will be in foregorund ) you will see that lang dont have to stay UK. 现在,如果你将Alt + Tab改为另一个窗口(将在foregorund中),你会发现lang不必留在英国。

so what you need to check is what is the thread id you are passing. 所以你需要检查的是你传递的线程ID是什么。

look at this code it will get you the lang for the current active window: 看看这段代码,它将为您提供当前活动窗口的lang:

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

to use GUITHREADINFO you need to define WINVER 0x500. 要使用GUITHREADINFO,您需要定义WINVER 0x500。 put this in the stdafx.h before all the include. 在所有包含之前将它放在stdafx.h中。

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

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

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). 如果你编写一个命令行程序, 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM