2017-02-05 71 views
2

我的键盘有2种我一直在切换的键盘语言,希腊语和英语。我如何获得当前的键盘语言? Ar有任何有用的库,可以为我做的伎俩? 我正在使用python 3.5.2,Windows 10如何在python中检测当前键盘语言

+0

它系统信息Windows/Linux/Mac。它可以用于你使用的系统。 – furas

+0

@furas windows! –

+0

也许[回答](http://stackoverflow.com/a/3425316/5209610)到另一个SO问题将有所帮助(请参阅这篇文章的两个答案)。在Unix SE站点上有另一个很好的[答](http://unix.stackexchange.com/a/295271)。 –

回答

5

下面的方法,利用​​库,适用于我。

# My keyboard is set to the English - United States keyboard 
>>> import ctypes 
# For debugging Windows error codes in the current thread 
>>> user32 = ctypes.WinDLL('user32', use_last_error=True) 
>>> curr_window = user32.GetForegroundWindow() 
>>> thread_id = user32.GetWindowThreadProcessId(curr_window, 0) 
# Made up of 0xAAABBBB, AAA = HKL (handle object) & BBBB = language ID 
>>> klid = user32.GetKeyboardLayout(thread_id) 
67699721 
# Language ID -> low 10 bits, Sub-language ID -> high 6 bits 
# Extract language ID from KLID 
>>> lid = klid & (2**16 - 1) 
# Convert language ID from decimal to hexadecimal 
>>> lid_hex = hex(lid) 
'0x409' 

# I switched my keyboard to the Russian keyboard 
>>> curr_window = user32.GetForegroundWindow() 
>>> thread_id = user32.GetWindowThreadProcessId(curr_window, 0) 
>>> klid = user32.GetKeyboardLayout(thread_id) 
68748313 
# Extract language ID from KLID 
>>> lid = klid & (2**16 - 1) 
# Convert language ID from decimal to hexadecimal 
>>> lid_hex = hex(lid) 
'0x419' 

您可以按照希腊相同的步骤(0x408),或任何其他语言,你想检测。如果您有兴趣,here is a plain-text listhere is Microsoft's list的所有十六进制值lid_hex可能承担,给定一个输入语言。

LCID存储在this format中(正如我在我的代码的评论中所述),以供参考。

只要确保在每次切换键盘上的语言时调用GetKeyboardLayout(thread_id)

编辑:

正如在评论中提到@furas,这是系统相关的。如果您要将代码移植到除Windows 10之外的其他操作系统(可能甚至是Windows的早期版本,如果LCID自那时起已更改),则此方法将无法按预期工作。

编辑2:

我的klid第一种解释是不正确的,但由于@ eryksun的意见,我已经纠正了这一点。

+0

切换到使用'user32 = ctypes.WinDLL('user32',use_last_error = True)'。此外,['GetKeyboardLayout'](https://msdn.microsoft.com/en-us/library/ms646296)的'HKL'结果在低位字(16位)中具有语言标识符,例如, 'klid = hkl&(2 ** 16 - 1)'。语言标识符由低10位中的主语言ID和高6位中的子语言ID组成,例如0x409的语言ID为9('LANG_ENGLISH'),子语言ID为1('SUBLANG_ENGLISH_US')。 – eryksun

+0

'use_last_error'在这里添加了一般性。它保护线程的最后一个错误值,以防在调用函数和获取错误(如果失败)之间进行修改。错误值可以用'ctypes.get_last_error()',这比直接调用'GetLastError'更可靠。切换到“WinDLL”的主要目的是将您的模块与其他模块隔离。 'windll'缓存库,缓存函数指针,当至少有一个模块定义的函数原型与另一个模块所期望的不同时,这会导致冲突,即'windll'是一个糟糕的设计。 – eryksun

+0

你对'klid'的解释是错误的。 0x4090409不是0xAAABBBB,其中语言ID是0xBBBB,子语言ID是0xAAA。语言ID是低位字(16位或4位十六进制数字),即0xBBBB,语言ID是该字的低10位,子语言ID是该字的高6位。 – eryksun