2017-02-05 111 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